phy_procedures_lte_ue.c 197 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * 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
 */
21 22 23

/*! \file phy_procedures_lte_ue.c
 * \brief Implementation of UE procedures from 36.213 LTE specifications
24
 * \author R. Knopp, F. Kaltenberger, N. Nikaein
25 26 27
 * \date 2011
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
29 30 31 32
 * \note
 * \warning
 */

33 34
#define _GNU_SOURCE

35
#include "assertions.h"
36 37
#include "PHY/defs_UE.h"
#include "PHY/phy_extern_ue.h"
38 39
#include <sched.h>
#include "targets/RT/USER/lte-softmodem.h"
40

41 42
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#include "SCHED_UE/sched_UE.h"
43 44 45
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"

46 47 48 49 50

#ifndef PUCCH
#define PUCCH
#endif

51
#include "LAYER2/MAC/mac.h"
52
#include "common/utils/LOG/log.h"
53

54
#include "common/utils/LOG/vcd_signal_dumper.h"
55
#include "UTIL/OPT/opt.h"
56

57 58 59 60
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

61
#include "PHY/defs_UE.h"
62

63
#include "PHY/CODING/coding_extern.h"
64

65 66
#include "T.h"

67
#include "PHY/TOOLS/tools_defs.h"
68

69 70 71 72 73
#define DLSCH_RB_ALLOC 0x1fbf  // skip DC RB (total 23/25 RBs)
#define DLSCH_RB_ALLOC_12 0x0aaa  // skip DC RB (total 23/25 RBs)

#define NS_PER_SLOT 500000

hbilel's avatar
hbilel committed
74
extern double cpuf;
75

76 77
void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
78

kaltenbe's avatar
kaltenbe committed
79
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
80
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
81 82
#endif

83 84 85
void get_dumpparam(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t nb_rb,
                   uint32_t *alloc_even, uint8_t subframe,uint32_t Qm, uint32_t Nl, uint32_t tm,
                   uint8_t *nsymb, uint32_t *coded_bits_per_codeword) {
86

87 88 89 90 91 92 93 94 95 96 97 98
  *nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;

  *coded_bits_per_codeword = get_G(&ue->frame_parms,
                                  nb_rb,
                                  alloc_even,
                                  Qm,
                                  Nl,
                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                  proc->frame_rx,
                                  subframe,
                                  tm);
}
99

100
void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid)
101
{
102
LOG_M_BEGIN(DEBUG_UE_PHYPROC)
103
  unsigned int coded_bits_per_codeword;
104
  uint8_t nsymb ;
105

106 107 108 109 110 111 112 113
  get_dumpparam(ue, proc, eNB_id, 
                ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb ,
                ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
                subframe,
                ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm,
                ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,                
                ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                &nsymb, &coded_bits_per_codeword);
114

bruno mongazon's avatar
bruno mongazon committed
115 116 117
  LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
  LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
118
  /*
bruno mongazon's avatar
bruno mongazon committed
119 120 121 122
    LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
123
  */
bruno mongazon's avatar
bruno mongazon committed
124 125
  LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1);
  LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0);
126

bruno mongazon's avatar
bruno mongazon committed
127 128
  LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1);
  LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1);
129
LOG_M_END
130 131
}

132
void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
133
{
134
LOG_M_BEGIN(DEBUG_UE_PHYPROC)
135
  unsigned int coded_bits_per_codeword;
136 137 138 139 140 141 142
  uint8_t nsymb;

  get_dumpparam(ue, proc, eNB_id,
                ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
                ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
                subframe,2,1,0,
                &nsymb, &coded_bits_per_codeword);
143

144
  LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
145
        ue->Mod_id,
146 147
        ue->frame_parms.ofdm_symbol_size,
        nsymb,
148 149 150
        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,
151
        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
152
        coded_bits_per_codeword);
153

bruno mongazon's avatar
bruno mongazon committed
154
  LOG_M("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
155

bruno mongazon's avatar
bruno mongazon committed
156 157 158
  LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
159
  /*
bruno mongazon's avatar
bruno mongazon committed
160 161 162 163
    LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
164
  */
bruno mongazon's avatar
bruno mongazon committed
165 166
  LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_SI[0]->rxdataF_comp0[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
  LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0);
167

bruno mongazon's avatar
bruno mongazon committed
168 169
  LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1);
  LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1);
170
  sleep(1);
171
  exit(-1);
172
LOG_M_END
173 174
}

kaltenbe's avatar
kaltenbe committed
175
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
Raymond Knopp's avatar
 
Raymond Knopp committed
176 177
//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
/*
178 179
  unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
  {
180

181
  int gain_dB = power_dBm - power_max_dBm;
Raymond Knopp's avatar
 
Raymond Knopp committed
182 183 184 185
  int amp_x_100;

  switch (N_RB_UL) {
  case 6:
186 187
  amp_x_100 = AMP;      // PRACH is 6 PRBS so no scale
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
188
  case 15:
189 190
  amp_x_100 = 158*AMP;  // 158 = 100*sqrt(15/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
191
  case 25:
192 193
  amp_x_100 = 204*AMP;  // 204 = 100*sqrt(25/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
194
  case 50:
195 196
  amp_x_100 = 286*AMP;  // 286 = 100*sqrt(50/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
197
  case 75:
198 199
  amp_x_100 = 354*AMP;  // 354 = 100*sqrt(75/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
200
  case 100:
201 202
  amp_x_100 = 408*AMP;  // 408 = 100*sqrt(100/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
203
  default:
204 205 206
  LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
  mac_xface->macphy_exit("");
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
207
  }
208
  if (gain_dB < -30) {
209
  return(amp_x_100/3162);
210
  } else if (gain_dB>0)
211
  return(amp_x_100);
212
  else
213 214
  return(amp_x_100/gain_table[-gain_dB]);  // 245 corresponds to the factor sqrt(25/6)
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
215 216 217 218 219
*/

unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
{

220
  int gain_dB;
Raymond Knopp's avatar
 
Raymond Knopp committed
221 222
  double gain_lin;

223 224 225 226 227
  if (power_dBm<=power_max_dBm)
    gain_dB = power_dBm - power_max_dBm;
  else
    gain_dB = 0;

Raymond Knopp's avatar
 
Raymond Knopp committed
228
  gain_lin = pow(10,.1*gain_dB);
229 230
  AssertFatal((nb_rb >0) && (nb_rb <= N_RB_UL),"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
  return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
Raymond Knopp's avatar
 
Raymond Knopp committed
231 232
}

233 234
#endif

235
void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
236
{
237
LOG_M_BEGIN(DEBUG_UE_PHYPROC)
238
  unsigned int coded_bits_per_codeword;
239 240 241 242 243 244 245 246
  uint8_t nsymb ;


  get_dumpparam(ue, proc, eNB_id,
                ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
                ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, 
                subframe,2,1,0,
                &nsymb, &coded_bits_per_codeword);
247 248

  LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
249 250 251 252
        ue->Mod_id,
        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,
253
        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
254
        coded_bits_per_codeword);
255

bruno mongazon's avatar
bruno mongazon committed
256 257 258
  LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
  LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1);
  LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
259
  /*
bruno mongazon's avatar
bruno mongazon committed
260 261 262 263
    LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
264
  */
bruno mongazon's avatar
bruno mongazon committed
265 266
  LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1);
  LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0);
267

bruno mongazon's avatar
bruno mongazon committed
268 269
  LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1);
  LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
270
LOG_M_END
271
}
272

273
void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
274
{
275 276 277

  // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
  // for more flexibility
278

279
  uint8_t i,j,k,s;
280
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
281

hbilel's avatar
hbilel committed
282
  //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
283
  for(int l=0; l<RX_NB_TH; l++) {
hbilel's avatar
hbilel committed
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
      for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
          for(j=0; j<2; j++) {
              //DL HARQ
              if(ue->dlsch[l][i][j]) {
                  for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->dlsch[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;
                      }
                  }
              }
299
          }
300

hbilel's avatar
hbilel committed
301 302 303 304 305 306
          //UL HARQ
          if(ue->ulsch[i]) {
              for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->ulsch[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;
307

hbilel's avatar
hbilel committed
308 309
              }
          }
310

hbilel's avatar
hbilel committed
311 312
          // flush Msg3 buffer
          ue->ulsch_Msg3_active[i] = 0;
313

hbilel's avatar
hbilel committed
314
      }
315 316 317
  }
}

318 319
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
320 321

  // if contention resolution fails, go back to PRACH
Raymond Knopp's avatar
 
Raymond Knopp committed
322
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
hbilel's avatar
hbilel committed
323 324 325 326
  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;
327
  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);
328 329
}

330 331
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
332 333 334

  int i;

335
  LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id);
336

hbilel's avatar
hbilel committed
337 338
  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;
339
  PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
340
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
341

342
  for (i=0; i<8; i++) {
343
    if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
344
      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=SCH_IDLE;
hbilel's avatar
hbilel committed
345 346
      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;
347
      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
348
    }
349 350 351 352 353
  }


}

354 355
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
356

Raymond Knopp's avatar
 
Raymond Knopp committed
357
  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
358 359

}
360
void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) {
361

362
  ue->timing_advance = timing_advance*4;
363 364


365
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
Cedric Roux's avatar
Cedric Roux committed
366 367 368
  /* TODO: fix this log, what is 'HW timing advance'? */
  /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);*/
  LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);
369
LOG_DEBUG_END
370 371 372

}

373
void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance)
374
{
375

376
  //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
377

378
  // timing advance has Q1.5 format
379
  timing_advance = timing_advance - 31;
380

381 382
  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!!!

383

384
  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);
385

386 387 388

}

389
uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
390 391
{

392 393
  int subframe=proc->subframe_tx;

394
  LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
395
        ue->Mod_id,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,proc->frame_tx,subframe,
396
        ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
397

398 399
  if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
    if ((subframe%5) == ue->scheduling_request_config[eNB_id].sr_ConfigIndex)
400
      return(1);
401 402
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 14) { // 10 ms SR period
    if (subframe==(ue->scheduling_request_config[eNB_id].sr_ConfigIndex-5))
403
      return(1);
404
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 34) { // 20 ms SR period
405
    if ((10*(proc->frame_tx&1)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
406
      return(1);
407
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 74) { // 40 ms SR period
408
    if ((10*(proc->frame_tx&3)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
409
      return(1);
410
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 154) { // 80 ms SR period
411
    if ((10*(proc->frame_tx&7)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
412 413 414 415 416 417
      return(1);
  }

  return(0);
}

418 419 420 421 422 423 424 425 426 427 428
uint8_t is_cqi_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
{
  int subframe = proc->subframe_tx;
  int frame    = proc->frame_tx;
  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;

  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for CQI TXOp (cqi_ConfigIndex %d) isCQIOp %d\n",
  //      ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame,subframe,
  //      cqirep->cqi_PMI_ConfigIndex,
  //      (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI));

429 430 431
  if (cqirep->cqi_PMI_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
    return(1);
  else
    return(0);
}
uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
{


  int subframe = proc->subframe_tx;
  int frame    = proc->frame_tx;
  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
  int log2Mri = cqirep->ri_ConfigIndex/161;
  int N_OFFSET_RI = cqirep->ri_ConfigIndex % 161;

  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for RI TXOp (ri_ConfigIndex %d) isRIOp %d\n",
  //      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<<log2Mri)) == 0));
450 451 452
  if (cqirep->ri_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
453 454 455 456 457
    return(1);
  else
    return(0);
}

hbilel's avatar
hbilel committed
458 459 460 461 462 463 464 465
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)
hbilel's avatar
hbilel committed
466
{
467 468
    //PHY_MEASUREMENTS *meas = &ue->measurements;
    //uint8_t transmission_mode = ue->transmission_mode[eNB_id];
hbilel's avatar
hbilel committed
469 470


471
    //LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format);
hbilel's avatar
hbilel committed
472
    if (cqi_status == 1 || ri_status == 1)
hbilel's avatar
hbilel committed
473
    {
hbilel's avatar
hbilel committed
474
        ulsch->O = 4;
hbilel's avatar
hbilel committed
475 476 477
    }
}

478
void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS)
hbilel's avatar
hbilel committed
479
{
480

481 482 483 484 485 486 487 488
  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;
hbilel's avatar
hbilel committed
489 490 491

  // check for SRS opportunity
  pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
492
  pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS;
hbilel's avatar
hbilel committed
493

494
  if (isSubframeSRS) {
495
    LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
fnabet's avatar
fnabet committed
496 497
      if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
      {
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
          compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset);

          LOG_D(PHY," srsPeriodicity: %d srsOffset: %d isSubframeSRS %d \n",srsPeriodicity,srsOffset,isSubframeSRS);

          // transmit SRS if the four following constraints are respected:
          // - UE is configured to transmit SRS
          // - SRS are configured in current subframe
          // - UE is configured to send SRS in this subframe

          // 36.213 8.2
          // 1- A UE shall not transmit SRS whenever SRS and PUCCH format 2/2a/2b transmissions happen to coincide in the same subframe
          // 2- A UE shall not transmit SRS whenever SRS transmit
          //    on and PUCCH transmission carrying ACK/NACK and/or
          //    positive SR happen to coincide in the same subframe if the parameter
          //    Simultaneous-AN-and-SRS is FALSE

          // check PUCCH format 2/2a/2b transmissions
          is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0);
          is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe;

          // check ACK/SR transmission
          if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE)
          {
              if(is_SR_TXOp(ue,proc,eNB_id))
              {
                  uint32_t SR_payload = 0;
                  if (ue->mac_enabled==1)
                  {
                      int Mod_id = ue->Mod_id;
                      int CC_id = ue->CC_id;
528 529 530 531
                      SR_payload = ue_get_SR(Mod_id,
					     CC_id,
					     frame_tx,
					     eNB_id,
532
					     ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
533
					     subframe_tx); // subframe used for meas gap
534 535 536 537 538 539 540 541

                      if (SR_payload > 0)
                          is_sr_an_subframe = 1;
                  }
              }

              uint8_t pucch_ack_payload[2];
              if (get_ack(&ue->frame_parms,
542
                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
hbilel's avatar
hbilel committed
543
                      subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0)
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
              {
                  is_sr_an_subframe = 1;
              }
          }

          // check SRS UE opportunity
          if( isSubframeSRS  &&
                  (((10*frame_tx+subframe_tx) % srsPeriodicity) == srsOffset)
          )
          {
              if ((is_pucch2_subframe == 0) && (is_sr_an_subframe == 0))
              {
                  pSoundingrs_ul_config_dedicated->srsUeSubframe = 1;
                  ue->ulsch[eNB_id]->srs_active   = 1;
                  ue->ulsch[eNB_id]->Nsymb_pusch  = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active;
              }
              else
              {
                  LOG_I(PHY,"DROP UE-SRS-TX for this subframe %d.%d: collision with PUCCH2 or SR/AN: PUCCH2-occasion: %d, SR-AN-occasion[simSRS-SR-AN %d]: %d  \n", frame_tx, subframe_tx, is_pucch2_subframe, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, is_sr_an_subframe);
              }
          }
fnabet's avatar
fnabet committed
565
      }
fnabet's avatar
fnabet committed
566
      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);
hbilel's avatar
hbilel committed
567 568 569
  }
}

570

Raymond Knopp's avatar
Raymond Knopp committed
571 572 573 574 575 576 577 578 579 580 581 582
void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
{

  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
  int cqi_PMI_ConfigIndex = cqirep->cqi_PMI_ConfigIndex;

  if (ue->frame_parms.frame_type == FDD) {
    if (cqi_PMI_ConfigIndex <= 1) {        // 2 ms CQI_PMI period
      cqirep->Npd = 2;
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex;
    } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
      cqirep->Npd = 5;
583
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
Raymond Knopp's avatar
Raymond Knopp committed
584 585
    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
      cqirep->Npd = 10;
586
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
Raymond Knopp's avatar
Raymond Knopp committed
587 588
    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
      cqirep->Npd = 20;
589
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
Raymond Knopp's avatar
Raymond Knopp committed
590 591
    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
      cqirep->Npd = 40;
592
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
Raymond Knopp's avatar
Raymond Knopp committed
593 594
    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
      cqirep->Npd = 80;
595
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
Raymond Knopp's avatar
Raymond Knopp committed
596 597
    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
      cqirep->Npd = 160;
598
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
Raymond Knopp's avatar
Raymond Knopp committed
599 600
    }
    else if (cqi_PMI_ConfigIndex > 317) {
601

Raymond Knopp's avatar
Raymond Knopp committed
602
      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
603
  cqirep->Npd = 32;
604
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
Raymond Knopp's avatar
Raymond Knopp committed
605 606
      }
      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
607 608
  cqirep->Npd = 64;
  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
Raymond Knopp's avatar
Raymond Knopp committed
609 610
      }
      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
611 612 613
  cqirep->Npd = 128;
  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
      }
Raymond Knopp's avatar
Raymond Knopp committed
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
    }
  }
  else { // TDD
   if (cqi_PMI_ConfigIndex == 0) {        // all UL subframes
     cqirep->Npd = 1;
     cqirep->N_OFFSET_CQI = 0;
   } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
     cqirep->Npd = 5;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-1;
   } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
     cqirep->Npd = 10;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-6;
   } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
     cqirep->Npd = 20;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-16;
   } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
     cqirep->Npd = 40;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-36;
   } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
     cqirep->Npd = 80;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-76;
   } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
     cqirep->Npd = 160;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-156;
   }
  }
}

642 643 644 645 646
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,
hbilel's avatar
hbilel committed
647 648
                             uint8_t ri_status,
                             uint8_t bundling_flag)
649 650 651 652 653 654 655
{
  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
hbilel's avatar
hbilel committed
656
      if((nb_cw == 1)&&(bundling_flag==bundling))
657 658 659
      {
          return pucch_format1a;
      }
hbilel's avatar
hbilel committed
660 661 662 663
      if((nb_cw == 1)&&(bundling_flag==multiplexing))
      {
          return pucch_format1b;
      }
664 665 666 667 668 669
      if(nb_cw == 2)
      {
          return pucch_format1b;
      }
      if(SR_payload == 1)
      {
gabrielC's avatar
gabrielC committed
670 671
          return pucch_format1;
          /*
672 673 674 675 676
          if (frame_type == FDD) {
              return pucch_format1;
          } else if (frame_type == TDD) {
              return pucch_format1b;
          } else {
677
              AssertFatal(1==0,"Unknown frame_type");
gabrielC's avatar
gabrielC committed
678
          }*/
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
      }
  }
  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;
      }
  }
hbilel's avatar
hbilel committed
708
  return pucch_format1a;
709
}
710
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
711
          UE_rxtx_proc_t *proc,
712
                      harq_status_t *harq_ack,
713 714 715 716
                      uint8_t eNB_id,
                      uint8_t *b,
                      uint8_t SR)
{
717

718
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
719
  uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2;
720
  ANFBmode_t bundling_flag;
gabrielC's avatar
gabrielC committed
721
  uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter;
722 723
  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
724 725
  int sf;
  int M;
726
  uint8_t ack_counter=0;
727
  // clear this, important for case where n1_pucch selection is not used
728
  int subframe=proc->subframe_tx;
729

730
  ue->pucch_sel[subframe] = 0;
731 732 733

  if (frame_parms->frame_type == FDD ) { // FDD
    sf = (subframe<4)? subframe+6 : subframe-4;
734
    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
735 736

    if (SR == 0)
737
      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
738
    else
739
      return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
740
  } else {
741

742
    bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
743
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
744 745

    if (bundling_flag==bundling) {
gabrielC's avatar
gabrielC committed
746
      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,
747
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
748
    } else {
gabrielC's avatar
gabrielC committed
749
      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,
750
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
751
    }
752

753
LOG_DEBUG_END
754

755 756 757 758 759
    switch (frame_parms->tdd_config) {
    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL

      harq_ack0 = 2; // DTX
      M=1;
760

761
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
762 763 764
      if (subframe == 2) {  // ACK subframes 5,6
        candidate_dl[0] = 6;
        candidate_dl[1] = 5;
765 766
        M=2;
      } else if (subframe == 3) { // ACK subframe 9
767 768 769 770
        candidate_dl[0] = 9;
      } else if (subframe == 7) { // ACK subframes 0,1
        candidate_dl[0] = 1;
        candidate_dl[1] = 0;
771 772
        M=2;
      } else if (subframe == 8) { // ACK subframes 4
773
        candidate_dl[0] = 4;
774
      } else {
775
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal tx-subframe %d for tdd_config %d\n",
776
              ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config);
777
        return(0);
778 779
      }

780 781 782 783 784 785 786 787 788
      // checking which downlink candidate is the last downlink with valid DL-DCI
      int k;
      for (k=0;k<M;k++) {
        if (harq_ack[candidate_dl[k]].send_harq_status>0) {
          last_dl = candidate_dl[k];
          break;
        }
      }
      if (last_dl >= 10) {
789 790
        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);
791 792 793 794 795 796 797
        return (0);
      }

      LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch0 from last_dl=%d\n",
          proc->frame_tx%1024,
          proc->subframe_tx,
          last_dl);
798 799

      // i=0
800
      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[last_dl];
801
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
802

803
      harq_ack0 = b[0];
804 805

      if (harq_ack0!=2) {  // DTX
806 807 808 809
        if (frame_parms->frame_type == FDD ) {
          if (SR == 0) {  // last paragraph pg 68 from 36.213 (v8.6), m=0
            b[0]=(M==2) ? 1-harq_ack0 : harq_ack0;
            b[1]=harq_ack0;   // in case we use pucch format 1b (subframes 2,7)
810
          ue->pucch_sel[subframe] = 0;
811 812 813
            return(n1_pucch0);
          } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213)
            b[0]=harq_ack0;
814
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
815 816 817 818 819 820 821 822 823 824 825 826
          }
        } else {
          if (SR == 0) {
            b[0] = harq_ack0;
            b[1] = harq_ack0;
            ue->pucch_sel[subframe] = 0;
            return(n1_pucch0);
          } else {
            b[0] = harq_ack0;
            b[1] = harq_ack0;
            return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
          }
827
        }
828 829 830 831
      }


      break;
832

833 834 835 836 837 838 839
    case 3:  // DL:S:UL:UL:UL:DL:DL:DL:DL:DL
      // in this configuration we have M=2 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_ack1 = 2; // DTX
      harq_ack0 = 2; // DTX
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
840
      last_dl = (subframe-2)<<1;
841
      // i=0
842
      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+last_dl];
843
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
844
      // i=1
845
      nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+last_dl)%10];
846
      n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
847 848

      // set ACK/NAK to values if not DTX
849 850
      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
851

852 853
      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].ack;
854

855 856 857 858 859
      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);
860 861

      if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
862 863 864 865 866 867 868 869 870

        if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
          // n1_pucch index takes value of smallest element in set {0,1}
          // i.e. 0 if harq_ack0 is not DTX, otherwise 1
          b[0] = harq_ack1;

          if (harq_ack0!=2)
            b[0]=b[0]&harq_ack0;

871
          ue->pucch_sel[subframe] = 1;
872 873 874 875 876 877 878 879 880 881
          return(n1_pucch1);

        } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
          if (harq_ack0 == 2)
            harq_ack0 = 0;

          b[1] = harq_ack0;
          b[0] = (harq_ack0!=harq_ack1)?0:1;

          if ((harq_ack0 == 1) && (harq_ack1 == 0)) {
882
            ue->pucch_sel[subframe] = 0;
883 884
            return(n1_pucch0);
          } else {
885
            ue->pucch_sel[subframe] = 1;
886 887 888 889 890 891 892 893 894
            return(n1_pucch1);
          }
        } 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 == 2)
            harq_ack0 = 0;

          b[0]= harq_ack1 | harq_ack0;
          b[1]= harq_ack1 ^ harq_ack0;
895
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
896 897 898 899
        }
      } else if (harq_ack0!=2) { // n-7  // subframe 5,7,9 only is to be ACK/NAKed
        if ((bundling_flag==bundling)&&(SR == 0)) {  // last paragraph pg 68 from 36.213 (v8.6), m=0
          b[0]=harq_ack0;
900
          ue->pucch_sel[subframe] = 0;
901 902 903 904
          return(n1_pucch0);
        } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 with i=1 set to DTX
          b[0] = harq_ack0;
          b[1] = 1-b[0];
905
          ue->pucch_sel[subframe] = 0;
906 907 908 909
          return(n1_pucch0);
        } else if (SR==1) { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213)
          b[0]=harq_ack0;
          b[1]=b[0];
910
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
911
        }
912
      }
913

914 915
      break;

916 917 918 919 920 921 922 923 924 925 926 927
    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
928 929
          //nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
930 931
          n1_pucch0 = 2*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=1
932
          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
933 934
          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
935
          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
936

937 938
          n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=3
939
          //nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(9+subframe)%10];
940 941 942
          //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
943 944
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
945

946 947
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
            harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].ack;
948

949 950
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
            harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].ack;
951

952 953
          //if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
954 955 956 957 958 959 960 961
          //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

962
          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[4+subframe];
963 964
          n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=1
965
          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+subframe];
966 967
          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
968
          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+subframe)];
969 970
          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
971
          nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(3+subframe)];
972 973 974
          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
975 976
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
          harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].ack;
977

978 979
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
          harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].ack;
980

981 982
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
          harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].ack;
983

984 985
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
          harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].ack;
986 987 988 989 990 991 992 993 994 995
          }

          //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,
996 997 998 999 1000 1001 1002 1003
             b[0] = 1;
             ack_counter = 0;

             if ((harq_ack3!=2) ) {
                b[0] = b[0]&harq_ack3;
                n1_pucch_inter = n1_pucch3;
                ack_counter ++;
             }
1004
             if ((harq_ack0!=2) ) {
1005
                b[0] = b[0]&harq_ack0;
1006
                n1_pucch_inter = n1_pucch0;
1007
                ack_counter ++;
1008 1009 1010 1011
             }
             if ((harq_ack1!=2) ) {
                b[0] = b[0]&harq_ack1;
                n1_pucch_inter = n1_pucch1;
1012
                ack_counter ++;
1013 1014 1015 1016
             }
             if ((harq_ack2!=2) ) {
                b[0] = b[0]&harq_ack2;
                n1_pucch_inter = n1_pucch2;
1017
                ack_counter ++;
1018 1019
             }

1020 1021 1022 1023
             if (ack_counter == 0)
                 b[0] = 0;

             /*if (subframe == 3) {
1024 1025
                n1_pucch_inter = n1_pucch2;
             } else if (subframe == 2) {
1026 1027
                n1_pucch_inter = n1_pucch1;
             }*/
1028

gabrielC's avatar
gabrielC committed
1029
             //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d  b[0]=%d b[1]=%d \n",
1030 1031
             //                                           proc->frame_tx%1024,
             //                                           proc->subframe_tx,n1_pucch_inter,
gabrielC's avatar
gabrielC committed
1032
             //                                           b[0],b[1]);
1033 1034 1035 1036 1037

              return(n1_pucch_inter);

            } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1

hbilel's avatar
hbilel committed
1038 1039
             if (subframe == 3) {
                 LOG_I(PHY, "sbuframe=%d \n",subframe);
1040 1041
              if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
                b[0] = 1;
hbilel's avatar
hbilel committed
1042
                b[1] = 1;
1043 1044 1045 1046 1047 1048 1049
                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[0] = 1;
hbilel's avatar
hbilel committed
1050
                b[1] = 1;
1051 1052
                return(n1_pucch2);
              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
hbilel's avatar
hbilel committed
1053 1054
                b[0] = 1;
                b[1] = 0;
1055 1056
                return(n1_pucch1);
              } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
hbilel's avatar
hbilel committed
1057 1058
                b[0] = 1;
                b[1] = 0;
1059 1060
                return(n1_pucch0);
              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
hbilel's avatar
hbilel committed
1061 1062
                b[0] = 1;
                b[1] = 0;
1063 1064 1065 1066 1067 1068 1069
                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[0] = 1;
hbilel's avatar
hbilel committed
1070
                b[1] = 1;
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
                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);
                }
hbilel's avatar
hbilel committed
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
             } else if (subframe == 2) {
                if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
                 b[0] = 1;
                 b[1] = 1;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 1;
                 b[1] = 1;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
                 b[0] = 1;
                 b[1] = 1;
                 return(n1_pucch0);
               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 0;
                 b[1] = 1;
                 return(n1_pucch0);
               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
                 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))) {
                 b[1] = 0;
                 b[0] = 0;
                 return(n1_pucch1);
               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
                 b[0] = 0;
                 b[1] = 0;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 2) && (harq_ack1 == 2) && (harq_ack2 == 0)) {
                 b[0] = 0;
                 b[1] = 1;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 2) && (harq_ack1 == 0) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 1;
                 b[1] = 0;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 0) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 1;
                 b[1] = 0;
                 return(n1_pucch0);
               }
1159

hbilel's avatar
hbilel committed
1160
             }
1161 1162
            } 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
1163
              ack_counter = 0;
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
              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;

1206
    }  // switch tdd_config
1207
  }
1208

Cedric Roux's avatar
Cedric Roux committed
1209
  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n", ue->Mod_id, proc->frame_tx);
1210 1211 1212 1213
  return(-1);
}


hbilel's avatar
hbilel committed
1214
void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empty_subframe) {
1215

1216
  int aa;
1217
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
1218

1219 1220 1221
  int nsymb;
  int subframe_tx = proc->subframe_tx;
  int ulsch_start;
1222
  int overflow=0;
1223
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1224
  int k,l;
1225
  int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16)));
1226 1227
#endif

1228
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);
1229
LOG_DEBUG_BEGIN(UE_TIMING)
1230
  start_meas(&ue->ofdm_mod_stats);
1231
LOG_DEBUG_END
1232
  nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
1233

1234 1235
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
  ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
         ue->hw_timing_advance-
         ue->timing_advance-
         ue->N_TA_offset+5);
  //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);

  if(ulsch_start < 0)
      ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);

  if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti))
      ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);

  //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);
1248 1249 1250
#else //this is the normal case
  ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
#endif //else EXMIMO
hbilel's avatar
hbilel committed
1251 1252 1253

  if (empty_subframe)
  {
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
    overflow = ulsch_start - 9*frame_parms->samples_per_tti;
    for (aa=0; aa<frame_parms->nb_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);
	}
    }
    return;
hbilel's avatar
hbilel committed
1268
  }
1269

1270 1271 1272 1273
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
    if (frame_parms->Ncp == 1)
      PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1274
       dummy_tx_buffer,
1275
#else
1276
       &ue->common_vars.txdata[aa][ulsch_start],
1277
#endif
1278 1279 1280 1281
       frame_parms->ofdm_symbol_size,
       nsymb,
       frame_parms->nb_prefix_samples,
       CYCLIC_PREFIX);
1282
    else {
1283 1284
      normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1285
			dummy_tx_buffer,
1286
#else
1287
			&ue->common_vars.txdata[aa][ulsch_start],
1288
#endif
1289 1290
			nsymb>>1,
			&ue->frame_parms);
1291
      
1292 1293 1294 1295 1296 1297 1298 1299
      normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
			dummy_tx_buffer+(frame_parms->samples_per_tti>>1),
#else
			&ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)],
#endif
			nsymb>>1,
			&ue->frame_parms);
1300
    }
1301

1302 1303 1304 1305 1306 1307 1308
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
    apply_7_5_kHz(ue,dummy_tx_buffer,0);
    apply_7_5_kHz(ue,dummy_tx_buffer,1);
#else
    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
#endif
1309 1310


1311 1312
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
    overflow = ulsch_start - 9*frame_parms->samples_per_tti;
1313 1314


1315
    for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) {
1316 1317
      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l];
      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1];
1318
    }
1319

1320
    for (k=0; k<overflow; k++,l++) {
1321 1322
      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l];
      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1];
1323 1324 1325 1326 1327
    }
#if defined(EXMIMO)
    // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
    for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; k<ulsch_start ; k++) {
      if (k<0)
1328
	ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
1329
      else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
1330
	ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
1331
      else
1332
	ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
1333
    }
1334
#endif
1335
#endif
1336 1337 1338 1339 1340 1341
    /*
    only for debug
    LOG_I(PHY,"ul-signal [subframe: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",subframe_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance);
    if( (crash == 1) && (subframe_tx == 0) )
    {
      LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start);
bruno mongazon's avatar
bruno mongazon committed
1342
      LOG_M("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
1343 1344
    }
    */
1345

1346
  } //nb_antennas_tx
1347

1348
LOG_DEBUG_BEGIN(UE_TIMING)
gabrielC's avatar
gabrielC committed
1349
      stop_meas(&ue->ofdm_mod_stats);
1350
LOG_DEBUG_END
1351

1352
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
1353

1354
}
1355

1356
void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
1357

1358 1359
  int frame_tx = proc->frame_tx;
  int subframe_tx = proc->subframe_tx;
1360
  LOG_USEDINLOG_VAR(int, prach_power);
1361
  PRACH_RESOURCES_t prach_resources_local;
1362

1363 1364
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);

1365
  ue->generate_prach=0;
1366

1367 1368 1369 1370 1371
  if (ue->mac_enabled==0){
    ue->prach_resources[eNB_id] = &prach_resources_local;
    prach_resources_local.ra_RNTI = 0xbeef;
    prach_resources_local.ra_PreambleIndex = 0;
  }
1372

1373 1374 1375
  if (ue->mac_enabled==1){
    // ask L2 for RACH transport
    if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
1376
      //LOG_D(PHY,"Getting PRACH resources\n");
1377

1378 1379 1380 1381 1382
      ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id,
						ue->CC_id,
						frame_tx,
						eNB_id,
						subframe_tx);
1383
      LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
1384 1385
    }
  }
1386

1387
  if (ue->prach_resources[eNB_id]!=NULL) {
1388

1389 1390 1391 1392 1393
    ue->generate_prach=1;
    ue->prach_cnt=0;
#ifdef SMBV
    ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
#endif
1394 1395 1396 1397 1398 1399 1400
    LOG_I(PHY,"mode %d\n",mode);
    
    if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
      ue->tx_power_dBm[subframe_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
    }
    else {
      ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1401
      ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
1402 1403
    }
    
1404
    LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d,  P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
	  ue->Mod_id,
	  frame_tx,
	  subframe_tx,
	  ue->prach_resources[eNB_id]->ra_PreambleIndex,
	  get_PL(ue->Mod_id,ue->CC_id,eNB_id),
	  ue->tx_power_dBm[subframe_tx],
	  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
	  ue->prach_resources[eNB_id]->ra_TDD_map_index,
	  ue->prach_resources[eNB_id]->ra_RNTI);
    
    ue->tx_total_RE[subframe_tx] = 96;
    
1417
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1418 1419 1420 1421
    ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
					     ue->tx_power_max_dBm,
					     ue->frame_parms.N_RB_UL,
					     6);
1422

1423
#else
1424
    ue->prach_vars[eNB_id]->amp = AMP;
1425
#endif
1426

1427 1428
    if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n",
1429
	    ue->Mod_id,
1430 1431
	    proc->frame_rx,
	    proc->subframe_tx,
1432
	    ue->tx_power_dBm[subframe_tx],
1433 1434 1435
	    ue->prach_vars[eNB_id]->amp);
    
    
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446
    //      start_meas(&ue->tx_prach);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
    prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
    //      stop_meas(&ue->tx_prach);
    LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
	  ue->Mod_id,
	  get_PL(ue->Mod_id,ue->CC_id,eNB_id),
	  ue->tx_power_dBm[subframe_tx],
	  dB_fixed(prach_power),
	  ue->prach_vars[eNB_id]->amp);
1447

Raymond Knopp's avatar
Raymond Knopp committed
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
    if (ue->mac_enabled==1){
      Msg1_transmitted(ue->Mod_id,
		       ue->CC_id,
		       frame_tx,
		       eNB_id);
    }
    
    LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
	  ue->Mod_id,frame_tx,subframe_tx,eNB_id,
	  ue->prach_resources[eNB_id]->ra_PreambleIndex,
	  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id),
	  get_PL(ue->Mod_id,ue->CC_id,eNB_id));
    
    
    
    // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
    if (mode == calib_prach_tx)
      ue->prach_resources[eNB_id]=NULL;
1466

Raymond Knopp's avatar
Raymond Knopp committed
1467 1468
    LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n",
	  ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
1469

Raymond Knopp's avatar
Raymond Knopp committed
1470
    ue->prach_cnt++;
1471

Raymond Knopp's avatar
Raymond Knopp committed
1472 1473 1474
    if (ue->prach_cnt==3)
      ue->generate_prach=0;
  }
1475
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
1476
}
1477

1478
void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1479

1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
  int harq_pid;
  int frame_tx=proc->frame_tx;
  int subframe_tx=proc->subframe_tx;
  int Mod_id = ue->Mod_id;
  int CC_id = ue->CC_id;
  uint8_t Msg3_flag=0;
  uint16_t first_rb, nb_rb;
  unsigned int input_buffer_length;
  int i;
  int aa;
  int tx_amp;
1491
  uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32)));
1492
  uint8_t access_mode;
1493
  uint8_t Nbundled=0;
hbilel's avatar
hbilel committed
1494
  uint8_t NbundledCw1=0;
hbilel's avatar
hbilel committed
1495 1496
  uint8_t ack_status_cw0=0;
  uint8_t ack_status_cw1=0;
hbilel's avatar
hbilel committed
1497 1498
  uint8_t cqi_status = 0;
  uint8_t ri_status  = 0;
1499 1500
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN);

1501 1502
  // get harq_pid from subframe relationship
  harq_pid = subframe2harq_pid(&ue->frame_parms,
1503 1504 1505
             frame_tx,
             subframe_tx);

1506 1507 1508
  LOG_D(PHY,"Frame %d, Subframe %d : ue_uespec_procedures, harq_pid %d => subframe_scheduling %d\n",
	frame_tx,subframe_tx,harq_pid,
	ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag);
1509

1510
  if (ue->mac_enabled == 1) {
1511 1512 1513
    if ((ue->ulsch_Msg3_active[eNB_id] == 1)       &&
	(ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
	(ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3
1514

1515
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
1516

1517
      if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
1518 1519 1520
	generate_ue_ulsch_params_from_rar(ue,
					  proc,
					  eNB_id);
1521

1522 1523
      ue->ulsch[eNB_id]->power_offset = 14;
      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n",
1524 1525 1526 1527
      Mod_id,
      frame_tx,
      subframe_tx,
      harq_pid);
1528 1529
      Msg3_flag = 1;
    } else {
1530

1531
      
1532
      AssertFatal(harq_pid!=255,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, exiting\n",
1533
	      Mod_id,frame_tx, subframe_tx);
1534 1535 1536
      Msg3_flag=0;
    }
  }
1537

1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {

    uint8_t isBad = 0;
    if (ue->frame_parms.N_RB_UL <= ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) {
      LOG_D(PHY,"Invalid PUSCH first_RB=%d for N_RB_UL=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
          ue->frame_parms.N_RB_UL);
      isBad = 1;
    }
    if (ue->frame_parms.N_RB_UL < ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) {
      LOG_D(PHY,"Invalid PUSCH num_RB=%d for N_RB_UL=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
          ue->frame_parms.N_RB_UL);
      isBad = 1;
    }
    if (0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) {
      LOG_D(PHY,"Invalid PUSCH first_RB=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb);
      isBad = 1;
    }
    if (0 >= ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) {
      LOG_D(PHY,"Invalid PUSCH num_RB=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb);
      isBad = 1;
    }
    if (ue->frame_parms.N_RB_UL < (ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb)) {
      LOG_D(PHY,"Invalid PUSCH num_RB=%d + first_RB=%d for N_RB_UL=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
          ue->frame_parms.N_RB_UL);
      isBad = 1;
    }
    if ((0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx) ||
        (3 < ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx)) {
      LOG_D(PHY,"Invalid PUSCH RV index=%d\n", ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx);
      isBad = 1;
    }

    if (isBad) {
hbilel's avatar
hbilel committed
1577
      LOG_I(PHY,"Skip PUSCH generation!\n");
1578 1579 1580
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
    }
  }
1581
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
1582

1583
    ue->generate_ul_signal[eNB_id] = 1;
1584

1585
    // deactivate service request
1586
    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
1587
    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);
1588
    if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1))
1589
    {
1590
      //        LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n");
1591 1592 1593
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
    }
1594

hbilel's avatar
hbilel committed
1595
    ack_status_cw0 = reset_ack(&ue->frame_parms,
1596
            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
hbilel's avatar
hbilel committed
1597
            subframe_tx,
hbilel's avatar
hbilel committed
1598 1599 1600 1601
            proc->subframe_rx,
            ue->ulsch[eNB_id]->o_ACK,
            &Nbundled,
            0);
hbilel's avatar
hbilel committed
1602
    ack_status_cw1 = reset_ack(&ue->frame_parms,
1603
            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
hbilel's avatar
hbilel committed
1604
            subframe_tx,
hbilel's avatar
hbilel committed
1605 1606 1607 1608 1609
            proc->subframe_rx,
            ue->ulsch[eNB_id]->o_ACK,
            &NbundledCw1,
            1);

1610
    //Nbundled = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack;
hbilel's avatar
hbilel committed
1611
    //ue->ulsch[eNB_id]->bundling = Nbundled;
hbilel's avatar
hbilel committed
1612

1613 1614
    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
1615

1616

hbilel's avatar
hbilel committed
1617 1618 1619 1620 1621 1622
    // 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));
1623

hbilel's avatar
hbilel committed
1624 1625 1626
    // 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);

hbilel's avatar
hbilel committed
1627
    if (ack_status_cw0 > 0) {
1628 1629 1630

      // check if we received a PDSCH at subframe_tx - 4
      // ==> send ACK/NACK on PUSCH
1631 1632 1633 1634 1635
      if (ue->frame_parms.frame_type == FDD)
      {
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1;
      }

1636

1637
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
1638 1639 1640
    if(ue->ulsch[eNB_id]->o_ACK[0])
    {
    	LOG_I(PHY,"PUSCH ACK\n");
Cedric Roux's avatar
Cedric Roux committed
1641
        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
1642
                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
1643 1644 1645 1646
    }
    else
    {
    	LOG_I(PHY,"PUSCH NACK\n");
Cedric Roux's avatar
Cedric Roux committed
1647
        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
1648
                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
1649
    }
gabrielC's avatar
gabrielC committed
1650
      LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
1651 1652
        Mod_id,
        ue->ulsch[eNB_id]->rnti,
1653
        frame_tx%1024,subframe_tx,
1654 1655
        ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
1656
LOG_DEBUG_END
1657 1658
    }

1659

1660
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
1661
        LOG_D(PHY,
hbilel's avatar
hbilel committed
1662
              "[UE  %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, "
1663
              "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",
1664
          Mod_id,harq_pid,frame_tx%1024,subframe_tx,
1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676
          first_rb,nb_rb,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
          (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
           ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
           ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12,
          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
          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,
1677 1678 1679 1680 1681
          ack_status_cw0,
          ack_status_cw1,
          ue->ulsch[eNB_id]->bundling, Nbundled,
          cqi_status,
          ri_status);
1682
LOG_DEBUG_END
1683 1684 1685 1686 1687





1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703
    if (Msg3_flag == 1) {
      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx,
	    subframe_tx,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
	    ue->prach_resources[eNB_id]->Msg3[0],
	    ue->prach_resources[eNB_id]->Msg3[1],
	    ue->prach_resources[eNB_id]->Msg3[2],
	    ue->prach_resources[eNB_id]->Msg3[3],
	    ue->prach_resources[eNB_id]->Msg3[4],
	    ue->prach_resources[eNB_id]->Msg3[5],
	    ue->prach_resources[eNB_id]->Msg3[6],
	    ue->prach_resources[eNB_id]->Msg3[7],
	    ue->prach_resources[eNB_id]->Msg3[8]);
1704
LOG_DEBUG_BEGIN(UE_TIMING)
1705
      start_meas(&ue->ulsch_encoding_stats);
1706
LOG_DEBUG_END
1707
      
1708 1709 1710 1711 1712 1713 1714
      AssertFatal(ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
				 ue,
				 harq_pid,
				 eNB_id,
				 proc->subframe_rx,
				 ue->transmission_mode[eNB_id],0,0)==0,
		  "ulsch_coding.c: FATAL ERROR: returning\n");
1715
      
1716
LOG_DEBUG_BEGIN(UE_TIMING)
1717
      stop_meas(&ue->phy_proc_tx);
1718
      LOG_UI(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0));
1719
      stop_meas(&ue->ulsch_encoding_stats);
1720 1721
LOG_DEBUG_END

1722
      if (ue->mac_enabled == 1) {
1723

1724
	// signal MAC that Msg3 was sent
1725 1726 1727 1728
	Msg3_transmitted(Mod_id,
			 CC_id,
			 frame_tx,
			 eNB_id);
1729
      }
1730
      LOG_I(PHY,"Done Msg3 encoding\n");
1731
    } // Msg3_flag==1
1732
    else {// Msg3_flag==0
1733
      input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
1734

1735
      if (ue->mac_enabled==1) {
1736

1737 1738 1739 1740
	//  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
	  //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
	  access_mode=SCHEDULED_ACCESS;
1741

1742 1743 1744 1745 1746 1747 1748 1749
	  ue_get_sdu(Mod_id,
		     CC_id,
		     frame_tx,
		     subframe_tx,
		     eNB_id,
		     ulsch_input_buffer,
		     input_buffer_length,
		     &access_mode);
1750 1751
	}
	
1752 1753 1754
      

	
1755
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
1756 1757 1758 1759 1760 1761
	LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
	
	for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
	  LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
	
	LOG_T(PHY,"\n");
1762
LOG_DEBUG_END
1763 1764 1765 1766 1767 1768 1769 1770 1771
      }
      else {
	unsigned int taus(void);
	
	for (i=0; i<input_buffer_length; i++)
	  ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
	
      }
      
1772
LOG_DEBUG_BEGIN(UE_TIMING)
1773
      start_meas(&ue->ulsch_encoding_stats);
1774
LOG_DEBUG_END
1775
      if (abstraction_flag==0) {
1776
	
1777 1778 1779 1780
	if (ulsch_encoding(ulsch_input_buffer,
			   ue,
			   harq_pid,
			   eNB_id,
hbilel's avatar
hbilel committed
1781
			   proc->subframe_rx,
1782 1783
			   ue->transmission_mode[eNB_id],0,
			   Nbundled)!=0) {
1784 1785
	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
1786
LOG_DEBUG_BEGIN(UE_TIMING)
1787
	  stop_meas(&ue->phy_proc_tx);
1788
LOG_DEBUG_END
1789
	  return;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1790
	}
1791 1792
      }
      
1793
LOG_DEBUG_BEGIN(UE_TIMING)
1794
      stop_meas(&ue->ulsch_encoding_stats);
1795
LOG_DEBUG_END
1796
    }
1797
    
1798 1799
    if (abstraction_flag == 0) {
      if (ue->mac_enabled==1) {
1800 1801
	pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
	ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
1802 1803
      }
      else {
1804
	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1805
      }
1806
      ue->tx_total_RE[subframe_tx] = nb_rb*12;
1807
      
kaltenbe's avatar
kaltenbe committed
1808
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1809
      tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
1810 1811 1812
			  ue->tx_power_max_dBm,
			  ue->frame_parms.N_RB_UL,
			  nb_rb);
1813
#else
1814
    tx_amp = AMP;
1815
#endif
Cedric Roux's avatar
Cedric Roux committed
1816 1817

    T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
1818
      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));
1819

1820
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
1821
    LOG_D(PHY,"[UE  %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
1822
	  Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
1823 1824
LOG_DEBUG_END
LOG_DEBUG_BEGIN(UE_TIMING)
1825
    start_meas(&ue->ulsch_modulation_stats);
1826
LOG_DEBUG_END
1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841
    ulsch_modulation(ue->common_vars.txdataF,
		     tx_amp,
		     frame_tx,
		     subframe_tx,
		     &ue->frame_parms,
		     ue->ulsch[eNB_id]);
    for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++)
      generate_drs_pusch(ue,
			 proc,
			 eNB_id,
			 tx_amp,
			 subframe_tx,
			 first_rb,
			 nb_rb,
			 aa);
1842 1843

LOG_DEBUG_BEGIN(UE_TIMING)
1844
    stop_meas(&ue->ulsch_modulation_stats);
1845
LOG_DEBUG_END
1846

1847
    }
1848
    
1849 1850 1851 1852 1853
    if (abstraction_flag==1) {
      // clear SR
      ue->sr[subframe_tx]=0;
    }
  } // subframe_scheduling_flag==1
1854 1855 1856

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT);

1857
}
1858

hbilel's avatar
hbilel committed
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885
void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag)
{

  //LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  //int8_t  frame_tx    = proc->frame_tx;
  int8_t  subframe_tx = proc->subframe_tx;
  int16_t tx_amp;
  int16_t Po_SRS;
  uint8_t nb_rb_srs;

  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
  uint8_t isSrsTxOccasion = pSoundingrs_ul_config_dedicated->srsUeSubframe;

  if(isSrsTxOccasion)
  {
    ue->generate_ul_signal[eNB_id] = 1;
    if (ue->mac_enabled==1)
    {
      srs_power_cntl(ue,proc,eNB_id, (uint8_t*)(&nb_rb_srs), abstraction_flag);
      Po_SRS = ue->ulsch[eNB_id]->Po_SRS;
    }
    else
    {
      Po_SRS = ue->tx_power_max_dBm;
    }

#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
fnabet's avatar
fnabet committed
1886 1887
    if (ue->mac_enabled==1)
    {
hbilel's avatar
hbilel committed
1888 1889 1890 1891
    tx_amp = get_tx_amp(Po_SRS,
                        ue->tx_power_max_dBm,
                        ue->frame_parms.N_RB_UL,
                        nb_rb_srs);
fnabet's avatar
fnabet committed
1892 1893 1894 1895 1896
    }
    else
    {
        tx_amp = AMP;
    }
hbilel's avatar
hbilel committed
1897 1898 1899
#else
      tx_amp = AMP;
#endif
fnabet's avatar
fnabet committed
1900
    LOG_D(PHY,"SRS PROC; TX_MAX_POWER %d, Po_SRS %d, NB_RB_UL %d, NB_RB_SRS %d TX_AMPL %d\n",ue->tx_power_max_dBm,
hbilel's avatar
hbilel committed
1901 1902 1903 1904 1905
            Po_SRS,
            ue->frame_parms.N_RB_UL,
            nb_rb_srs,
            tx_amp);

1906 1907
    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));
1908 1909 1910 1911 1912
    generate_srs(&ue->frame_parms,
     &ue->soundingrs_ul_config_dedicated[eNB_id],
     &ue->common_vars.txdataF[eNB_id][symbol_offset],
     tx_amp,
     subframe_tx);
hbilel's avatar
hbilel committed
1913 1914
  }
}
1915

Raymond Knopp's avatar
Raymond Knopp committed
1916 1917 1918 1919 1920
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
1921 1922 1923 1924
          /*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]));*/
Raymond Knopp's avatar
Raymond Knopp committed
1925 1926
    *len=4;
    return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
1927
        ue->transmission_mode[eNB_id]));
Raymond Knopp's avatar
Raymond Knopp committed
1928 1929
  }
  else { // Mode 1-1 feedback, later
1930
          //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
Raymond Knopp's avatar
Raymond Knopp committed
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943
    *len=0;
    // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI)

    // 2-antenna ports RI=2, 8 bits (1 PMI, 7 CQI/DIFF CQI)
    return(0);
  }
}


int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) {

  return(1);
}
1944

1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968

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:
1969 1970 1971
    case pucch_format1b_csA2:
    case pucch_format1b_csA3:
    case pucch_format1b_csA4:
1972 1973 1974
    {
        pucch_resource[0] = get_n1_pucch(ue,
                                         proc,
1975
                                         ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
1976 1977 1978 1979
                                         eNB_id,
                                         ack_payload,
                                         SR);
        pucch_payload[0]  = ack_payload[0];
hbilel's avatar
hbilel committed
1980 1981
        pucch_payload[1]  = ack_payload[1];
        //pucch_payload[1]  = 1;
1982 1983 1984 1985 1986 1987 1988 1989
    }
    break;

    case pucch_format2:
    {
        pucch_resource[0]    = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
        if(cqi_report)
        {
hbilel's avatar
hbilel committed
1990
            pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int*)plength);
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
        }
        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;
2004 2005 2006 2007

    case pucch_format3:
      fprintf(stderr, "PUCCH format 3 not handled\n");
      abort();
2008 2009 2010
    }
}

2011
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
2012 2013


2014 2015
  uint8_t  pucch_ack_payload[2];
  uint16_t pucch_resource;
2016 2017
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
Raymond Knopp's avatar
Raymond Knopp committed
2018

2019 2020 2021
  uint8_t  SR_payload;
  uint8_t  pucch_payload[2];
  uint16_t len;
Raymond Knopp's avatar
Raymond Knopp committed
2022

2023 2024 2025 2026 2027 2028
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  int frame_tx=proc->frame_tx;
  int subframe_tx=proc->subframe_tx;
  int Mod_id = ue->Mod_id;
  int CC_id = ue->CC_id;
  int tx_amp;
2029
  int16_t Po_PUCCH;
2030 2031 2032 2033 2034
  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;
2035

2036
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
2037

hbilel's avatar
hbilel committed
2038
  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
2039 2040 2041 2042 2043 2044

  // 36.213 8.2
  /*if ackNackSRS_SimultaneousTransmission ==  TRUE and in the cell specific SRS subframes UE shall transmit
    ACK/NACK and SR using the shortened PUCCH format. This shortened PUCCH format shall be used in a cell
    specific SRS subframe even if the UE does not transmit SRS in that subframe
  */
2045 2046 2047 2048 2049 2050 2051 2052

  int harq_pid = subframe2harq_pid(&ue->frame_parms,
                                   frame_tx,
                                   subframe_tx);

  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);
2053
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
2054 2055 2056
      return;
  }

fnabet's avatar
fnabet committed
2057
  uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
hbilel's avatar
hbilel committed
2058

2059
  bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
2060

2061 2062 2063 2064
  if ((frame_parms->frame_type==FDD) ||
      (bundling_flag==bundling)    ||
      ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) {
    format = pucch_format1a;
2065
    //    LOG_D(PHY,"[UE] PUCCH 1a\n");
2066 2067
  } else {
    format = pucch_format1b;
2068
    //    LOG_D(PHY,"[UE] PUCCH 1b\n");
2069
  }
2070

2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081
  // 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) {
2082 2083 2084 2085 2086 2087
	SR_payload = ue_get_SR(Mod_id,
			       CC_id,
			       frame_tx,
			       eNB_id,
			       ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
			       subframe_tx); // subframe used for meas gap
2088 2089 2090 2091
      }
      else {
          SR_payload = 1;
      }
2092
  }
Raymond Knopp's avatar
Raymond Knopp committed
2093

2094
  ack_status_cw0 = get_ack(&ue->frame_parms,
2095
                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
2096
                       subframe_tx,
hbilel's avatar
hbilel committed
2097
                       proc->subframe_rx,
2098 2099
                       pucch_ack_payload,
                       0);
2100

2101
  ack_status_cw1 = get_ack(&ue->frame_parms,
2102
                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
2103
                       subframe_tx,
hbilel's avatar
hbilel committed
2104
                       proc->subframe_rx,
2105 2106
                       pucch_ack_payload,
                       1);
Raymond Knopp's avatar
Raymond Knopp committed
2107

gabrielC's avatar
gabrielC committed
2108
  nb_cw = ( (ack_status_cw0 != 0) ? 1:0) + ( (ack_status_cw1 != 0) ? 1:0);
Raymond Knopp's avatar
Raymond Knopp committed
2109

2110 2111
  cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
      (is_cqi_TXOp(ue,proc,eNB_id)==1));
Raymond Knopp's avatar
Raymond Knopp committed
2112

2113 2114
  ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
           (is_ri_TXOp(ue,proc,eNB_id)==1));
Raymond Knopp's avatar
Raymond Knopp committed
2115

2116 2117
  // Part - II
  // if nothing to report ==> exit function
hbilel's avatar
hbilel committed
2118
  if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) )
2119
  {
2120
      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",
2121
            frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status);
2122 2123
      return;
  }
Raymond Knopp's avatar
Raymond Knopp committed
2124

2125 2126 2127 2128 2129 2130 2131
  // 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,
hbilel's avatar
hbilel committed
2132 2133
                            ri_status,
                            bundling_flag);
2134 2135 2136 2137 2138 2139 2140 2141 2142
  // 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,
hbilel's avatar
hbilel committed
2143
                  (uint8_t *)&pucch_payload,
2144 2145 2146
                  &len);


2147 2148
  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]);
2149 2150 2151 2152 2153 2154 2155 2156 2157 2158

  // Part - IV
  // Generate PUCCH signal
  ue->generate_ul_signal[eNB_id] = 1;

  switch (format) {
  case pucch_format1:
  case pucch_format1a:
  case pucch_format1b:
  {
2159 2160 2161 2162 2163 2164 2165 2166 2167
    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;
    
Raymond Knopp's avatar
Raymond Knopp committed
2168
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
2169 2170 2171 2172
    tx_amp = get_tx_amp(Po_PUCCH,
			ue->tx_power_max_dBm,
			ue->frame_parms.N_RB_UL,
			1);
Raymond Knopp's avatar
Raymond Knopp committed
2173
#else
2174
    tx_amp = AMP;
2175
#endif
2176

2177 2178 2179
    T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
    
2180
      if(format == pucch_format1)
2181 2182 2183 2184 2185 2186 2187 2188 2189
	{
          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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
		frame_tx%1024, subframe_tx,
		frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
		isShortenPucch,
		ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
		Po_PUCCH);
2190 2191 2192 2193
      }
      else
      {
          if (SR_payload>0) {
2194
              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",
2195
                      Mod_id,
2196
                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2197 2198 2199 2200 2201 2202 2203 2204 2205 2206
                      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 {
2207
              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",
2208
                      Mod_id,
2209
                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219
                      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);
          }
      }
2220

2221 2222

LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2223 2224
      if(pucch_payload[0])
      {
Cedric Roux's avatar
Cedric Roux committed
2225
          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
2226
                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
2227 2228 2229
      }
      else
      {
Cedric Roux's avatar
Cedric Roux committed
2230
          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
2231
                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
2232
      }
2233
LOG_DEBUG_END
2234

2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245
      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);
      
2246 2247
  }
  break;
2248

Raymond Knopp's avatar
Raymond Knopp committed
2249

2250 2251
  case pucch_format2:
  {
Raymond Knopp's avatar
Raymond Knopp committed
2252
      if (ue->mac_enabled == 1) {
2253
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
2254 2255
      }
      else {
2256
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
2257 2258 2259
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
2260

Raymond Knopp's avatar
Raymond Knopp committed
2261 2262
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
      tx_amp =  get_tx_amp(Po_PUCCH,
2263 2264 2265
              ue->tx_power_max_dBm,
              ue->frame_parms.N_RB_UL,
              1);
Raymond Knopp's avatar
Raymond Knopp committed
2266 2267 2268
#else
      tx_amp = AMP;
#endif
Cedric Roux's avatar
Cedric Roux committed
2269
      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
2270
              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
2271
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2272
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n",
2273
              Mod_id,
2274
              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2275 2276 2277 2278
              frame_tx%1024, subframe_tx,
              Po_PUCCH,
              isShortenPucch,
              tx_amp);
2279
LOG_DEBUG_END
Raymond Knopp's avatar
Raymond Knopp committed
2280
      generate_pucch2x(ue->common_vars.txdataF,
2281 2282 2283 2284 2285 2286 2287 2288 2289 2290
              &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,
2291
              ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti);
2292 2293 2294 2295
  }
  break;

  case pucch_format2a:
gabrielC's avatar
gabrielC committed
2296
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
2297
              Mod_id,
2298
              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2299 2300 2301
              frame_tx%1024, subframe_tx);
      break;
  case pucch_format2b:
gabrielC's avatar
gabrielC committed
2302
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
2303
              Mod_id,
2304
              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2305 2306 2307 2308
              frame_tx%1024, subframe_tx);
      break;
  default:
      break;
Raymond Knopp's avatar
Raymond Knopp committed
2309
  }
2310 2311 2312

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);

2313
}
2314

2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335
void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) {

  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  SLSS_t *slss;
  SLDCH_t *sldch;
  SLSCH_t *slsch;

  LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);

  // check for SLBCH/SLSS
  if ((slss = ue_get_slss(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slss(ue,slss,frame_tx,subframe_tx);

  // check for SLDCH
  if ((sldch = ue_get_sldch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_sldch(ue,sldch,frame_tx,subframe_tx);

  // check for SLSCH
  if ((slsch = ue_get_slsch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slsch(ue,slsch,frame_tx,subframe_tx);

}

2336
void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
2337

2338

2339
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2340
  //int32_t ulsch_start=0;
2341 2342 2343
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  unsigned int aa;
2344
  uint8_t isSubframeSRS;
2345

2346 2347
  uint8_t next1_thread_id = ue->current_thread_id[proc->subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
2348

2349
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
2350

2351
  LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
2352

hbilel's avatar
hbilel committed
2353
  T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx));
2354

2355

2356
  ue->generate_ul_signal[eNB_id] = 0;
2357
LOG_DEBUG_BEGIN(UE_TIMING)
2358
  start_meas(&ue->phy_proc_tx);
2359
LOG_DEBUG_END
2360

2361
  ue->tx_power_dBm[subframe_tx]=-127;
2362

2363
      
2364 2365 2366 2367
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
    memset(&ue->common_vars.txdataF[aa][subframe_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
	   0,
	   frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
2368
  }
2369
  
2370 2371 2372 2373 2374
  if (subframe_select(&ue->frame_parms,proc->subframe_tx) == SF_UL ||
      ue->frame_parms.frame_type == FDD) {    
    if (ue->UE_mode[eNB_id] != PRACH ) {
      // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding
      isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx);
2375
      
2376 2377 2378 2379 2380 2381 2382 2383 2384
      ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS);
      
      ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
      
      LOG_D(PHY,"ULPOWERS After ulsch_uespec_procedures : ue->tx_power_dBm[%d]=%d, NPRB %d\n",
	    subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_total_RE[subframe_tx]);
    }
    
    if (ue->UE_mode[eNB_id] == PUSCH) {
hbilel's avatar
hbilel committed
2385 2386 2387 2388
      // check if we need to use PUCCH 1a/1b
      ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
      // check if we need to use SRS
      ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
2389
    } // UE_mode==PUSCH
2390

2391
  }
2392
  	
2393

2394 2395
  LOG_D(PHY,"doing ulsch_common_procedures (%d.%d): generate_ul_signal %d\n",frame_tx,subframe_tx,
	ue->generate_ul_signal[eNB_id]);	
2396 2397
  ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
        
2398 2399
  if ((ue->UE_mode[eNB_id] == PRACH) && 
      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
2400

2401
    // check if we have PRACH opportunity
2402

2403
    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
2404

2405
      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
2406
    }
2407 2408 2409 2410
  } // mode is PRACH
  else {
    ue->generate_prach=0;
  }
2411

2412
  // reset DL ACK/NACK status
hbilel's avatar
hbilel committed
2413
  uint8_t N_bundled = 0;
2414
  if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0] != NULL)
hbilel's avatar
hbilel committed
2415
  {
2416
    reset_ack(&ue->frame_parms,
2417
               ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
2418
               subframe_tx,
hbilel's avatar
hbilel committed
2419 2420 2421 2422
               proc->subframe_rx,
               ue->ulsch[eNB_id]->o_ACK,
               &N_bundled,
               0);
hbilel's avatar
hbilel committed
2423
    reset_ack(&ue->frame_parms,
2424
               ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack,
2425
               subframe_tx,
hbilel's avatar
hbilel committed
2426 2427 2428 2429
               proc->subframe_rx,
               ue->ulsch[eNB_id]->o_ACK,
               &N_bundled,
               0);
hbilel's avatar
hbilel committed
2430
    reset_ack(&ue->frame_parms,
2431
               ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack,
hbilel's avatar
hbilel committed
2432
               subframe_tx,
hbilel's avatar
hbilel committed
2433 2434 2435 2436
               proc->subframe_rx,
               ue->ulsch[eNB_id]->o_ACK,
               &N_bundled,
               0);
hbilel's avatar
hbilel committed
2437
  }
2438

2439
  if (ue->dlsch_SI[eNB_id] != NULL)
2440
    reset_ack(&ue->frame_parms,
2441 2442
             ue->dlsch_SI[eNB_id]->harq_ack,
             subframe_tx,
hbilel's avatar
hbilel committed
2443 2444 2445 2446
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &N_bundled,
             0);
2447

2448

2449 2450
  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);

2451
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
2452
LOG_DEBUG_BEGIN(UE_TIMING)
2453
  stop_meas(&ue->phy_proc_tx);
2454
LOG_DEBUG_END
2455 2456
}

2457
void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag)
2458
{
2459
  int aa;//i,aa;
2460
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2461

2462
  
2463
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
2464
#if defined(EXMIMO) //this is the EXPRESS MIMO case
2465 2466 2467 2468 2469
    int i;
    // set the whole tx buffer to RX
    for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
      ue->common_vars.txdata[aa][i] = 0x00010001;
    
2470
#else //this is the normal case
2471 2472
    //    memset(&ue->common_vars.txdata[aa][0],0,
    //	   (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
2473
#endif //else EXMIMO
2474
    
2475
  }
2476
  
2477 2478
}

2479 2480 2481
void ue_measurement_procedures(
    uint16_t l,    // symbol index of each slot [0..6]
    PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,
2482
    uint16_t slot, // slot index of each radio frame [0..19]
2483
    uint8_t abstraction_flag,runmode_t mode)
2484
{
2485

hbilel's avatar
hbilel committed
2486
  //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp);
hbilel's avatar
hbilel committed
2487

2488
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
Raymond Knopp's avatar
 
Raymond Knopp committed
2489

2490
  int subframe_rx = proc->subframe_rx;
2491

2492
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
2493 2494

  if (l==0) {
2495
    // UE measurements on symbol 0
2496

2497
    LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
2498
      LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
2499

2500
      lte_ue_measurements(ue,
2501 2502 2503 2504 2505 2506
			  (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
			  (subframe_rx == 1) ? 1 : 0,
			  0,
			  0,
			  subframe_rx);
      
2507

2508
      if(slot == 0)
Cedric Roux's avatar
Cedric Roux committed
2509
	T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
2510 2511 2512 2513 2514 2515 2516
	  T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
	  T_INT((int)ue->measurements.rx_rssi_dBm[0]),
	  T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
	  T_INT((int)ue->measurements.rx_power_avg_dB[0]),
	  T_INT((int)ue->measurements.n0_power_avg_dB),
	  T_INT((int)ue->measurements.wideband_cqi_avg[0]),
	  T_INT((int)ue->common_vars.freq_offset));
2517 2518
  }

2519
  if (l==(6-ue->frame_parms.Ncp)) {
2520

2521
    // make sure we have signal from PSS/SSS for N0 measurement
2522
         // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
2523

2524
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
2525
    ue_rrc_measurements(ue,
2526 2527
      slot,
      abstraction_flag);
2528
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
2529

2530
  }
2531

2532 2533
  // accumulate and filter timing offset estimation every subframe (instead of every frame)
  if (( (slot%2) == 0) && (l==(4-frame_parms->Ncp))) {
2534

2535
    // AGC
Raymond Knopp's avatar
 
Raymond Knopp committed
2536

2537
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2538

2539
#ifndef OAI_USRP
kaltenbe's avatar
kaltenbe committed
2540 2541
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
2542
    phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0);
kaltenbe's avatar
kaltenbe committed
2543 2544
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2545
#endif
2546

2547
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
2548

2549
    eNB_id = 0;
2550

2551
    
2552 2553 2554 2555 2556 2557 2558 2559
    if (ue->no_timing_correction==0)
      lte_adjust_synch(&ue->frame_parms,
		       ue,
		       eNB_id,
		       subframe_rx,
		       0,
		       16384);
 
2560
  }
2561

2562
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
2563 2564 2565 2566
}



2567
void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag)
2568
{
2569 2570 2571

  //  int i;
  int pbch_tx_ant=0;
2572 2573 2574 2575
  uint8_t pbch_phase;
  uint16_t frame_tx;
  static uint8_t first_run = 1;
  uint8_t pbch_trials = 0;
2576

2577
  DevAssert(ue);
2578 2579 2580

  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2581

2582
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
2583

Raymond Knopp's avatar
 
Raymond Knopp committed
2584
  pbch_phase=(frame_rx%4);
2585

2586 2587
  if (pbch_phase>=4)
    pbch_phase=0;
2588 2589 2590

  for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
    //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
2591
    //LOG_I(PHY,"[UE  %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
2592

2593 2594 2595 2596 2597 2598 2599 2600
    pbch_tx_ant = rx_pbch(&ue->common_vars,
			  ue->pbch_vars[eNB_id],
			  &ue->frame_parms,
			  eNB_id,
			  ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI,
			  ue->high_speed_flag,
			  pbch_phase);
    
2601 2602 2603
    if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {
      break;
    }
2604

2605
    pbch_phase++;
2606

2607 2608 2609 2610 2611 2612 2613 2614
    if (pbch_phase>=4)
      pbch_phase=0;
  }



  if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {

2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625
    if (opt_enabled) {
      static uint8_t dummy[3];
      dummy[0] = ue->pbch_vars[eNB_id]->decoded_output[2];
      dummy[1] = ue->pbch_vars[eNB_id]->decoded_output[1];
      dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0];
      trace_pdu(1, dummy, 3, ue->Mod_id, 0, 0,
          frame_rx, subframe_rx, 0, 0);
      LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n",
          ue->Mod_id, subframe_rx);
    }

2626
    if (pbch_tx_ant>2) {
2627
      LOG_W(PHY,"[openair][SCHED][SYNCH] PBCH decoding: pbch_tx_ant>2 not supported\n");
2628
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2629 2630 2631 2632
      return;
    }


2633 2634 2635
    ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0;
    frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8);
    frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc));
2636 2637
    frame_tx += pbch_phase;

2638
    if (ue->mac_enabled==1) {
2639

2640 2641
      dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id,
			  ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2642
    }
2643

2644 2645 2646
    // if this is the first PBCH after initial synchronization, make L1 state = PRACH
    if (ue->UE_mode[eNB_id]==NOT_SYNCHED) ue->UE_mode[eNB_id] = PRACH;

2647 2648
    if (first_run) {
      first_run = 0;
2649 2650 2651

      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
      proc->frame_tx = proc->frame_rx;
2652

2653 2654 2655 2656
      for(int th_id=0; th_id<RX_NB_TH; th_id++)
      {
        ue->proc.proc_rxtx[th_id].frame_rx = proc->frame_rx;
        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx;
2657 2658 2659 2660 2661 2662 2663 2664 2665 2666

        printf("[UE %d] frame %d, subframe %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n",
 	    ue->Mod_id,
 	    ue->proc.proc_rxtx[th_id].frame_rx,
 	    subframe_rx,
 	    pbch_tx_ant,
 	    frame_tx,
 	    pbch_phase,
 	    ue->rx_offset,
 	    proc->frame_rx);
2667
      }
2668

2669

2670
      frame_rx = proc->frame_rx;
2671

2672
    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
2673
      //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
Cedric Roux's avatar
Cedric Roux committed
2674
      LOG_D(PHY,"[UE %d] frame %d, subframe %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%%1024=%d, phase %d).\n",
2675 2676 2677 2678 2679 2680 2681
      ue->Mod_id,
      proc->frame_rx,
      subframe_rx,
      pbch_tx_ant,
      frame_tx,
      frame_rx & 0x03FF,
      pbch_phase);
2682 2683 2684 2685 2686


      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
      proc->frame_tx = proc->frame_rx;
      frame_rx = proc->frame_rx;
2687 2688 2689 2690 2691 2692
      
      for(int th_id=0; th_id<RX_NB_TH; th_id++)
      {
        ue->proc.proc_rxtx[th_id].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_rx;
      }
2693

2694
    }
2695

2696
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2697

2698
    LOG_UI(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
2699 2700 2701
	  ue->Mod_id,
	  frame_rx,
	  subframe_rx,
2702
	  ue->frame_parms.nb_antenna_ports_eNB,
2703 2704 2705 2706 2707
	  pbch_tx_ant,
	  frame_tx,
	  ue->frame_parms.N_RB_DL,
	  ue->frame_parms.phich_config_common.phich_duration,
	  ue->frame_parms.phich_config_common.phich_resource);
2708
LOG_DEBUG_END
2709

2710
  } else { 
2711

2712
    /*
2713
    LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
2714
    ue->Mod_id,frame_rx, subframe_rx);
2715

2716 2717 2718
    LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);


bruno mongazon's avatar
bruno mongazon committed
2719
    LOG_M("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1);
2720

bruno mongazon's avatar
bruno mongazon committed
2721 2722
    LOG_M("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);
    LOG_M("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);
2723

bruno mongazon's avatar
bruno mongazon committed
2724 2725 2726 2727
    LOG_M("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
    LOG_M("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1);
    LOG_M("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1);
    LOG_M("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4);
2728 2729
    exit(-1);
    */
2730

2731 2732
    ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
    ue->pbch_vars[eNB_id]->pdu_errors++;
2733

2734 2735 2736
    if (ue->mac_enabled == 1) rrc_out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id);
    else AssertFatal(ue->pbch_vars[eNB_id]->pdu_errors_conseq<100,
		     "More that 100 consecutive PBCH errors! Exiting!\n");
2737
  }
2738
  
2739

Raymond Knopp's avatar
 
Raymond Knopp committed
2740
  if (frame_rx % 100 == 0) {
2741 2742
    ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last;
    ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors;
2743
  }
2744

2745 2746
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
  LOG_UI(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
2747 2748 2749
  ue->Mod_id,frame_rx, subframe_rx,
  ue->pbch_vars[eNB_id]->pdu_errors,
  ue->pbch_vars[eNB_id]->pdu_errors_conseq);
2750
LOG_DEBUG_END
2751
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2752 2753
}

2754 2755


2756
int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag)
2757
{
2758 2759

  unsigned int dci_cnt=0, i;
2760

2761 2762
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2763
  DCI_ALLOC_t dci_alloc_rx[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
2764

2765 2766
  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
2767

2768
  LOG_D(PHY,"DCI Decoding procedure in %d.%d\n",frame_rx,subframe_rx);
2769
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
2770
LOG_DEBUG_BEGIN(UE_TIMING)
2771
  start_meas(&ue->dlsch_rx_pdcch_stats);
2772
LOG_DEBUG_END
2773

2774 2775 2776 2777 2778
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
  rx_pdcch(ue,
	   proc->frame_rx,
	   subframe_rx,
	   eNB_id,
2779
	   ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI,
2780
	   ue->high_speed_flag);
2781 2782 2783
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
2784 2785
  
  
2786 2787 2788 2789 2790
  /*printf("Decode SIB frame param aggregation + DCI %d %d, num_pdcch_symbols %d\n",
	 ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel,
	 ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat,
	 ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
  */
2791 2792
  //agregation level == FF means no configuration on
  if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB)
2793
    {
2794 2795 2796 2797 2798 2799
      // search all possible dcis
      dci_cnt = dci_decoding_procedure(ue,
				       dci_alloc_rx,
				       (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
				       // later when we need paging or RA during connection, update this ...
				       eNB_id,subframe_rx);
2800
    }
2801
  else
2802
    {
2803 2804 2805 2806 2807 2808 2809 2810
      // search only preconfigured dcis
      // search C RNTI dci
      dci_cnt = dci_CRNTI_decoding_procedure(ue,
					     dci_alloc_rx,
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat,
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel,
					     eNB_id,
					     subframe_rx);
2811
    }
2812
  
2813 2814 2815 2816 2817 2818 2819 2820
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
  //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d PHICH RX\n",ue->Mod_id,frame_rx,subframe_rx);
  
  if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
    rx_phich(ue,proc,
	     subframe_rx,eNB_id);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
2821
  }
2822
  
2823 2824 2825
  uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx];
  uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[subframe_rx];
  uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[subframe_rx];
2826
  memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
2827
  memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
2828

2829
  LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[subframe_rx], next1_thread_id, next2_thread_id);
2830

2831
  LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n",
hbilel's avatar
hbilel committed
2832 2833 2834
       ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],
       dci_cnt,
       dci_alloc_rx[0].rnti,
2835
       ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
hbilel's avatar
hbilel committed
2836
       dci_alloc_rx[0].format );
2837

2838
  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dci_received += dci_cnt;
2839

2840 2841 2842
  for (i=0; i<dci_cnt; i++) {


2843

2844
    if ((ue->UE_mode[eNB_id]>PRACH) &&
2845
	(dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
2846 2847
	(dci_alloc_rx[i].format != format0)) {
      
2848
      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
2849
	    ue->Mod_id,dci_alloc_rx[i].rnti,
2850
	    frame_rx%1024,subframe_rx,
2851
	    dci_alloc_rx[i].format,
2852 2853
	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx],
2854
	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
2855
      
2856
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2857
      
2858
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2859 2860
	  (generate_ue_dlsch_params_from_dci(frame_rx,
					     subframe_rx,
2861
					     (void *)&dci_alloc_rx[i].dci_pdu,
2862
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
2863
					     dci_alloc_rx[i].format,
2864 2865 2866
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
					     ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
					     ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id],
2867 2868
					     &ue->frame_parms,
					     ue->pdsch_config_dedicated,
2869 2870
					     SI_RNTI,
					     0,
2871
					     P_RNTI,
2872
					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
2873
					     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti: 0)==0)) {
2874 2875 2876 2877 2878 2879 2880 2881
	
	// 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 == format2B))
hbilel's avatar
hbilel committed
2882
          {
2883 2884
            //ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
            int32_t delta_pucch = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
2885
            for(int th_id=0; th_id<RX_NB_TH; th_id++)
2886
	      {
2887
                ue->dlsch[th_id][eNB_id][0]->g_pucch += delta_pucch;
2888
	      }
2889
            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid,
2890 2891 2892 2893 2894
		  delta_pucch,
		  ue->dlsch[0][eNB_id][0]->g_pucch,
		  ue->dlsch[1][eNB_id][0]->g_pucch
		  //ue->dlsch[2][eNB_id][0]->g_pucch
		  );
hbilel's avatar
hbilel committed
2895
          }
2896
	
2897
	ue->dlsch_received[eNB_id]++;
2898
	
2899
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2900 2901
	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]);
2902
	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active);
2903
LOG_DEBUG_END
2904
	
2905 2906
	// we received a CRNTI, so we're in PUSCH
	if (ue->UE_mode[eNB_id] != PUSCH) {
2907
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2908
	  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);
2909
LOG_DEBUG_END
2910
	  
2911 2912
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	  ue->UE_mode[eNB_id] = PUSCH;
2913 2914
	}
      } else {
2915 2916
	  LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
	  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2917
	}
2918
    }
2919 2920 2921
      
      else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
	       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2922

2923

2924
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2925
	LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
2926
LOG_DEBUG_END
2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945
	
	if (generate_ue_dlsch_params_from_dci(frame_rx,
					      subframe_rx,
					      (void *)&dci_alloc_rx[i].dci_pdu,
					      SI_RNTI,
					      dci_alloc_rx[i].format,
					      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
					      ue->pdsch_vars_SI[eNB_id],
					      &ue->dlsch_SI[eNB_id],
					      &ue->frame_parms,
					      ue->pdsch_config_dedicated,
					      SI_RNTI,
					      0,
					      P_RNTI,
					      ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
					      0)==0) {
	  
	  ue->dlsch_SI_received[eNB_id]++;
	  
2946
	  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
2947 2948 2949
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	
	}
2950
      }
2951

2952
    else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
2953
       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2954

2955
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2956
      LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
2957
LOG_DEBUG_END
2958 2959 2960 2961 2962


      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
					    (void *)&dci_alloc_rx[i].dci_pdu,
2963
					    P_RNTI,
2964
					    dci_alloc_rx[i].format,
2965
					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
2966
					    ue->pdsch_vars_p[eNB_id],
2967 2968 2969 2970 2971
					    &ue->dlsch_SI[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    0,
2972
					    P_RNTI,
2973 2974
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
2975 2976 2977 2978

	ue->dlsch_p_received[eNB_id]++;
	LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH P_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2979
	
2980 2981 2982
      }
    }

2983
    else if ((ue->prach_resources[eNB_id]) &&
2984 2985
       (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
       (dci_alloc_rx[i].format == format1A)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2986

2987
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
2988
      LOG_D(PHY,"[UE  %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i);
2989
LOG_DEBUG_END
2990 2991


2992 2993
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2994 2995 2996
					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
					    ue->prach_resources[eNB_id]->ra_RNTI,
					    format1A,
2997
					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
2998
					    ue->pdsch_vars_ra[eNB_id],
2999 3000 3001 3002 3003
					    &ue->dlsch_ra[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    ue->prach_resources[eNB_id]->ra_RNTI,
3004
					    P_RNTI,
3005 3006
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
3007
	
3008
  ue->dlsch_ra_received[eNB_id]++;
3009

3010
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3011 3012
  LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
        ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
3013
LOG_DEBUG_END
3014
      }
3015
    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
3016
	       (dci_alloc_rx[i].format == format0)) {
3017

3018
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3019
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
3020
      ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
3021
LOG_DEBUG_END
3022

3023 3024
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
3025
      
3026
      if ((ue->UE_mode[eNB_id] > PRACH) &&
3027
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
3028
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3029 3030
					     subframe_rx,
					     format0,
3031
					     ue,
3032
					     proc,
3033 3034 3035 3036 3037 3038
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
3039 3040 3041 3042 3043
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
   
    LOG_USEDINLOG_VAR(int8_t,harq_pid) = subframe2harq_pid(&ue->frame_parms,
                              pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx),
                              pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx));
Cedric Roux's avatar
Cedric Roux committed
3044
    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
3045 3046
      T_INT(dci_alloc_rx[i].rnti), 
      T_INT(harq_pid),
3047 3048 3049 3050 3051
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS));
3052

3053
      LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
3054
LOG_DEBUG_END
3055

3056
      }
3057
    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
3058
         (dci_alloc_rx[i].format == format0)) {
3059
      // UE could belong to more than one CBA group
3060
      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
3061
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3062
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
3063
      ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
3064
      /*
3065 3066
  if (((frame_rx%100) == 0) || (frame_rx < 20))
  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
3067
      */
3068
LOG_DEBUG_END
3069

3070 3071
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
3072

3073
      if ((ue->UE_mode[eNB_id] > PRACH) &&
3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085
    (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
               ue->ulsch[eNB_id]->cba_rnti[0],
               subframe_rx,
               format0,
               ue,
               proc,
               SI_RNTI,
               0,
               P_RNTI,
               CBA_RNTI,
               eNB_id,
               0)==0)) {
3086

3087
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3088
  LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
3089
LOG_DEBUG_END
3090
  ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
3091 3092 3093
      }
    }

3094
    else {
3095
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3096
      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,
3097
	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3098 3099
	    ue->ulsch[eNB_id]->cba_rnti[0],
	    dci_alloc_rx[i].format);
3100

3101
      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
3102
LOG_DEBUG_END
3103
    }
3104

3105
  }
3106
LOG_DEBUG_BEGIN(UE_TIMING)
3107
  stop_meas(&ue->dlsch_rx_pdcch_stats);
3108
LOG_DEBUG_END
3109
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
3110 3111 3112
  return(0);
}

3113

3114
void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
3115

3116
  int subframe_rx = proc->subframe_rx;
3117
  int frame_rx = proc->frame_rx;
3118
  int pmch_mcs=-1;
3119
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3120
  int CC_id = ue->CC_id;
Cedric Roux's avatar
Cedric Roux committed
3121
#endif
3122 3123 3124 3125
  uint8_t sync_area=255;
  uint8_t mcch_active;
  int l;
  int ret=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3126

3127
  if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
3128
    // LOG_D(PHY,"ue calling pmch subframe ..\n ");
3129

3130
    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
3131
    ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
3132
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3133

3134 3135 3136 3137 3138 3139 3140
    pmch_mcs = ue_query_mch(ue->Mod_id,
			    CC_id,
			    frame_rx,
			    subframe_rx,
			    eNB_id,
			    &sync_area,
			    &mcch_active);
3141 3142 3143
    
#else
    pmch_mcs=-1;
3144
#endif
3145

3146 3147 3148
    if (pmch_mcs>=0) {
      LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs);
      fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
3149

3150
      
3151
      for (l=2; l<12; l++) {
3152
	
3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163
	slot_fep_mbsfn(ue,
		       l,
		       subframe_rx,
		       0,0);//ue->rx_offset,0);
      }
      
      for (l=2; l<12; l++) {
	rx_pmch(ue,
		0,
		subframe_rx,
		l);
3164 3165
      }
      
3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189
      
      ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
						     ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
						     ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
						     ue->dlsch_MCH[0]->harq_processes[0]->Qm,
						     1,
						     2,
						     frame_rx,
						     subframe_rx,
						     0);
      
      dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
			 ue->dlsch_MCH[0]->harq_processes[0]->G,
			 ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1);
      
      ret = dlsch_decoding(ue,
			   ue->pdsch_vars_MCH[0]->llr[0],
			   &ue->frame_parms,
			   ue->dlsch_MCH[0],
			   ue->dlsch_MCH[0]->harq_processes[0],
			   frame_rx,
			   subframe_rx,
			   0,
			   0,1);
3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201
      if (mcch_active == 1)
	ue->dlsch_mcch_trials[sync_area][0]++;
      else
	ue->dlsch_mtch_trials[sync_area][0]++;
      
      if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) {
	if (mcch_active == 1)
	  ue->dlsch_mcch_errors[sync_area][0]++;
	else
	  ue->dlsch_mtch_errors[sync_area][0]++;
	
	LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
Cedric Roux's avatar
Cedric Roux committed
3202 3203
	      ue->Mod_id,
              frame_rx,subframe_rx,
3204 3205 3206 3207 3208 3209
	      ue->dlsch_mcch_errors[sync_area][0],
	      ue->dlsch_mtch_errors[sync_area][0],
	      ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
	      ue->dlsch_MCH[0]->max_turbo_iterations,
	      ue->dlsch_MCH[0]->harq_processes[0]->G);
	dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
3210
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3211 3212 3213
	
	for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
	  LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
3214
	}
3215 3216
	
	LOG_T(PHY,"\n");
3217
LOG_DEBUG_END
3218
	
3219
	
3220 3221
	//	if (subframe_rx==9)
	//  mac_xface->macphy_exit("Why are we exiting here?");
3222
      } else { // decoding successful
3223
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3224 3225
	
	if (mcch_active == 1) {
3226 3227 3228 3229 3230 3231 3232
	  ue_send_mch_sdu(ue->Mod_id,
			  CC_id,
			  frame_rx,
			  ue->dlsch_MCH[0]->harq_processes[0]->b,
			  ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
			  eNB_id,// not relevant in eMBMS context
			  sync_area);
3233 3234 3235 3236 3237 3238 3239 3240
	  ue->dlsch_mcch_received[sync_area][0]++;
	  
	  
	  if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
	    ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
	  } else {
	    ue->dlsch_mch_received[0]+=1;
	    ue->dlsch_mch_received_sf[subframe_rx][0]=1;
3241
	  }
3242 3243 3244
	  
	  
	}
3245

3246
#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3247 3248 3249 3250
      } // decoding sucessful
    } // pmch_mcs>=0
  } // is_pmch_subframe=true
}
3251

3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
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));
}

3294
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) {
3295

3296 3297 3298 3299 3300
  int subframe_rx = proc->subframe_rx;
  int m;
  int harq_pid;
  int i_mod,eNB_id_i,dual_stream_UE;
  int first_symbol_flag=0;
3301

3302 3303
  if (dlsch0->active == 0)
    return;
3304

3305
  for (m=s0;m<=s1;m++) {
3306

3307 3308
    if (dlsch0 && (!dlsch1))  {
      harq_pid = dlsch0->current_harq_pid;
hbilel's avatar
hbilel committed
3309
      LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m);
3310

3311 3312 3313 3314 3315 3316 3317
      if ((pdsch==PDSCH) &&
          (ue->transmission_mode[eNB_id] == 5) &&
          (dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
          (ue->use_ia_receiver ==1)) {
        dual_stream_UE = 1;
        eNB_id_i = ue->n_connected_eNB;
        i_mod =  dlsch0->harq_processes[harq_pid]->Qm;
3318

hbilel's avatar
hbilel committed
3319 3320 3321 3322 3323 3324 3325 3326
      }
      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 {
3327 3328 3329
        dual_stream_UE = 0;
        eNB_id_i = eNB_id+1;
        i_mod = 0;
3330
      }
3331

3332 3333 3334
      //TM7 UE specific channel estimation here!!!
      if (ue->transmission_mode[eNB_id]==7) {
        if (ue->frame_parms.Ncp==0) {
Xiwen JIANG's avatar
Xiwen JIANG committed
3335
          if ((m==3) || (m==6) || (m==9) || (m==12))
3336 3337
            //LOG_D(PHY,"[UE %d] dlsch->active in subframe %d => %d, l=%d\n",phy_vars_ue->Mod_id,subframe_rx,phy_vars_ue->dlsch_ue[eNB_id][0]->active, l);
            lte_dl_bf_channel_estimation(ue,eNB_id,0,subframe_rx*2+(m>6?1:0),5,m);
3338
        } else {
3339
          LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
3340
        }
3341
      }
3342

3343
      if ((m==s0) && (m<4))
3344
          first_symbol_flag = 1;
3345
      else
3346
          first_symbol_flag = 0;
3347 3348

LOG_DEBUG_BEGIN(UE_TIMING)
3349 3350 3351
      uint8_t slot = 0;
      if(m >= ue->frame_parms.symbols_per_tti>>1)
        slot = 1;
tct-labo4's avatar
tct-labo4 committed
3352
      start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
3353
LOG_DEBUG_END
3354 3355 3356 3357 3358
      // process DLSCH received in first slot
      rx_pdsch(ue,
	       pdsch,
	       eNB_id,
	       eNB_id_i,
3359
	       proc->frame_rx,
3360 3361 3362 3363 3364 3365
	       subframe_rx,  // subframe,
	       m,
	       first_symbol_flag,
	       dual_stream_UE,
	       i_mod,
	       dlsch0->current_harq_pid);
3366 3367 3368 3369
LOG_DEBUG_BEGIN(UE_TIMING)
      uint8_t slot = 0;
      if(m >= ue->frame_parms.symbols_per_tti>>1)
        slot = 1;
tct-labo4's avatar
tct-labo4 committed
3370
      stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
3371 3372 3373
      LOG_UI(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
LOG_DEBUG_END

3374

3375

3376 3377 3378 3379
      if(first_symbol_flag)
      {
          proc->first_symbol_available = 1;
      }
3380
    } // CRNTI active
3381
  }
3382
}
3383

3384
void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
3385

3386 3387 3388 3389 3390 3391
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
  int timing_advance;
  LTE_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
  int harq_pid = 0;
  uint8_t *rar;
3392 3393
  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
3394

3395
  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
3396 3397 3398 3399 3400
  ue->Mod_id,
  frame_rx,
  subframe_rx, ue->UE_mode[eNB_id]);


3401
  if (ue->mac_enabled == 1) {
3402 3403
    if ((ue->UE_mode[eNB_id] != PUSCH) &&
  (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
3404 3405 3406 3407 3408
      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n",
	    ue->Mod_id,frame_rx,
	    subframe_rx,
	    ue->prach_resources[eNB_id]->ra_PreambleIndex);
      
3409 3410 3411 3412 3413
      timing_advance = ue_process_rar(ue->Mod_id,
				      ue->CC_id,
				      frame_rx,
				      ue->prach_resources[eNB_id]->ra_RNTI,
				      dlsch0->harq_processes[0]->b,
3414
				      &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3415 3416 3417
				      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
      
3418 3419
      ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
      ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
3420

3421 3422
      
      if (timing_advance!=0xffff) {
3423

3424
              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
3425 3426 3427
              ue->Mod_id,
              frame_rx,
              subframe_rx,
3428
              ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3429
              timing_advance);
3430

3431
	      // remember this c-rnti is still a tc-rnti
3432
	      
3433
	      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti_is_temporary = 1;
3434
	      
3435 3436
	      //timing_advance = 0;
	      process_timing_advance_rar(ue,proc,timing_advance);
3437
	      
3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461
	      if (mode!=debug_prach) {
		ue->ulsch_Msg3_active[eNB_id]=1;
		get_Msg3_alloc(&ue->frame_parms,
			       subframe_rx,
			       frame_rx,
			       &ue->ulsch_Msg3_frame[eNB_id],
			       &ue->ulsch_Msg3_subframe[eNB_id]);
		
		LOG_D(PHY,"[UE  %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n",
		      ue->Mod_id,
		      frame_rx,
		      subframe_rx,
		      ue->ulsch_Msg3_frame[eNB_id],
		      ue->ulsch_Msg3_subframe[eNB_id]);
		harq_pid = subframe2harq_pid(&ue->frame_parms,
					     ue->ulsch_Msg3_frame[eNB_id],
					     ue->ulsch_Msg3_subframe[eNB_id]);
		ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
		
		ue->UE_mode[eNB_id] = RA_RESPONSE;
		//      ue->Msg3_timer[eNB_id] = 10;
		ue->ulsch[eNB_id]->power_offset = 6;
		ue->ulsch_no_allocation_counter[eNB_id] = 0;
	      }
3462 3463 3464 3465
      } else { // PRACH preamble doesn't match RAR
	LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
	      ue->Mod_id,
	      ue->prach_resources[eNB_id]->ra_PreambleIndex);
3466
      }
3467 3468 3469 3470 3471 3472 3473 3474 3475
    } // mode != PUSCH
  }
  else {
    rar = dlsch0->harq_processes[0]->b+1;
    timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
    process_timing_advance_rar(ue,proc,timing_advance);
  }
  
}
3476

3477 3478 3479 3480 3481 3482 3483 3484 3485
void ue_dlsch_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 *dlsch_errors,
       runmode_t mode,
       int abstraction_flag) {
3486

3487 3488 3489
  int harq_pid;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
hbilel's avatar
hbilel committed
3490
  int ret=0, ret1=0;
3491 3492
  int CC_id = ue->CC_id;
  LTE_UE_PDSCH *pdsch_vars;
hbilel's avatar
hbilel committed
3493 3494 3495 3496 3497
  uint8_t is_cw0_active = 0;
  uint8_t is_cw1_active = 0;

  if (dlsch0==NULL)
      AssertFatal(0,"dlsch0 should be defined at this level \n");
3498

hbilel's avatar
hbilel committed
3499 3500 3501 3502 3503 3504 3505 3506
  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);
3507

hbilel's avatar
hbilel committed
3508 3509 3510 3511 3512 3513 3514 3515 3516 3517
  if(is_cw0_active && is_cw1_active)
  {
      dlsch0->Kmimo = 2;
      dlsch1->Kmimo = 2;
  }
  else
  {
      dlsch0->Kmimo = 1;
  }
  if (1) {
3518 3519 3520 3521 3522 3523 3524
    switch (pdsch) {
    case SI_PDSCH:
      pdsch_vars = ue->pdsch_vars_SI[eNB_id];
      break;
    case RA_PDSCH:
      pdsch_vars = ue->pdsch_vars_ra[eNB_id];
      break;
3525 3526 3527
    case P_PDSCH:
      pdsch_vars = ue->pdsch_vars_p[eNB_id];
      break;
3528
    case PDSCH:
3529
      pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id];
3530 3531 3532 3533 3534 3535 3536
      break;
    case PMCH:
    case PDSCH1:
      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
      pdsch_vars = NULL;
      return;
      break;
3537 3538 3539 3540 3541
    default:
      pdsch_vars = NULL;
      return;
      break;

3542 3543 3544
    }
    if (frame_rx < *dlsch_errors)
      *dlsch_errors=0;
3545

3546
    if (pdsch==RA_PDSCH) {
3547
      
3548
      if (ue->prach_resources[eNB_id]!=NULL)
3549
	dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
3550
      else {
3551 3552
	LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
	AssertFatal(1==0,"prach_resources is NULL");
3553 3554
      }
    }
3555
    
3556
      
hbilel's avatar
hbilel committed
3557
      // start turbo decode for CW 0
3558 3559 3560 3561 3562
      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,
						  dlsch0->harq_processes[harq_pid]->Qm,
						  dlsch0->harq_processes[harq_pid]->Nl,
3563
						  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
3564 3565 3566
						  frame_rx,
						  subframe_rx,
						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
3567
LOG_DEBUG_BEGIN(UE_TIMING)
3568
      start_meas(&ue->dlsch_unscrambling_stats);
3569
LOG_DEBUG_END
3570 3571
      dlsch_unscrambling(&ue->frame_parms,
			 0,
3572
			 dlsch0,
3573 3574 3575 3576
			 dlsch0->harq_processes[harq_pid]->G,
			 pdsch_vars->llr[0],
			 0,
			 subframe_rx<<1);
3577
LOG_DEBUG_BEGIN(UE_TIMING)
3578
      stop_meas(&ue->dlsch_unscrambling_stats);
3579
LOG_DEBUG_END
3580
      
bruno mongazon's avatar
bruno mongazon committed
3581 3582
      LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
      LOG_D(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);
3583
      LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, (unsigned int)((intptr_t)dlsch0->harq_processes[harq_pid]->rb_alloc_even));
bruno mongazon's avatar
bruno mongazon committed
3584 3585 3586 3587 3588
      LOG_D(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_D(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_D(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_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
      LOG_D(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[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
3589
      
3590
LOG_DEBUG_BEGIN(UE_TIMING)
3591
      start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
3592
LOG_DEBUG_END
3593 3594 3595 3596 3597
      ret = dlsch_decoding(ue,
			   pdsch_vars->llr[0],
			   &ue->frame_parms,
			   dlsch0,
			   dlsch0->harq_processes[harq_pid],
3598
			   frame_rx,
3599 3600 3601
			   subframe_rx,
			   harq_pid,
			   pdsch==PDSCH?1:0,
3602
			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
3603
      
3604
LOG_DEBUG_BEGIN(UE_TIMING)
3605
      stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
3606
      LOG_UI(PHY, " --> Unscrambling for CW0 %5.3f\n",
3607
	    (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
3608
      LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
3609 3610
	    frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
      
3611
LOG_DEBUG_END
hbilel's avatar
hbilel committed
3612
      if(is_cw1_active)
3613
	{
hbilel's avatar
hbilel committed
3614 3615
          // start turbo decode for CW 1
          dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
3616 3617 3618 3619 3620 3621 3622 3623
						      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[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
						      frame_rx,
						      subframe_rx,
						      ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
3624
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
3625
          start_meas(&ue->dlsch_unscrambling_stats);
3626
LOG_DEBUG_END
hbilel's avatar
hbilel committed
3627
          dlsch_unscrambling(&ue->frame_parms,
3628 3629 3630 3631 3632 3633
			     0,
			     dlsch1,
			     dlsch1->harq_processes[harq_pid]->G,
			     pdsch_vars->llr[1],
			     1,
			     subframe_rx<<1);
3634
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
3635
          stop_meas(&ue->dlsch_unscrambling_stats);
3636
LOG_DEBUG_END
3637
	  
bruno mongazon's avatar
bruno mongazon committed
3638
          LOG_D(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);
3639
          LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, (uint16_t)((intptr_t)dlsch1->harq_processes[harq_pid]->rb_alloc_even));
bruno mongazon's avatar
bruno mongazon committed
3640 3641 3642 3643 3644
          LOG_D(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_D(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_D(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_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo);
          LOG_D(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[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
3645
	  
3646
LOG_DEBUG_BEGIN(UE_TIMING)
3647
          start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
3648
LOG_DEBUG_END
3649
	  
hbilel's avatar
hbilel committed
3650
          ret1 = dlsch_decoding(ue,
3651 3652 3653 3654 3655 3656 3657 3658 3659 3660
				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);
	  
3661
LOG_DEBUG_BEGIN(UE_TIMING)
3662
          stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
3663
          LOG_UI(PHY, " --> Unscrambling for CW1 %5.3f\n",
3664
		(ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
3665
          LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
3666
		frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
3667 3668
LOG_DEBUG_END

3669
          LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
3670 3671 3672
		frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
	}
      
3673
      LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
3674
    
3675
    
3676

hbilel's avatar
hbilel committed
3677
    // Check CRC for CW 0
3678 3679
    if (ret == (1+dlsch0->max_turbo_iterations)) {
      *dlsch_errors=*dlsch_errors+1;
3680

3681 3682
      if(dlsch0->rnti != 0xffff)
      {
3683

3684 3685 3686 3687 3688 3689 3690
	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);
3691
      }
3692

3693

3694
    } else {
3695 3696
        if(dlsch0->rnti != 0xffff)
        {
3697
      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
3698 3699 3700
            ue->Mod_id,dlsch0->rnti,
            harq_pid,frame_rx,subframe_rx,
            dlsch0->harq_processes[harq_pid]->rvidx,
3701
            dlsch0->harq_processes[harq_pid]->round,
3702 3703
            dlsch0->harq_processes[harq_pid]->mcs,
            dlsch0->harq_processes[harq_pid]->TBS);
3704
        }
3705

3706
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3707 3708
      int j;
      LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
3709

3710
      for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
3711 3712
  LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);

3713
      LOG_T(PHY,"\n");
3714
LOG_DEBUG_END
3715

3716

3717
      if (ue->mac_enabled == 1) {
3718
	
3719 3720
	switch (pdsch) {
	case PDSCH:
3721 3722 3723 3724 3725 3726 3727
	  ue_send_sdu(ue->Mod_id,
		      CC_id,
		      frame_rx,
		      subframe_rx,
		      dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
		      dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
		      eNB_id);
3728 3729
	  break;
	case SI_PDSCH:
3730 3731 3732 3733 3734 3735
	  ue_decode_si(ue->Mod_id,
		       CC_id,
		       frame_rx,
		       eNB_id,
		       ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
		       ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
3736
	  break;
3737
	case P_PDSCH:
3738
		ue_decode_p(ue->Mod_id,
3739 3740 3741 3742 3743
		      CC_id,
		      frame_rx,
		      eNB_id,
		      ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
		      ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
3744
	  break;
3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756
	case RA_PDSCH:
	  process_rar(ue,proc,eNB_id,mode,abstraction_flag);
	  break;
	case PDSCH1:
	  LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
	  AssertFatal(1==0,"exiting");
	  break;
	case PMCH:
	  LOG_E(PHY,"Shouldn't have PMCH here\n");
	  AssertFatal(1==0,"exiting");
	  break;
	}
3757
      }
3758 3759 3760 3761 3762
      ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] +
	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
      ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] +
	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
    }
hbilel's avatar
hbilel committed
3763 3764
    // Check CRC for CW 1
    if(is_cw1_active)
3765
      {
hbilel's avatar
hbilel committed
3766
        if (ret1 == (1+dlsch0->max_turbo_iterations)) {
3767
	  LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n",
3768 3769 3770 3771 3772 3773
		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);
	  
hbilel's avatar
hbilel committed
3774
        } else {
3775
	  LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n",
3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803
		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)
		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;
	    }
	  }
hbilel's avatar
hbilel committed
3804
        }
3805 3806
      }
    
3807
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824
    LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n",
	  ue->Mod_id,
	  dlsch0->rnti,harq_pid,
	  frame_rx,subframe_rx,ret,
	  dlsch0->harq_processes[harq_pid]->mcs,
	  dlsch0->harq_processes[harq_pid]->rvidx,
	  dlsch0->harq_processes[harq_pid]->TBS);
    
    if (frame_rx%100==0) {
      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n",
	    ue->Mod_id,dlsch0->rnti,
	    frame_rx,subframe_rx,
	    ue->dlsch_errors[eNB_id],
	    ue->dlsch_received[eNB_id],
	    ue->dlsch_fer[eNB_id],
	    ue->measurements.wideband_cqi_tot[eNB_id]);
    }
3825
    
3826
LOG_DEBUG_END
3827
    
3828
  }
3829
  
3830
  
3831
}
3832

3833 3834 3835 3836 3837 3838
/*!
 * \brief This is the UE synchronize thread.
 * It performs band scanning and synchonization.
 * \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.
 */
3839
#ifdef UE_SLOT_PARALLELISATION
3840
#define FIFO_PRIORITY   40
3841
void *UE_thread_slot1_dl_processing(void *arg) {
3842

3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902
    static __thread int UE_dl_slot1_processing_retval;
    struct rx_tx_thread_data *rtd = arg;
    UE_rxtx_proc_t *proc = rtd->proc;
    PHY_VARS_UE    *ue   = rtd->UE;

    int frame_rx;
    uint8_t subframe_rx;
    uint8_t pilot0;
    uint8_t pilot1;
    uint8_t slot1;

    uint8_t next_subframe_rx;
    uint8_t next_subframe_slot0;

    proc->instance_cnt_slot1_dl_processing=-1;
    proc->subframe_rx=proc->sub_frame_start;

    char threadname[256];
    sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start);

    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 )
        CPU_SET(threads.slot1_proc_one, &cpuset);
    if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 )
        CPU_SET(threads.slot1_proc_two, &cpuset);
    if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 )
        CPU_SET(threads.slot1_proc_three, &cpuset);

    init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
                threadname);

    while (!oai_exit) {
        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" );
            exit_fun("nothing to add");
        }
        while (proc->instance_cnt_slot1_dl_processing < 0) {
            // most of the time, the thread is waiting here
            pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing );
        }
        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" );
            exit_fun("nothing to add");
        }

        /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++)
        {
        frame_rx    = ue->proc.proc_rxtx[0].frame_rx;
        subframe_rx = ue->proc.proc_rxtx[0].subframe_rx;
        printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
        }*/
        frame_rx    = proc->frame_rx;
        subframe_rx = proc->subframe_rx;
        next_subframe_rx    = (1+subframe_rx)%10;
        next_subframe_slot0 = next_subframe_rx<<1;

        slot1  = (subframe_rx<<1) + 1;
        pilot0 = 0;

3903
        //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
3904 3905 3906 3907 3908 3909 3910 3911

        if (ue->frame_parms.Ncp == 0) {  // normal prefix
            pilot1 = 4;
        } else { // extended prefix
            pilot1 = 3;
        }

        /**** Slot1 FE Processing ****/
3912
LOG_DEBUG_BEGIN(UE_TIMING)
3913
        start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
3914
LOG_DEBUG_END
3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938
        // I- start dl slot1 processing
        // do first symbol of next downlink subframe for channel estimation
        /*
        // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
        {
            front_end_fft(ue,
                    pilot0,
                    next_subframe_slot0,
                    0,
                    0);
        }

        front_end_fft(ue,
                pilot1,
                slot1,
                0,
                0);
         */
        // 1- perform FFT
        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
        {
            //if( (l != pilot0) && (l != pilot1))
            {
3939
LOG_DEBUG_BEGIN(UE_TIMING)
3940
                start_meas(&ue->ofdm_demod_stats);
3941
LOG_DEBUG_END
3942 3943 3944 3945 3946 3947 3948 3949
                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
                //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
                front_end_fft(ue,
                        l,
                        slot1,
                        0,
                        0);
                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
3950
LOG_DEBUG_BEGIN(UE_TIMING)
3951
                stop_meas(&ue->ofdm_demod_stats);
3952
LOG_DEBUG_END
3953 3954
            }
        } // for l=1..l2
3955

3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977
        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
        {
            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
            front_end_fft(ue,
                    pilot0,
                    next_subframe_slot0,
                    0,
                    0);
        }

        // 2- perform Channel Estimation for slot1
        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
        {
            if(l == pilot1)
            {
                //wait until channel estimation for pilot0/slot1 is available
                uint32_t wait = 0;
                while(proc->chan_est_pilot0_slot1_available == 0)
                {
                    usleep(1);
                    wait++;
                }
3978
                //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998
            }
            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
            front_end_chanEst(ue,
                    l,
                    slot1,
                    0);
            ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode);
        }
        //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
        front_end_chanEst(ue,
                pilot0,
                next_subframe_slot0,
                0);

        if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
        {
            ue_pbch_procedures(0,ue,proc,0);
        }

        proc->chan_est_slot1_available = 1;
3999 4000
        //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
        //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
4001 4002 4003 4004

        //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);


4005
LOG_DEBUG_BEGIN(UE_TIMING)
4006
        stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
4007
        LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
4008

4009
LOG_DEBUG_END
4010 4011 4012 4013 4014 4015 4016 4017 4018


    //wait until pdcch is decoded
    uint32_t wait = 0;
    while(proc->dci_slot0_available == 0)
    {
        usleep(1);
        wait++;
    }
4019
    //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,subframe_rx,wait);
4020 4021 4022 4023 4024


    /**** Pdsch Procedure Slot1 ****/
    // start slot1 thread for Pdsch Procedure (slot1)
    // do procedures for C-RNTI
4025
    //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,subframe_rx);
4026 4027


4028
LOG_DEBUG_BEGIN(UE_TIMING)
4029
    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
4030
LOG_DEBUG_END
4031 4032 4033 4034
    // start slave thread for Pdsch Procedure (slot1)
    // do procedures for C-RNTI
    uint8_t eNB_id = 0;
    uint8_t abstraction_flag = 0;
4035
    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049
        //wait until first ofdm symbol is processed
        //wait = 0;
        //while(proc->first_symbol_available == 0)
        //{
        //    usleep(1);
        //    wait++;
        //}
        //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,subframe_rx,wait);

        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                PDSCH,
4050
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
        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);
    }

    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                SI_PDSCH,
                ue->dlsch_SI[eNB_id],
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
    }

    // do procedures for P-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                P_PDSCH,
                ue->dlsch_p[eNB_id],
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
    }
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                RA_PDSCH,
                ue->dlsch_ra[eNB_id],
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
    }

    proc->llr_slot1_available=1;
4098
    //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
4099

4100
LOG_DEBUG_BEGIN(UE_TIMING)
4101
    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
4102 4103
    LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
LOG_DEBUG_END
4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119


        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
            exit_fun("noting to add");
        }
        proc->instance_cnt_slot1_dl_processing--;
        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" );
            exit_fun("noting to add");
        }
    }
    // thread finished
        free(arg);
        return &UE_dl_slot1_processing_retval;
}
4120
#endif
4121

4122
#ifdef UE_SLOT_PARALLELISATION
4123
int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
4124
        uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode)  {
4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136

    int l,l2;
    int pmch_flag=0;
    int frame_rx = proc->frame_rx;
    int subframe_rx = proc->subframe_rx;
    uint8_t pilot0;
    uint8_t pilot1;
    uint8_t slot0;
    uint8_t slot1;
    uint8_t first_ofdm_sym;

    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
4137

4138

4139 4140 4141
    T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));

    T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
fnabet's avatar
fnabet committed
4142 4143
            T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
                    ue->frame_parms.samples_per_tti * 4));
4144

4145 4146

    // start timers
4147
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
4148
    LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
4149
LOG_DEBUG_END
fnabet's avatar
fnabet committed
4150

4151
LOG_DEBUG_BEGIN(UE_TIMING)
4152 4153
    start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
    start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
4154
LOG_DEBUG_END
4155 4156 4157

    pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;

fnabet's avatar
fnabet committed
4158 4159
    if (do_pdcch_flag) {
        // deactivate reception until we scan pdcch
4160 4161 4162 4163
        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
fnabet's avatar
fnabet committed
4164 4165 4166 4167 4168 4169 4170 4171 4172

        if (ue->dlsch_SI[eNB_id])
            ue->dlsch_SI[eNB_id]->active = 0;
        if (ue->dlsch_p[eNB_id])
            ue->dlsch_p[eNB_id]->active = 0;
        if (ue->dlsch_ra[eNB_id])
            ue->dlsch_ra[eNB_id]->active = 0;
    }

4173
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
4174
    LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
fnabet's avatar
fnabet committed
4175
                    ue->Mod_id,frame_rx, subframe_rx);
4176
LOG_DEBUG_END
4177 4178 4179



fnabet's avatar
fnabet committed
4180 4181 4182 4183 4184 4185 4186 4187 4188

    if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
        l2 = 5;
    } else if (pmch_flag == 1) { // do first 2 symbols only
        l2 = 1;
    } else { // normal subframe, last symbol to be processed is the first of the second slot
        l2 = (ue->frame_parms.symbols_per_tti/2)-1;
    }

4189 4190
    int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
    if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
fnabet's avatar
fnabet committed
4191 4192 4193 4194
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // RX processing of symbols l=0...l2
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        first_ofdm_sym = 0;
4195
    } else {
fnabet's avatar
fnabet committed
4196 4197 4198 4199
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        first_ofdm_sym = 1;
4200 4201 4202 4203 4204
    }
    slot0  = (subframe_rx<<1);
    slot1  = (subframe_rx<<1) + 1;
    pilot0 = 0;
    if (ue->frame_parms.Ncp == 0) {  // normal prefix
fnabet's avatar
fnabet committed
4205
        pilot1 = 4;
4206
    } else { // extended prefix
fnabet's avatar
fnabet committed
4207
        pilot1 = 3;
4208
    }
Cedric Roux's avatar
Cedric Roux committed
4209

4210 4211 4212 4213 4214 4215 4216
    //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
    //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
    //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
    proc->chan_est_pilot0_slot1_available=0;
    proc->llr_slot1_available=0;
    proc->dci_slot0_available=0;
    proc->first_symbol_available=0;
4217
    proc->chan_est_slot1_available=0;
tct-labo4's avatar
tct-labo4 committed
4218
    //proc->channel_level=0;
4219

4220 4221 4222 4223 4224 4225 4226 4227
    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
        LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id );
        exit_fun("nothing to add");
    }

    proc->instance_cnt_slot1_dl_processing++;
    if (proc->instance_cnt_slot1_dl_processing == 0)
    {
4228
    LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_slot1_dl_processing : %d \n", proc->instance_cnt_slot1_dl_processing );
4229 4230
        if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id);
fnabet's avatar
fnabet committed
4231 4232
            exit_fun("nothing to add");
        }
4233 4234 4235 4236 4237 4238 4239 4240 4241 4242
        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \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_slot1_dl_processing);
        if (proc->instance_cnt_slot1_dl_processing > 2)
            exit_fun("instance_cnt_slot1_dl_processing > 2");
4243
    }
4244 4245
    //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,"");
    AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,"");
4246

4247 4248

    /**** Slot0 FE Processing ****/
4249
    // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
4250
LOG_DEBUG_BEGIN(UE_TIMING)
4251
    start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
4252
LOG_DEBUG_END
4253
    // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
4254
    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
4255 4256 4257 4258 4259
    front_end_fft(ue,
            pilot0,
            slot1,
            0,
            0);
4260
    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
4261 4262 4263 4264 4265
    front_end_fft(ue,
            pilot1,
            slot0,
            0,
            0);
4266
    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
4267 4268 4269 4270
    front_end_chanEst(ue,
            pilot1,
            slot0,
            0);
4271
    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
4272 4273 4274 4275 4276
    front_end_chanEst(ue,
            pilot0,
            slot1,
            0);
    proc->chan_est_pilot0_slot1_available = 1;
4277
    //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
fnabet's avatar
fnabet committed
4278

4279 4280 4281 4282 4283
    // 2- perform FFT for other ofdm symbols other than pilots
    for (l=first_ofdm_sym; l<=l2; l++)
    {
        if( (l != pilot0) && (l != pilot1))
        {
4284
            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
4285
LOG_DEBUG_BEGIN(UE_TIMING)
4286
            start_meas(&ue->ofdm_demod_stats);
4287
LOG_DEBUG_END
4288 4289 4290 4291 4292 4293 4294
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
            front_end_fft(ue,
                    l,
                    slot0,
                    0,
                    0);
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
4295
LOG_DEBUG_BEGIN(UE_TIMING)
4296
            stop_meas(&ue->ofdm_demod_stats);
4297
LOG_DEBUG_END
4298 4299
        }
    } // for l=1..l2
hbilel's avatar
hbilel committed
4300

4301 4302 4303 4304 4305
    // 3- perform Channel Estimation for slot0
    for (l=first_ofdm_sym; l<=l2; l++)
    {
        if( (l != pilot0) && (l != pilot1))
        {
4306
            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
fnabet's avatar
fnabet committed
4307 4308 4309 4310
            front_end_chanEst(ue,
                    l,
                    slot0,
                    0);
4311 4312 4313
        }
        ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
    }
hbilel's avatar
hbilel committed
4314

fnabet's avatar
fnabet committed
4315
    if (do_pdcch_flag) {
4316
LOG_DEBUG_BEGIN(UE_TIMING)
4317
        start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4318
LOG_DEBUG_END
fnabet's avatar
fnabet committed
4319 4320
        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);
4321 4322 4323 4324
LOG_DEBUG_BEGIN(UE_TIMING)
            LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END

4325
            //proc->dci_slot0_available = 1;
fnabet's avatar
fnabet committed
4326 4327
            return(-1);
        }
4328
        //proc->dci_slot0_available=1;
4329
LOG_DEBUG_BEGIN(UE_TIMING)
4330
        stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4331 4332
        LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END
4333
    }
4334

4335
    //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
4336

fnabet's avatar
fnabet committed
4337
    // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
4338
LOG_DEBUG_BEGIN(UE_TIMING)
4339
    stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
4340 4341
    LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
LOG_DEBUG_END
fnabet's avatar
fnabet committed
4342

4343 4344 4345
    //wait until slot1 FE is done
    uint32_t wait = 0;
    while(proc->chan_est_slot1_available == 0)
4346
    {
4347 4348
        usleep(1);
        wait++;
4349
    }
hbilel's avatar
hbilel committed
4350

4351
LOG_DEBUG_BEGIN(UE_TIMING)
4352
    stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
4353 4354
    LOG_UI(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
LOG_DEBUG_END
4355
    /**** End Subframe FE Processing ****/
fnabet's avatar
fnabet committed
4356

4357

4358
    //Trigger LLR parallelized for Slot 1
bruno mongazon's avatar
bruno mongazon committed
4359 4360
    //proc->dci_slot0_available=1;
    //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
4361

4362
    /**** Pdsch Procedure Slot0 ****/
4363 4364
    // start main thread for Pdsch Procedure (slot0)
    // do procedures for C-RNTI
4365 4366
    //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx);
    //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active);
4367

4368
LOG_DEBUG_BEGIN(UE_TIMING)
4369
    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4370
LOG_DEBUG_END
4371

4372
LOG_DEBUG_BEGIN(UE_TIMING)
4373
    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
4374
LOG_DEBUG_END
4375
    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
fnabet's avatar
fnabet committed
4376 4377 4378 4379 4380
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                PDSCH,
4381
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
fnabet's avatar
fnabet committed
4382
                NULL,
4383
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4384
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4385 4386 4387
                abstraction_flag);

        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
4388
    }
fnabet's avatar
fnabet committed
4389

4390 4391
    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
fnabet's avatar
fnabet committed
4392 4393 4394 4395 4396 4397 4398
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                SI_PDSCH,
                ue->dlsch_SI[eNB_id],
                NULL,
4399
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4400
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4401 4402
                abstraction_flag);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
4403
    }
fnabet's avatar
fnabet committed
4404

4405 4406
    // do procedures for SI-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
fnabet's avatar
fnabet committed
4407 4408 4409 4410 4411 4412 4413
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                P_PDSCH,
                ue->dlsch_p[eNB_id],
                NULL,
4414
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4415
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4416 4417
                abstraction_flag);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
4418
    }
hbilel's avatar
hbilel committed
4419

4420 4421
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
fnabet's avatar
fnabet committed
4422 4423 4424 4425 4426 4427 4428
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                RA_PDSCH,
                ue->dlsch_ra[eNB_id],
                NULL,
4429
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4430
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4431 4432
                abstraction_flag);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
4433
    }
hbilel's avatar
hbilel committed
4434

4435 4436
    // LLR linear
    proc->dci_slot0_available=1;
4437
    //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
4438

4439 4440

LOG_DEBUG_BEGIN(UE_TIMING)
4441
    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
4442 4443
    LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
LOG_DEBUG_END
4444

hbilel's avatar
hbilel committed
4445

4446 4447 4448 4449 4450 4451
    //wait until LLR Slot1 is done
    wait = 0;
    while(proc->llr_slot1_available == 0)
    {
        usleep(1);
        wait++;
4452
    }
hbilel's avatar
hbilel committed
4453

fnabet's avatar
fnabet committed
4454 4455


4456
LOG_DEBUG_BEGIN(UE_TIMING)
4457
    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4458 4459
    LOG_UI(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END
4460

fnabet's avatar
fnabet committed
4461 4462

    //=====================================================================//
4463
LOG_DEBUG_BEGIN(UE_TIMING)
4464
    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4465
LOG_DEBUG_END
tct-labo4's avatar
tct-labo4 committed
4466

4467
    LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active,
tct-labo4's avatar
tct-labo4 committed
4468 4469 4470
    		ue->dlsch_SI[eNB_id]->active,
			//ue->dlsch_p[eNB_id]->active,
			ue->dlsch_ra[eNB_id]->active);
4471
    // Start Turbo decoder
4472
    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4473
        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
fnabet's avatar
fnabet committed
4474 4475 4476 4477
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                PDSCH,
4478 4479
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
fnabet's avatar
fnabet committed
4480 4481 4482
                &ue->dlsch_errors[eNB_id],
                mode,
                abstraction_flag);
4483
        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
fnabet's avatar
fnabet committed
4484
    }
4485

fnabet's avatar
fnabet committed
4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525
    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                SI_PDSCH,
                ue->dlsch_SI[eNB_id],
                NULL,
                &ue->dlsch_SI_errors[eNB_id],
                mode,
                abstraction_flag);
        ue->dlsch_SI[eNB_id]->active = 0;
    }

    // do procedures for P-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                P_PDSCH,
                ue->dlsch_p[eNB_id],
                NULL,
                &ue->dlsch_p_errors[eNB_id],
                mode,
                abstraction_flag);
        ue->dlsch_p[eNB_id]->active = 0;
    }
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                RA_PDSCH,
                ue->dlsch_ra[eNB_id],
                NULL,
                &ue->dlsch_ra_errors[eNB_id],
                mode,
                abstraction_flag);
        ue->dlsch_ra[eNB_id]->active = 0;
    }
4526

4527
LOG_DEBUG_BEGIN(UE_TIMING)
4528
        stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4529 4530
        LOG_UI(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END
fnabet's avatar
fnabet committed
4531

4532
        // duplicate harq structure
4533 4534 4535
        uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
        LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
        harq_status_t    *current_harq_ack       = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
4536

4537
        // For Debug parallelisation
4538 4539 4540 4541
        //if (current_harq_ack->ack == 0) {
            //printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,subframe_rx,current_harq_pid,current_harq_processes->round);
        //}
        for(uint8_t rx_th_idx=1; rx_th_idx<RX_NB_TH; rx_th_idx++)
4542
        {
4543 4544
            LTE_DL_UE_HARQ_t *harq_processes_dest  = ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid];
            harq_status_t    *harq_ack_dest        = &ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[subframe_rx];
4545 4546 4547 4548 4549 4550

            copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
            copy_ack_struct(harq_ack_dest, current_harq_ack);

        }
    /*
fnabet's avatar
fnabet committed
4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562
    LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
    LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];

    harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
    harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
    harq_status_t *harq_ack_dest1    = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];

    copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
    copy_ack_struct(harq_ack_dest, current_harq_ack);

    copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
    copy_ack_struct(harq_ack_dest1, current_harq_ack);
4563
    */
4564
    if (subframe_rx==9) {
fnabet's avatar
fnabet committed
4565 4566 4567
        if (frame_rx % 10 == 0) {
            if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
                ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
4568

fnabet's avatar
fnabet committed
4569 4570 4571
            ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
            ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
        }
gabrielC's avatar
gabrielC committed
4572 4573


fnabet's avatar
fnabet committed
4574 4575 4576 4577 4578
        ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
        ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
        LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
                ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
                ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
gabrielC's avatar
gabrielC committed
4579

fnabet's avatar
fnabet committed
4580 4581 4582 4583
#if UE_AUTOTEST_TRACE
        if ((frame_rx % 100 == 0)) {
            LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
        }
4584
#endif
4585

4586
    }
4587

fnabet's avatar
fnabet committed
4588
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
jiangx's avatar
jiangx committed
4589

4590
LOG_DEBUG_BEGIN(UE_TIMING)
4591
    stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
4592 4593
    LOG_UI(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END
jiangx's avatar
jiangx committed
4594

fnabet's avatar
fnabet committed
4595
    LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
4596
    return (0);
fnabet's avatar
fnabet committed
4597
}
4598
#endif /*UE_SLOT_PARALLELISATION */
4599

fnabet's avatar
fnabet committed
4600

4601 4602 4603 4604 4605
void phy_procedures_UE_SL_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) {


}

4606
int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
4607
			 uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) {
fnabet's avatar
fnabet committed
4608

4609 4610 4611 4612 4613
  int l,l2;
  int pilot1;
  int pmch_flag=0;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
fnabet's avatar
fnabet committed
4614

4615 4616
  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
fnabet's avatar
fnabet committed
4617

4618
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
fnabet's avatar
fnabet committed
4619

4620

hbilel's avatar
hbilel committed
4621
  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
4622

hbilel's avatar
hbilel committed
4623
  T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
4624 4625
    T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
             ue->frame_parms.samples_per_tti * 4));
4626

4627

hbilel's avatar
hbilel committed
4628
  // start timers
4629
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
4630
  LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
4631
LOG_DEBUG_END
4632

4633
LOG_DEBUG_BEGIN(UE_TIMING)
4634
  start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
hbilel's avatar
hbilel committed
4635
  start_meas(&ue->generic_stat);
4636
LOG_DEBUG_END
4637

4638
  pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
4639

4640
  if (do_pdcch_flag) {
4641
  // deactivate reception until we scan pdcch
4642 4643 4644 4645
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
4646

4647 4648
  if (ue->dlsch_SI[eNB_id])
    ue->dlsch_SI[eNB_id]->active = 0;
4649 4650
  if (ue->dlsch_p[eNB_id])
    ue->dlsch_p[eNB_id]->active = 0;
4651 4652
  if (ue->dlsch_ra[eNB_id])
    ue->dlsch_ra[eNB_id]->active = 0;
4653
  }
4654

4655
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
4656
  LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
4657
  ue->Mod_id,frame_rx, subframe_rx);
4658
LOG_DEBUG_END
4659

4660 4661 4662 4663 4664
  if (ue->frame_parms.Ncp == 0) {  // normal prefix
    pilot1 = 4;
  } else { // extended prefix
    pilot1 = 3;
  }
fnabet's avatar
fnabet committed
4665 4666


4667 4668 4669 4670 4671 4672 4673
  if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
    l2 = 5;
  } else if (pmch_flag == 1) { // do first 2 symbols only
    l2 = 1;
  } else { // normal subframe, last symbol to be processed is the first of the second slot
    l2 = (ue->frame_parms.symbols_per_tti/2)-1;
  }
fnabet's avatar
fnabet committed
4674

4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686
  int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
  if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // RX processing of symbols l=0...l2
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    l=0;
  } else {
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    l=1;
  }
hbilel's avatar
hbilel committed
4687

4688 4689
  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);
4690
  for (; l<=l2; l++) {
4691
    if (abstraction_flag == 0) {
4692
LOG_DEBUG_BEGIN(UE_TIMING)
gabrielC's avatar
gabrielC committed
4693
        start_meas(&ue->ofdm_demod_stats);
4694
LOG_DEBUG_END
4695 4696
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
      slot_fep(ue,
4697 4698 4699 4700 4701
         l,
         (subframe_rx<<1),
         0,
         0,
         0);
4702
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
4703
LOG_DEBUG_BEGIN(UE_TIMING)
4704
      stop_meas(&ue->ofdm_demod_stats);
4705
LOG_DEBUG_END
4706
    }
fnabet's avatar
fnabet committed
4707

4708
    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
fnabet's avatar
fnabet committed
4709

4710 4711 4712 4713
    if (do_pdcch_flag) {
      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);
fnabet's avatar
fnabet committed
4714

4715
	//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
4716 4717 4718 4719
	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);
	  return(-1);
	}
4720
	//stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
4721
    //printf("subframe %d n_pdcch_sym %d pdcch procedures  %5.3f \n",
4722 4723
    //        subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
    //     (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
4724
	LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
4725
      }
4726
    }
4727

4728
  } // for l=1..l2
4729 4730
  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);

4731
  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4732 4733 4734 4735 4736
    // If this is PMCH, call procedures and return
  if (pmch_flag == 1) {
    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
    return 0;
  }
4737

4738
  slot_fep(ue,
4739 4740 4741 4742 4743
     0,
     1+(subframe_rx<<1),
     0,
     0,
     0);
4744

4745
  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
4746
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
4747
  stop_meas(&ue->generic_stat);
4748 4749
  LOG_UI(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
LOG_DEBUG_END
hbilel's avatar
hbilel committed
4750

fnabet's avatar
fnabet committed
4751

gabrielC's avatar
gabrielC committed
4752
  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4753
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
4754
  start_meas(&ue->generic_stat);
4755
LOG_DEBUG_END
4756
  // do procedures for C-RNTI
4757
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4758
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
4759 4760 4761 4762
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
4763
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
4764
			NULL,
4765
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4766 4767
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
fnabet's avatar
fnabet committed
4768

4769
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
4770
  }
hbilel's avatar
hbilel committed
4771

4772
  LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4773 4774
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
4775
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
4776
    ue_pdsch_procedures(ue,
4777

4778 4779 4780 4781 4782
			proc,
			eNB_id,
			SI_PDSCH,
			ue->dlsch_SI[eNB_id],
			NULL,
4783
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4784 4785
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
4786
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
4787
  }
4788 4789 4790

  // do procedures for SI-RNTI
  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
4791
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
4792 4793 4794 4795 4796 4797
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			P_PDSCH,
			ue->dlsch_p[eNB_id],
			NULL,
4798
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4799 4800
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
4801
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
4802 4803
  }

4804 4805
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
4806
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
4807 4808 4809 4810 4811 4812
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			RA_PDSCH,
			ue->dlsch_ra[eNB_id],
			NULL,
4813
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4814 4815
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
4816
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
4817
  }
fnabet's avatar
fnabet committed
4818

4819 4820
  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);
hbilel's avatar
hbilel committed
4821

4822 4823 4824
  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; l<ue->frame_parms.symbols_per_tti>>1; l++) {
      if (abstraction_flag == 0) {
4825
LOG_DEBUG_BEGIN(UE_TIMING)
gabrielC's avatar
gabrielC committed
4826
          start_meas(&ue->ofdm_demod_stats);
4827
LOG_DEBUG_END
4828 4829 4830 4831
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
	slot_fep(ue,
		 l,
		 1+(subframe_rx<<1),
4832
		 0,
4833 4834 4835
		 0,
		 0);
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
4836
LOG_DEBUG_BEGIN(UE_TIMING)
gabrielC's avatar
gabrielC committed
4837
    stop_meas(&ue->ofdm_demod_stats);
4838
LOG_DEBUG_END
4839
      }
fnabet's avatar
fnabet committed
4840

4841
      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
fnabet's avatar
fnabet committed
4842

4843
    } // for l=1..l2
4844 4845 4846 4847 4848 4849 4850 4851

    // do first symbol of next downlink subframe for channel estimation
    int next_subframe_rx = (1+subframe_rx)%10;
    if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
    {
      slot_fep(ue,
         0,
         (next_subframe_rx<<1),
4852
         0,
4853 4854 4855
         0,
         0);
    }
4856
  } // not an S-subframe
4857
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
4858
  stop_meas(&ue->generic_stat);
4859 4860
  LOG_UI(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
LOG_DEBUG_END
hbilel's avatar
hbilel committed
4861

4862 4863
  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);

4864 4865
  if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
  {
4866
    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
4867
  }
fnabet's avatar
fnabet committed
4868 4869 4870



4871
  // do procedures for C-RNTI
4872
  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4873
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4874
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
4875 4876 4877
LOG_DEBUG_BEGIN(UE_TIMING)
    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
LOG_DEBUG_END
4878 4879 4880 4881
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
4882
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
4883 4884 4885 4886
			NULL,
			1+(ue->frame_parms.symbols_per_tti>>1),
			ue->frame_parms.symbols_per_tti-1,
			abstraction_flag);
4887 4888
    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);
4889
LOG_DEBUG_BEGIN(UE_TIMING)
4890 4891
    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4892
LOG_DEBUG_END
4893 4894 4895 4896
    ue_dlsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
4897 4898
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
4899 4900 4901
			&ue->dlsch_errors[eNB_id],
			mode,
			abstraction_flag);
4902
LOG_DEBUG_BEGIN(UE_TIMING)
4903
    stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4904 4905 4906
    LOG_UI(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
    LOG_UI(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END
hbilel's avatar
hbilel committed
4907

4908
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
4909

4910
  }
4911
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
4912
  start_meas(&ue->generic_stat);
4913
LOG_DEBUG_END
hbilel's avatar
hbilel committed
4914

4915
LOG_M_BEGIN(DEBUG_UE_PHYPROC)
4916
  if(subframe_rx==5 &&  ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){
bruno mongazon's avatar
bruno mongazon committed
4917 4918
       //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0);
       //LOG_M("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);
hbilel's avatar
hbilel committed
4919

bruno mongazon's avatar
bruno mongazon committed
4920 4921
       LOG_M("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
       //LOG_M("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
hbilel's avatar
hbilel committed
4922

bruno mongazon's avatar
bruno mongazon committed
4923
       //LOG_M("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
hbilel's avatar
hbilel committed
4924

bruno mongazon's avatar
bruno mongazon committed
4925 4926 4927 4928 4929
       LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
       LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
       LOG_M("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
       //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
       //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
hbilel's avatar
hbilel committed
4930 4931 4932

       AssertFatal (0,"");
  }
4933
LOG_M_END
hbilel's avatar
hbilel committed
4934

4935 4936 4937
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
4938 4939 4940 4941 4942 4943 4944 4945
      proc,
      eNB_id,
      SI_PDSCH,
      ue->dlsch_SI[eNB_id],
      NULL,
      1+(ue->frame_parms.symbols_per_tti>>1),
      ue->frame_parms.symbols_per_tti-1,
      abstraction_flag);
4946

4947
    ue_dlsch_procedures(ue,
4948 4949 4950 4951 4952 4953 4954 4955
      proc,
      eNB_id,
      SI_PDSCH,
      ue->dlsch_SI[eNB_id],
      NULL,
      &ue->dlsch_SI_errors[eNB_id],
      mode,
      abstraction_flag);
4956 4957
    ue->dlsch_SI[eNB_id]->active = 0;
  }
4958 4959 4960 4961

  // do procedures for P-RNTI
  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
4962 4963 4964 4965 4966 4967 4968 4969
      proc,
      eNB_id,
      P_PDSCH,
      ue->dlsch_p[eNB_id],
      NULL,
      1+(ue->frame_parms.symbols_per_tti>>1),
      ue->frame_parms.symbols_per_tti-1,
      abstraction_flag);
4970 4971

    ue_dlsch_procedures(ue,
4972 4973 4974 4975 4976 4977 4978 4979
      proc,
      eNB_id,
      P_PDSCH,
      ue->dlsch_p[eNB_id],
      NULL,
      &ue->dlsch_p_errors[eNB_id],
      mode,
      abstraction_flag);
4980 4981
    ue->dlsch_p[eNB_id]->active = 0;
  }
4982 4983 4984
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
4985 4986 4987 4988 4989 4990 4991 4992
      proc,
      eNB_id,
      RA_PDSCH,
      ue->dlsch_ra[eNB_id],
      NULL,
      1+(ue->frame_parms.symbols_per_tti>>1),
      ue->frame_parms.symbols_per_tti-1,
      abstraction_flag);
4993
    ue_dlsch_procedures(ue,
4994 4995 4996 4997 4998 4999 5000 5001
      proc,
      eNB_id,
      RA_PDSCH,
      ue->dlsch_ra[eNB_id],
      NULL,
      &ue->dlsch_ra_errors[eNB_id],
      mode,
      abstraction_flag);
5002 5003
    ue->dlsch_ra[eNB_id]->active = 0;
  }
5004

gabrielC's avatar
gabrielC committed
5005
  // duplicate harq structure
5006

5007 5008 5009 5010
  uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[next1_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
  LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[next2_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
gabrielC's avatar
gabrielC committed
5011

5012 5013 5014
  harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
  harq_status_t *harq_ack_dest    = &ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack[subframe_rx];
  harq_status_t *harq_ack_dest1    = &ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack[subframe_rx];
gabrielC's avatar
gabrielC committed
5015

5016 5017
  copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
  copy_ack_struct(harq_ack_dest, current_harq_ack);
gabrielC's avatar
gabrielC committed
5018

5019 5020 5021
  copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
  copy_ack_struct(harq_ack_dest1, current_harq_ack);

5022
  if (subframe_rx==9) {
Raymond Knopp's avatar
 
Raymond Knopp committed
5023
    if (frame_rx % 10 == 0) {
5024
      if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
5025
  ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
5026

5027 5028
      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
5029
    }
5030 5031


5032 5033
    ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
    ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
5034
    LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
fnabet's avatar
fnabet committed
5035 5036
    ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
    ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
5037

5038
LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
5039 5040 5041
    if ((frame_rx % 100 == 0)) {
      LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
    }
5042
LOG_DEBUG_END
5043

5044
  }
5045

5046
LOG_DEBUG_BEGIN(UE_TIMING)
hbilel's avatar
hbilel committed
5047
  stop_meas(&ue->generic_stat);
gabrielC's avatar
gabrielC committed
5048
  printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
5049
LOG_DEBUG_END
jiangx's avatar
jiangx committed
5050

5051
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
hbilel's avatar
hbilel committed
5052

5053
LOG_DEBUG_BEGIN(UE_TIMING)
5054
  stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
5055 5056
  LOG_UI(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
LOG_DEBUG_END
fnabet's avatar
fnabet committed
5057

5058
  LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
5059
  return (0);
5060
}
5061 5062 5063



5064
void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode)
5065
{
5066
#if defined(ENABLE_ITTI)
5067 5068
  MessageDef   *msg_p;
  int           result;
5069
#endif
5070

5071 5072 5073 5074
  int           frame_rx = proc->frame_rx;
  int           frame_tx = proc->frame_tx;
  int           subframe_rx = proc->subframe_rx;
  int           subframe_tx = proc->subframe_tx;
5075

5076

5077
  UE_L2_STATE_t ret;
5078
  int slot;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
5079

5080 5081
  if (ue->mac_enabled == 0) {
    ue->UE_mode[eNB_id]=PUSCH;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
5082
  }
5083 5084


5085
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
5086
LOG_DEBUG_BEGIN(UE_TIMING)
5087
  start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
5088 5089
LOG_DEBUG_END

5090
#if defined(ENABLE_ITTI)
5091

5092 5093
  do {
    // Checks if a message has been sent to PHY sub-task
5094
    itti_poll_msg (TASK_PHY_UE, &msg_p);
5095

5096 5097
    if (msg_p != NULL) {
      switch (ITTI_MSG_ID(msg_p)) {
5098
      case PHY_FIND_CELL_REQ:
5099
  LOG_I(PHY, "[UE %d] Received %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p));
5100 5101 5102 5103

  /* TODO process the message */
  break;

5104
      default:
5105
  LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p));
5106
  break;
5107
      }
5108

5109 5110
      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
5111 5112
    }
  } while(msg_p != NULL);
5113

5114
#endif
5115

5116
  for (slot=0;slot<2;slot++) {
5117

5118
    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
5119
  (ue->frame_parms.frame_type == FDD)) {
5120
      phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode);
5121
    }
5122

5123
    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
5124 5125
	(ue->frame_parms.frame_type == FDD)) {
      phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode);
5126
    }
5127

5128
    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
5129
	(slot==1)) {
5130
      phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag);
5131
    }
5132

5133
    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
5134 5135
	(slot==0)) {
	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode);
5136
    }
5137

5138 5139
    if (ue->mac_enabled==1) {
      if (slot==0) {
5140

5141
          //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx);
5142 5143 5144 5145 5146 5147 5148 5149 5150
        ret = ue_scheduler(ue->Mod_id,
			   frame_rx,
			   subframe_rx,
			   frame_tx,
			   subframe_tx,
			   subframe_select(&ue->frame_parms,subframe_tx),
			   eNB_id,
			   0/*FIXME CC_id*/);
	
5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168
	if (ret == CONNECTION_LOST) {
	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
		frame_rx,subframe_tx);
	  ue->UE_mode[eNB_id] = PRACH;
	  //      mac_xface->macphy_exit("Connection lost");
	} else if (ret == PHY_RESYNCH) {
	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
		ue->Mod_id,
		frame_rx,subframe_tx);
	  ue->UE_mode[eNB_id] = RESYNCH;
	  //     mac_xface->macphy_exit("Connection lost");
	} else if (ret == PHY_HO_PRACH) {
	  LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
		ue->Mod_id,frame_rx,subframe_tx);
	  ue->UE_mode[eNB_id] = PRACH;
	}
      }
    }
5169
    
5170
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
5171
LOG_DEBUG_BEGIN(UE_TIMING)
5172
    stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
5173
LOG_DEBUG_END
5174
  } // slot
5175
}
5176 5177