phy_procedures_lte_ue.c 146 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
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
#include "assertions.h"
34 35 36 37 38 39 40 41 42 43
#include "defs.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"

#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif

Florian Kaltenberger's avatar
Florian Kaltenberger committed
44
#define DEBUG_PHY_PROC
45 46 47 48 49 50 51 52 53 54 55 56 57 58

#ifndef PUCCH
#define PUCCH
#endif

#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#include "UTIL/LOG/log.h"

#ifdef EMOS
fifo_dump_emos_UE emos_dump_UE;
#endif

#include "UTIL/LOG/vcd_signal_dumper.h"
59
#include "UTIL/OPT/opt.h"
60

61 62 63 64
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

65 66 67
#include "PHY/defs.h"

#include "PHY/CODING/extern.h"
68

69 70
#include "T.h"

71 72 73 74 75 76 77
#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

extern int oai_exit;

hbilel's avatar
hbilel committed
78
extern double cpuf;
79 80 81



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

86

87

88
void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid)
89
{
90
  unsigned int coded_bits_per_codeword;
91 92 93
  uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;

  coded_bits_per_codeword = get_G(&ue->frame_parms,
hbilel's avatar
hbilel committed
94 95 96 97
                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm,
                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
hbilel's avatar
hbilel committed
98
                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
99
                                  proc->frame_rx,
100
				  subframe,
101
				  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
102

103 104 105
  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[subframe&0x1][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
106
  /*
107 108 109 110
    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
111
  */
112 113
  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0],300*12,1,1);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[subframe&0x1][0]->llr[0],coded_bits_per_codeword,1,0);
114

115 116
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0,300*12,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0,300*12,1,1);
117 118
}

119
void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
120
{
121
  unsigned int coded_bits_per_codeword;
122
  uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
123

124 125 126
  coded_bits_per_codeword = get_G(&ue->frame_parms,
                                  ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
                                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
127
                                  2,
128
                                  1,
hbilel's avatar
hbilel committed
129
                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
130
                                  proc->frame_rx,
131
				  subframe,
132
				  0);
133
  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",
134 135
        ue->Mod_id,
	ue->frame_parms.ofdm_symbol_size,
136
	nsymb,
137 138 139
        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,
hbilel's avatar
hbilel committed
140
        ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
141
        coded_bits_per_codeword);
142

143
  write_output("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
144

145
  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
146 147
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  write_output("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);
148
  /*
149 150 151 152
    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
153
  */
154 155
  write_output("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);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0);
156

157 158
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1);
159
  sleep(1);
160 161 162
  exit(-1);
}

kaltenbe's avatar
kaltenbe committed
163
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
Raymond Knopp's avatar
 
Raymond Knopp committed
164 165
//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};
/*
166 167
  unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
  {
168

169
  int gain_dB = power_dBm - power_max_dBm;
Raymond Knopp's avatar
 
Raymond Knopp committed
170 171 172 173
  int amp_x_100;

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

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

  int gain_dB = power_dBm - power_max_dBm;
  double gain_lin;

  gain_lin = pow(10,.1*gain_dB);
  if ((nb_rb >0) && (nb_rb <= N_RB_UL)) {
    return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
  }
  else {
    LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
    mac_xface->macphy_exit("");
  }
  return(0);
}

222 223
#endif

224
void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
225
{
226
  unsigned int coded_bits_per_codeword;
227
  uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
228

229 230 231
  coded_bits_per_codeword = get_G(&ue->frame_parms,
                                  ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
                                  ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even,
232
                                  2,
233
                                  1,
hbilel's avatar
hbilel committed
234
                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
235
                                  proc->frame_rx,
236
				  subframe,
237
				  0);
238
  LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
239 240 241 242
        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,
hbilel's avatar
hbilel committed
243
        ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
244
        coded_bits_per_codeword);
245

246
  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
247 248
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1);
  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
249
  /*
250 251 252 253
    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
254
  */
255 256
  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0);
257

258 259
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
260
}
261

262
void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
263
{
264 265 266

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

268
  uint8_t i,j,k,s;
269
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
270

hbilel's avatar
hbilel committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
  //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
  for(int l=0; l<2; l++) {
      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;
                      }
                  }
              }
288
          }
289

hbilel's avatar
hbilel committed
290 291 292 293 294 295
          //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;
296

hbilel's avatar
hbilel committed
297 298
              }
          }
299

hbilel's avatar
hbilel committed
300 301
          // flush Msg3 buffer
          ue->ulsch_Msg3_active[i] = 0;
302

hbilel's avatar
hbilel committed
303
      }
304 305 306
  }
}

307 308
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
309 310

  // if contention resolution fails, go back to PRACH
Raymond Knopp's avatar
 
Raymond Knopp committed
311
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
hbilel's avatar
hbilel committed
312 313 314 315
  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;
316
  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);
317 318 319
  //mac_xface->macphy_exit("");
}

320 321
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
322 323 324

  int i;

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

hbilel's avatar
hbilel committed
327 328
  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;
329
  PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
330
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
331

332
  for (i=0; i<8; i++) {
333 334
    if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE;
hbilel's avatar
hbilel committed
335 336
      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;
337
    }
338 339 340 341 342
  }


}

343 344
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
345

Raymond Knopp's avatar
 
Raymond Knopp committed
346
  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
347 348

}
349
void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) {
350

351
  ue->timing_advance = timing_advance*4;
352 353


354
#ifdef DEBUG_PHY_PROC
Cedric Roux's avatar
Cedric Roux committed
355 356 357
  /* 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);
358 359 360 361
#endif

}

362 363
void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
{
364

365
  //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
366

367
  // timing advance has Q1.5 format
368
  timing_advance = timing_advance - 31;
369

370 371
  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!!!

372

373
  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);
374

375 376 377

}

378
uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
379 380
{

381 382
  int subframe=proc->subframe_tx;

383
  LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
hbilel's avatar
hbilel committed
384
        ue->Mod_id,ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti,proc->frame_tx,subframe,
385
        ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
386

387 388
  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)
389
      return(1);
390 391
  } 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))
392
      return(1);
393
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 34) { // 20 ms SR period
394
    if ((10*(proc->frame_tx&1)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
395
      return(1);
396
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 74) { // 40 ms SR period
397
    if ((10*(proc->frame_tx&3)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
398
      return(1);
399
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 154) { // 80 ms SR period
400
    if ((10*(proc->frame_tx&7)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
401 402 403 404 405 406
      return(1);
  }

  return(0);
}

407 408 409 410 411 412 413 414 415 416 417
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));

418 419 420
  if (cqirep->cqi_PMI_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
    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));
439 440 441
  if (cqirep->ri_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
442 443 444 445 446
    return(1);
  else
    return(0);
}

hbilel's avatar
hbilel committed
447 448


449
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
450
{
451 452 453 454 455 456 457 458 459
  
  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
460 461 462

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

465 466
  if (isSubframeSRS) {  
    LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
fnabet's avatar
fnabet committed
467 468
      if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
      {
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
          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;
                      SR_payload = mac_xface->ue_get_SR(Mod_id,
                              CC_id,
                              frame_tx,
                              eNB_id,
hbilel's avatar
hbilel committed
503
                              ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti,
504 505 506 507 508 509 510 511 512
                              subframe_tx); // subframe used for meas gap

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

              uint8_t pucch_ack_payload[2];
              if (get_ack(&ue->frame_parms,
hbilel's avatar
hbilel committed
513
                      ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
514
                      subframe_tx,pucch_ack_payload,0) > 0)
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
              {
                  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
536
      }
fnabet's avatar
fnabet committed
537
      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
538 539 540
  }
}

541

Raymond Knopp's avatar
Raymond Knopp committed
542 543 544 545 546 547 548 549 550 551 552 553
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;
554
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
Raymond Knopp's avatar
Raymond Knopp committed
555 556
    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
      cqirep->Npd = 10;
557
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
Raymond Knopp's avatar
Raymond Knopp committed
558 559
    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
      cqirep->Npd = 20;
560
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
Raymond Knopp's avatar
Raymond Knopp committed
561 562
    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
      cqirep->Npd = 40;
563
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
Raymond Knopp's avatar
Raymond Knopp committed
564 565
    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
      cqirep->Npd = 80;
566
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
Raymond Knopp's avatar
Raymond Knopp committed
567 568
    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
      cqirep->Npd = 160;
569
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
Raymond Knopp's avatar
Raymond Knopp committed
570 571 572 573 574
    }
    else if (cqi_PMI_ConfigIndex > 317) {
      
      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
	cqirep->Npd = 32;
575
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
Raymond Knopp's avatar
Raymond Knopp committed
576 577 578
      }
      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
	cqirep->Npd = 64;
579
	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
Raymond Knopp's avatar
Raymond Knopp committed
580 581 582
      }
      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
	cqirep->Npd = 128;
583
	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
Raymond Knopp's avatar
Raymond Knopp committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
      }  
    }
  }
  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;
   }
  }
}

613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
                             lte_prefix_type_t cyclic_prefix_type,
                             uint8_t SR_payload,
                             uint8_t nb_cw,
                             uint8_t cqi_status,
                             uint8_t ri_status)
{
  if((cqi_status == 0) && (ri_status==0))
  {
      // PUCCH Format 1 1a 1b
      // 1- SR only ==> PUCCH format 1
      // 2- 1bit Ack/Nack with/without SR  ==> PUCCH format 1a
      // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
      if(nb_cw == 1)
      {
          return pucch_format1a;
      }
      if(nb_cw == 2)
      {
          return pucch_format1b;
      }
      if(SR_payload == 1)
      {
636 637 638 639 640 641 642
          if (frame_type == FDD) {
              return pucch_format1;
          } else if (frame_type == TDD) {
              return pucch_format1b;
          } else {
	      AssertFatal(1==0,"Unknown frame_type");
          }
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
      }
  }
  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
672
  return pucch_format1a;
673
}
674
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
675
		      UE_rxtx_proc_t *proc,
676
                      harq_status_t *harq_ack,
677 678 679 680
                      uint8_t eNB_id,
                      uint8_t *b,
                      uint8_t SR)
{
681

682
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
683
  uint8_t nCCE0,nCCE1,harq_ack1,harq_ack0;
684
  ANFBmode_t bundling_flag;
685
  uint16_t n1_pucch0=0,n1_pucch1=0;
686 687
  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
688 689 690
  int sf;
  int M;
  // clear this, important for case where n1_pucch selection is not used
691
  int subframe=proc->subframe_tx;
692

693
  ue->pucch_sel[subframe] = 0;
694 695 696

  if (frame_parms->frame_type == FDD ) { // FDD
    sf = (subframe<4)? subframe+6 : subframe-4;
hbilel's avatar
hbilel committed
697
    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[proc->subframe_rx&0x1][eNB_id]->nCCE[sf]);
698 699

    if (SR == 0)
hbilel's avatar
hbilel committed
700
      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[sf]);
701
    else
702
      return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
703
  } else {
704

705
    bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
706
#ifdef DEBUG_PHY_PROC
707 708

    if (bundling_flag==bundling) {
709
      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,
710
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
711
    } else {
712
      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,
713
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
714
    }
715

716
#endif
717

718 719 720 721 722
    switch (frame_parms->tdd_config) {
    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL

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

724
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
725 726 727
      if (subframe == 2) {  // ACK subframes 5,6
        candidate_dl[0] = 6;
        candidate_dl[1] = 5;
728 729
        M=2;
      } else if (subframe == 3) { // ACK subframe 9
730 731 732 733
        candidate_dl[0] = 9;
      } else if (subframe == 7) { // ACK subframes 0,1
        candidate_dl[0] = 1;
        candidate_dl[1] = 0;
734 735
        M=2;
      } else if (subframe == 8) { // ACK subframes 4
736
        candidate_dl[0] = 4;
737 738
      } else {
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
739
              ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config);
740
        return(0);
741 742
      }

743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
      // 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) {
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
              ue->Mod_id,proc->frame_tx,last_dl,frame_parms->tdd_config);
        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);
761 762

      // i=0
hbilel's avatar
hbilel committed
763
      nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[last_dl];
764
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
765

766
      harq_ack0 = b[0];
767 768

      if (harq_ack0!=2) {  // DTX
769 770 771 772
        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)
773
          ue->pucch_sel[subframe] = 0;
774 775 776
            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;
777
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
778 779 780 781 782 783 784 785 786 787 788 789
          }
        } 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);
          }
790
        }
791 792 793 794
      }


      break;
795

796 797 798 799 800 801 802
    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)
803
      last_dl = (subframe-2)<<1;
804
      // i=0
hbilel's avatar
hbilel committed
805
      nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[5+last_dl];
806
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
807
      // i=1
hbilel's avatar
hbilel committed
808
      nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(6+last_dl)%10];
809
      n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
810 811

      // set ACK/NAK to values if not DTX
hbilel's avatar
hbilel committed
812 813
      if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
        harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
814

hbilel's avatar
hbilel committed
815 816
      if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
        harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack;
817

818 819

      if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
820 821 822 823 824 825 826 827 828

        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;

829
          ue->pucch_sel[subframe] = 1;
830 831 832 833 834 835 836 837 838 839
          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)) {
840
            ue->pucch_sel[subframe] = 0;
841 842
            return(n1_pucch0);
          } else {
843
            ue->pucch_sel[subframe] = 1;
844 845 846 847 848 849 850 851 852
            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;
853
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
854 855 856 857
        }
      } 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;
858
          ue->pucch_sel[subframe] = 0;
859 860 861 862
          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];
863
          ue->pucch_sel[subframe] = 0;
864 865 866 867
          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];
868
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
869
        }
870
      }
871

872 873
      break;

874
    }  // switch tdd_config
875
  }
876

Cedric Roux's avatar
Cedric Roux committed
877
  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n", ue->Mod_id, proc->frame_tx);
878 879 880 881 882 883
  return(-1);
}


#ifdef EMOS
/*
884
  void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) {
885
  uint8_t harq_pid;
886

887 888

  if (next_slot%2==0) {
889 890 891 892 893 894 895
  // get harq_pid from subframe relationship
  harq_pid = subframe2harq_pid(&ue->frame_parms,ue->frame,(next_slot>>1));
  if (harq_pid==255) {
  LOG_E(PHY,"[UE%d] Frame %d : FATAL ERROR: illegal harq_pid, returning\n",
  0,ue->frame);
  return;
  }
896

897 898 899 900 901 902 903 904 905 906 907 908 909
  if (ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
  emos_dump_UE.uci_cnt[next_slot>>1] = 1;
  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o,ulsch[eNB_id]->o,MAX_CQI_BITS*sizeof(char));
  emos_dump_UE.UCI_data[0][next_slot>>1].O = ulsch[eNB_id]->O;
  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_RI,ulsch[eNB_id]->o_RI,2*sizeof(char));
  emos_dump_UE.UCI_data[0][next_slot>>1].O_RI = ulsch[eNB_id]->O_RI;
  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_ACK,ulsch[eNB_id]->o_ACK,4*sizeof(char));
  emos_dump_UE.UCI_data[0][next_slot>>1].O_ACK = ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK;
  }
  else {
  emos_dump_UE.uci_cnt[next_slot>>1] = 0;
  }
  }
910 911 912 913
  }
*/
#endif

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

916
  int aa;
917
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
918

919 920 921 922
  int nsymb;
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  int ulsch_start;
923
  int overflow=0;
924
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
925
  int k,l;
926
  int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16)));
927 928
#endif

929 930
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);

931 932 933 934 935
  start_meas(&ue->ofdm_mod_stats);
  nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
  
#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-
936 937 938 939 940 941 942 943 944 945 946 947
         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);
948 949 950
#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
951

952
//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
hbilel's avatar
hbilel committed
953 954 955 956 957 958
  if (empty_subframe)
  {
//#if 1
      overflow = ulsch_start - 9*frame_parms->samples_per_tti;
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {

959 960 961 962 963 964 965 966 967
          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);
		 }
hbilel's avatar
hbilel committed
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
      }
/*#else
      overflow = ulsch_start - 9*frame_parms->samples_per_tti;
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
          for (k=ulsch_start; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++) {
              ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
              ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
          }

          for (k=0; k<overflow; k++) {
              ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
              ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
          }
      }
#endif*/
      return;
  }
985
//#endif
hbilel's avatar
hbilel committed
986

987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
  if ((frame_tx%100) == 0)
    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
	  ue->Mod_id,frame_tx,subframe_tx,
	  ulsch_start,
	  ue->rx_offset,
	  ue->hw_timing_advance,
	  ue->timing_advance,
	  ue->N_TA_offset);
  
  
  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)
		   dummy_tx_buffer,
#else
		   &ue->common_vars.txdata[aa][ulsch_start],
#endif
		   frame_parms->ofdm_symbol_size,
		   nsymb,
		   frame_parms->nb_prefix_samples,
		   CYCLIC_PREFIX);
    else
      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)
			dummy_tx_buffer,
#else
			&ue->common_vars.txdata[aa][ulsch_start],
#endif
			nsymb,
			&ue->frame_parms);
    
    
#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
    
    
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
    overflow = ulsch_start - 9*frame_parms->samples_per_tti;
    
    
    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++) {
      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
    }
    
    for (k=0; k<overflow; k++,l++) {
      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
    }
#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)
	ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
      else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
	ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
      else
	ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
    }
1052
#endif
1053
#endif
1054 1055 1056 1057 1058 1059 1060 1061 1062
    /*
    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);
      write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
    }
    */
1063 1064 1065 1066
    
  } //nb_antennas_tx
  
  stop_meas(&ue->ofdm_mod_stats);
1067

1068
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
1069

1070
}
1071

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

1074 1075 1076 1077
  int frame_tx = proc->frame_tx;
  int subframe_tx = proc->subframe_tx;
  int prach_power;
  PRACH_RESOURCES_t prach_resources_local;
1078

1079 1080
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);

1081
  ue->generate_prach=0;
1082

1083 1084 1085 1086 1087
  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;
  }
1088

1089 1090 1091
  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) ) {
1092
      LOG_D(PHY,"Getting PRACH resources\n");
1093 1094 1095 1096 1097
      ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,
							   ue->CC_id,
							   frame_tx,
							   eNB_id,
							   subframe_tx);
Cedric Roux's avatar
Cedric Roux committed
1098
      LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
1099
      LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
    }
  }
  
  if (ue->prach_resources[eNB_id]!=NULL) {
    
    ue->generate_prach=1;
    ue->prach_cnt=0;
#ifdef SMBV
    ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
#endif
#ifdef OAI_EMU
    ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
#endif
    
    if (abstraction_flag == 0) {
Rohit Gupta's avatar
Rohit Gupta committed
1115 1116

      LOG_I(PHY,"mode %d\n",mode);
1117 1118
      
      if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
1119
	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);
1120
      }
1121
      else {
1122
	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1123
	ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1124
      }
1125
      
1126
      LOG_I(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",
Rohit Gupta's avatar
Rohit Gupta committed
1127 1128 1129 1130
	    ue->Mod_id,
	    frame_tx,
	    subframe_tx,
	    ue->prach_resources[eNB_id]->ra_PreambleIndex,
1131
		get_PL(ue->Mod_id,ue->CC_id,eNB_id),
1132
		ue->tx_power_dBm[subframe_tx],
Rohit Gupta's avatar
Rohit Gupta committed
1133 1134 1135 1136
	    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);

1137
      ue->tx_total_RE[subframe_tx] = 96;
1138 1139
      
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1140
      ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
					       ue->tx_power_max_dBm,
					       ue->frame_parms.N_RB_UL,
					       6);
#else
      ue->prach_vars[eNB_id]->amp = AMP;
#endif
      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",
	      ue->Mod_id,
	      proc->frame_rx,
	      proc->subframe_tx,
1152
	      ue->tx_power_dBm[subframe_tx],
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
	      ue->prach_vars[eNB_id]->amp);
      
      
      //      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),
1164
	    ue->tx_power_dBm[subframe_tx],
1165 1166 1167 1168 1169 1170 1171
	    dB_fixed(prach_power),
	    ue->prach_vars[eNB_id]->amp);
    } else {
      UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
      UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
    }
    
1172 1173 1174 1175 1176 1177 1178
    if (ue->mac_enabled==1){
      mac_xface->Msg1_transmitted(ue->Mod_id,
          ue->CC_id,
          frame_tx,
          eNB_id);
    }

1179 1180 1181 1182 1183 1184 1185 1186
    LOG_D(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));
    
  }	  
  
1187

1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
  // 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;
  
  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);
  
  ue->prach_cnt++;
  
  if (ue->prach_cnt==3)
    ue->generate_prach=0;
1199 1200

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
1201
}
1202

1203
void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1204

1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215
  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;
1216
  uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32)));
1217
  uint8_t access_mode;
1218
  uint8_t Nbundled=0;
hbilel's avatar
hbilel committed
1219 1220
  uint8_t ack_status_cw0=0;
  uint8_t ack_status_cw1=0;
1221

1222 1223
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN);

1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251
  // get harq_pid from subframe relationship
  harq_pid = subframe2harq_pid(&ue->frame_parms,
			       frame_tx,
			       subframe_tx);
  
  
  if (ue->mac_enabled == 1) {
    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
      
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
      
      if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
	generate_ue_ulsch_params_from_rar(ue,
					  proc,
					  eNB_id);
      
      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",
	    Mod_id,
	    frame_tx,
	    subframe_tx,
	    harq_pid);
      Msg3_flag = 1;
    } else {
      
      if (harq_pid==255) {
1252 1253
	LOG_E(PHY,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
	      Mod_id,frame_tx, subframe_tx);
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
	mac_xface->macphy_exit("Error in ulsch_decoding");
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
	stop_meas(&ue->phy_proc_tx);
	return;
      }
      
      Msg3_flag=0;
    }
  }
  
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302
  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
1303
      LOG_I(PHY,"Skip PUSCH generation!\n");
1304 1305 1306
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
    }
  }
1307 1308 1309 1310 1311
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
    
    ue->generate_ul_signal[eNB_id] = 1;
    
    // deactivate service request
1312
    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
1313
    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);
1314
    if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1))
1315
    {
Cedric Roux's avatar
Cedric Roux committed
1316
        LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n");
1317 1318 1319
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
    }
1320
    
hbilel's avatar
hbilel committed
1321 1322 1323 1324 1325 1326 1327 1328 1329 1330
    ack_status_cw0 = reset_ack(&ue->frame_parms,
            ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
            subframe_tx,
            ue->ulsch[eNB_id]->o_ACK,0);
    ack_status_cw1 = reset_ack(&ue->frame_parms,
            ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack,
            subframe_tx,
            ue->ulsch[eNB_id]->o_ACK,1);

    Nbundled = ack_status_cw0;
1331 1332 1333 1334 1335 1336
    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
    
    
    
    
1337

hbilel's avatar
hbilel committed
1338
    if (ack_status_cw0 > 0) {
1339 1340 1341

      // check if we received a PDSCH at subframe_tx - 4
      // ==> send ACK/NACK on PUSCH
hbilel's avatar
hbilel committed
1342
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1;
1343 1344 1345 1346 1347

#if T_TRACER
    if(ue->ulsch[eNB_id]->o_ACK[0])
    {
    	LOG_I(PHY,"PUSCH ACK\n");
hbilel's avatar
hbilel committed
1348 1349
        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
                      T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
1350 1351 1352 1353
    }
    else
    {
    	LOG_I(PHY,"PUSCH NACK\n");
hbilel's avatar
hbilel committed
1354 1355
        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
                      T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
1356 1357 1358
    }
#endif

1359
      LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
1360 1361
        Mod_id,
        ue->ulsch[eNB_id]->rnti,
1362
        frame_tx%1024,subframe_tx,
1363 1364 1365 1366
        ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
    }

1367
#ifdef DEBUG_PHY_PROC
1368
        LOG_D(PHY,
hbilel's avatar
hbilel committed
1369 1370
              "[UE  %d][PUSCH %d] AbsSubframe %d.%d %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n",
	  Mod_id,harq_pid,frame_tx,subframe_tx,proc->subframe_rx,
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381
	  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],
1382 1383
	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK,
	  ue->ulsch[eNB_id]->bundling);
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413
#endif
    
    
    
    
    
    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]);
      
      start_meas(&ue->ulsch_encoding_stats);
      
      if (abstraction_flag==0) {
	if (ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
			   ue,
			   harq_pid,
			   eNB_id,
hbilel's avatar
hbilel committed
1414
			   proc->subframe_rx,
1415 1416 1417 1418 1419
			   ue->transmission_mode[eNB_id],0,0)!=0) {
	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
	  mac_xface->macphy_exit("Error in ulsch_coding");
	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
	  stop_meas(&ue->phy_proc_tx);
1420
	  //printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0));
1421 1422 1423 1424
	  return;
	}
      }
      
1425
#ifdef PHY_ABSTRACTION
1426
      else {
hbilel's avatar
hbilel committed
1427
	ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,proc->subframe_rx,harq_pid,0);
1428 1429
      }
      
1430
#endif
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459
      
      stop_meas(&ue->ulsch_encoding_stats);
      
      if (ue->mac_enabled == 1) {
	// signal MAC that Msg3 was sent
	mac_xface->Msg3_transmitted(Mod_id,
				    CC_id,
				    frame_tx,
				    eNB_id);
      }
    } // Msg3_flag==1
    else {
      input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
      
      if (ue->mac_enabled==1) {
	//  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;
	  mac_xface->ue_get_sdu(Mod_id,
				CC_id,
				frame_tx,
				subframe_tx,
				eNB_id,
				ulsch_input_buffer,
				input_buffer_length,
				&access_mode);
	}
	
1460 1461
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
1462 1463 1464 1465 1466 1467
	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");
1468 1469
#endif
#endif
1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486
      }
      else {
	unsigned int taus(void);
	
	for (i=0; i<input_buffer_length; i++)
	  ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
	
      }
      
      start_meas(&ue->ulsch_encoding_stats);
      
      if (abstraction_flag==0) {
	
	if (ulsch_encoding(ulsch_input_buffer,
			   ue,
			   harq_pid,
			   eNB_id,
hbilel's avatar
hbilel committed
1487
			   proc->subframe_rx,
1488 1489
         ue->transmission_mode[eNB_id],0,
         Nbundled)!=0) {
1490 1491 1492 1493
	  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);
	  stop_meas(&ue->phy_proc_tx);
	  return;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1494
	}
1495 1496
      }
      
1497
#ifdef PHY_ABSTRACTION
1498
      else {
hbilel's avatar
hbilel committed
1499
	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0);
1500 1501
      }
      
1502
#endif
1503 1504 1505 1506 1507 1508
      stop_meas(&ue->ulsch_encoding_stats);
    }
    
    if (abstraction_flag == 0) {
      if (ue->mac_enabled==1) {
	pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
1509
	ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
1510 1511
      }
      else {
1512
	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1513
      }
1514
      ue->tx_total_RE[subframe_tx] = nb_rb*12;
1515
      
kaltenbe's avatar
kaltenbe committed
1516
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1517
      tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
1518 1519 1520
			  ue->tx_power_max_dBm,
			  ue->frame_parms.N_RB_UL,
			  nb_rb);
1521
#else
1522
      tx_amp = AMP;
1523 1524 1525
#endif
#if T_TRACER
      T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
1526
                    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));
1527
#endif
1528 1529
      LOG_D(PHY,"[UE  %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
	    Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540
      start_meas(&ue->ulsch_modulation_stats);
      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,
Raymond Knopp's avatar
 
Raymond Knopp committed
1541
			   tx_amp,
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
			   subframe_tx,
			   first_rb,
			   nb_rb,
			   aa);
      
      stop_meas(&ue->ulsch_modulation_stats);
    }
    
    if (abstraction_flag==1) {
      // clear SR
      ue->sr[subframe_tx]=0;
    }
  } // subframe_scheduling_flag==1
1555 1556 1557

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT);

1558
}
1559

hbilel's avatar
hbilel committed
1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586
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
1587 1588
    if (ue->mac_enabled==1)
    {
hbilel's avatar
hbilel committed
1589 1590 1591 1592
    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
1593 1594 1595 1596 1597
    }
    else
    {
        tx_amp = AMP;
    }
hbilel's avatar
hbilel committed
1598 1599 1600
#else
      tx_amp = AMP;
#endif
fnabet's avatar
fnabet committed
1601
    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
1602 1603 1604 1605 1606
            Po_SRS,
            ue->frame_parms.N_RB_UL,
            nb_rb_srs,
            tx_amp);

1607 1608 1609 1610 1611 1612 1613
    uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12;
    uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((subframe_tx*nsymb)+(nsymb-1));
    generate_srs(&ue->frame_parms, 
		 &ue->soundingrs_ul_config_dedicated[eNB_id], 
		 &ue->common_vars.txdataF[eNB_id][symbol_offset], 
		 tx_amp, 
		 subframe_tx);
hbilel's avatar
hbilel committed
1614 1615
  }
}
1616

Raymond Knopp's avatar
Raymond Knopp committed
1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639
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
    *len=4;
    return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
		    ue->transmission_mode[eNB_id]));
  }
  else { // Mode 1-1 feedback, later
    *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);
}
1640

1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667

void get_pucch_param(PHY_VARS_UE    *ue,
                     UE_rxtx_proc_t *proc,
                     uint8_t        *ack_payload,
                     PUCCH_FMT_t    format,
                     uint8_t        eNB_id,
                     uint8_t        SR,
                     uint8_t        cqi_report,
                     uint16_t       *pucch_resource,
                     uint8_t        *pucch_payload,
                     uint16_t       *plength)
{

    switch (format) {
    case pucch_format1:
    {
        pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex;
        pucch_payload[0]  = 0; // payload is ignored in case of format1
        pucch_payload[1]  = 0; // payload is ignored in case of format1
    }
    break;

    case pucch_format1a:
    case pucch_format1b:
    {
        pucch_resource[0] = get_n1_pucch(ue,
                                         proc,
hbilel's avatar
hbilel committed
1668
                                         ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
1669 1670 1671 1672
                                         eNB_id,
                                         ack_payload,
                                         SR);
        pucch_payload[0]  = ack_payload[0];
hbilel's avatar
hbilel committed
1673 1674
        pucch_payload[1]  = ack_payload[1];
        //pucch_payload[1]  = 1;
1675 1676 1677 1678 1679 1680 1681 1682
    }
    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
1683
            pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int*)plength);
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699
        }
        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;
    }
}

1700
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1701 1702


1703
  uint8_t  pucch_ack_payload[2];
Cedric Roux's avatar
Cedric Roux committed
1704
  uint8_t  n2_pucch = -1;
1705
  uint16_t pucch_resource;
1706 1707
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
Raymond Knopp's avatar
Raymond Knopp committed
1708

1709 1710 1711
  uint8_t  SR_payload;
  uint8_t  pucch_payload[2];
  uint16_t len;
Raymond Knopp's avatar
Raymond Knopp committed
1712

1713 1714 1715 1716 1717 1718
  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;
1719
  int16_t Po_PUCCH;
1720 1721 1722 1723 1724
  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;
1725

1726 1727
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
  
hbilel's avatar
hbilel committed
1728
  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
1729 1730 1731 1732 1733 1734

  // 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
  */
1735 1736 1737 1738 1739 1740 1741 1742

  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);
1743
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
1744 1745 1746
      return;
  }

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

1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760
  bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
  
  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;
    LOG_D(PHY,"[UE] PUCCH 1a\n");
  } else {
    format = pucch_format1b;
    LOG_D(PHY,"[UE] PUCCH 1b\n");
  }
  
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
  // Part - I
  // Collect feedback that should be transmitted at this subframe
  // - SR
  // - ACK/NACK
  // - CQI
  // - RI

  SR_payload = 0;
  if (is_SR_TXOp(ue,proc,eNB_id)==1)
  {
      if (ue->mac_enabled==1) {
          SR_payload = mac_xface->ue_get_SR(Mod_id,
                  CC_id,
                  frame_tx,
                  eNB_id,
hbilel's avatar
hbilel committed
1776
                  ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti,
1777 1778 1779 1780 1781
                  subframe_tx); // subframe used for meas gap
      }
      else {
          SR_payload = 1;
      }
1782
  }
Raymond Knopp's avatar
Raymond Knopp committed
1783

1784
  ack_status_cw0 = reset_ack(&ue->frame_parms,
hbilel's avatar
hbilel committed
1785
                       ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
1786 1787 1788
                       subframe_tx,
                       pucch_ack_payload,
                       0);
1789

1790
  ack_status_cw1 = reset_ack(&ue->frame_parms,
hbilel's avatar
hbilel committed
1791
                       ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack,
1792 1793 1794
                       subframe_tx,
                       pucch_ack_payload,
                       1);
Raymond Knopp's avatar
Raymond Knopp committed
1795

1796
  nb_cw = ack_status_cw0 + ack_status_cw1;
Raymond Knopp's avatar
Raymond Knopp committed
1797

1798 1799
  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
1800

1801 1802
  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
1803

1804 1805 1806 1807
  // Part - II
  // if nothing to report ==> exit function
  if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0))
  {
1808 1809
      LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n",
            frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status);
1810 1811
      return;
  }
Raymond Knopp's avatar
Raymond Knopp committed
1812

1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829
  // Part - III
  // Decide which PUCCH format should be used if needed
  format = get_pucch_format(frame_parms->frame_type,
                            frame_parms->Ncp,
                            SR_payload,
                            nb_cw,
                            cqi_status,
                            ri_status);
  // Determine PUCCH resources and payload: mandatory for pucch encoding
  get_pucch_param(ue,
                  proc,
                  pucch_ack_payload,
                  format,
                  eNB_id,
                  SR_payload,
                  cqi_status,
                  &pucch_resource,
hbilel's avatar
hbilel committed
1830
                  (uint8_t *)&pucch_payload,
1831 1832
                  &len);

1833
  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
gabrielC's avatar
gabrielC committed
1834
          frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845


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

  switch (format) {
  case pucch_format1:
  case pucch_format1a:
  case pucch_format1b:
  {
Raymond Knopp's avatar
Raymond Knopp committed
1846
      if (ue->mac_enabled == 1) {
1847
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
1848 1849
      }
      else {
1850
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
1851 1852 1853
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
1854

Raymond Knopp's avatar
Raymond Knopp committed
1855
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1856 1857 1858 1859
      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
1860 1861
#else
      tx_amp = AMP;
1862 1863 1864
#endif
#if T_TRACER
      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
hbilel's avatar
hbilel committed
1865
              T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
Raymond Knopp's avatar
Raymond Knopp committed
1866
#endif
1867 1868
      if(format == pucch_format1)
      {
1869
          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",
1870
                  Mod_id,
hbilel's avatar
hbilel committed
1871
                  ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
1872
                  frame_tx%1024, subframe_tx,
1873 1874 1875 1876 1877 1878 1879 1880
                  frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                  isShortenPucch,
                  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
                  Po_PUCCH);
      }
      else
      {
          if (SR_payload>0) {
1881
              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",
1882
                      Mod_id,
hbilel's avatar
hbilel committed
1883
                      ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
1884 1885 1886 1887 1888 1889 1890 1891 1892 1893
                      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 {
1894
              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",
1895
                      Mod_id,
hbilel's avatar
hbilel committed
1896
                      ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906
                      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);
          }
      }
1907

1908 1909 1910
#if T_TRACER
      if(pucch_payload[0])
      {
hbilel's avatar
hbilel committed
1911 1912
          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
                  T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
1913 1914 1915
      }
      else
      {
hbilel's avatar
hbilel committed
1916 1917
          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
                  T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
1918 1919
      }
#endif
1920

1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946
      if (abstraction_flag == 0) {

          generate_pucch1x(ue->common_vars.txdataF,
                  &ue->frame_parms,
                  ue->ncs_cell,
                  format,
                  &ue->pucch_config_dedicated[eNB_id],
                  pucch_resource,
                  isShortenPucch,  // shortened format
                  pucch_payload,
                  tx_amp,
                  subframe_tx);

      } else {
#ifdef PHY_ABSTRACTION
          LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
          generate_pucch_emul(ue,
                  proc,
                  format,
                  ue->frame_parms.pucch_config_common.nCS_AN,
                  pucch_payload,
                  SR_payload);
#endif
      }
  }
  break;
1947

Raymond Knopp's avatar
Raymond Knopp committed
1948

1949 1950
  case pucch_format2:
  {
Raymond Knopp's avatar
Raymond Knopp committed
1951
      if (ue->mac_enabled == 1) {
1952
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
1953 1954
      }
      else {
1955
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
1956 1957 1958
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
1959

Raymond Knopp's avatar
Raymond Knopp committed
1960 1961
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
      tx_amp =  get_tx_amp(Po_PUCCH,
1962 1963 1964
              ue->tx_power_max_dBm,
              ue->frame_parms.N_RB_UL,
              1);
Raymond Knopp's avatar
Raymond Knopp committed
1965 1966 1967
#else
      tx_amp = AMP;
#endif
1968 1969
#if T_TRACER
      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
hbilel's avatar
hbilel committed
1970
              T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
1971
#endif
Raymond Knopp's avatar
Raymond Knopp committed
1972

1973
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
1974
              Mod_id,
hbilel's avatar
hbilel committed
1975
              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
1976 1977 1978 1979 1980
              frame_tx%1024, subframe_tx,
              n2_pucch,
              Po_PUCCH,
              isShortenPucch,
              tx_amp);
Raymond Knopp's avatar
Raymond Knopp committed
1981 1982

      generate_pucch2x(ue->common_vars.txdataF,
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992
              &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,
hbilel's avatar
hbilel committed
1993
              ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti);
1994 1995 1996 1997 1998 1999
  }
  break;

  case pucch_format2a:
      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
              Mod_id,
hbilel's avatar
hbilel committed
2000
              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
2001 2002 2003 2004 2005
              frame_tx%1024, subframe_tx);
      break;
  case pucch_format2b:
      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
              Mod_id,
hbilel's avatar
hbilel committed
2006
              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
2007 2008 2009 2010
              frame_tx%1024, subframe_tx);
      break;
  default:
      break;
Raymond Knopp's avatar
Raymond Knopp committed
2011
  }
2012 2013 2014

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);

2015
}
2016

2017 2018
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,relaying_type_t r_type) {
  
2019

2020
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2021
  //int32_t ulsch_start=0;
2022 2023 2024
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  unsigned int aa;
2025
  uint8_t isSubframeSRS;
2026

2027
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
2028

2029
#if T_TRACER
hbilel's avatar
hbilel committed
2030
  T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx));
2031
#endif
2032

2033
  ue->generate_ul_signal[eNB_id] = 0;
2034

2035
  start_meas(&ue->phy_proc_tx);
2036

2037 2038
#ifdef EMOS
  //phy_procedures_emos_UE_TX(next_slot);
2039 2040
#endif

2041
  ue->tx_power_dBm[subframe_tx]=-127;
2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
      
  if (abstraction_flag==0) {
    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));
    }
  }
      
  if (ue->UE_mode[eNB_id] != PRACH) {
fnabet's avatar
fnabet committed
2052
    // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding
2053 2054 2055
    isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx);

    ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS);
2056

2057
    ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
2058

2059 2060
  }
  	  
hbilel's avatar
hbilel committed
2061 2062 2063 2064 2065
  if (ue->UE_mode[eNB_id] == PUSCH) {
      // 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);
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102
  } // UE_mode==PUSCH
	
  	
#ifdef CBA
	
  if ((ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag >= 1) &&
      (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == CBA_ACTIVE)) {
    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag=0; //-=1
    //  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
    //cba_mcs=ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs;
    input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
    access_mode=CBA_ACCESS;
	  
    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: CBA num dci %d\n",
	  Mod_id,frame_tx,subframe_tx,
	  ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]);
	  
    mac_xface->ue_get_sdu(Mod_id,
			  CC_id,
			  frame_tx,
			  subframe_tx,
			  eNB_id,
			  ulsch_input_buffer,
			  input_buffer_length,
			  &access_mode);
	  
    ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]=0;
	  
    if (access_mode > UNKNOWN_ACCESS) {
	    
      if (abstraction_flag==0) {
	if (ulsch_encoding(ulsch_input_buffer,
			   ue,
			   harq_pid,
			   eNB_id,
hbilel's avatar
hbilel committed
2103
			   proc->subframe_rx,
2104 2105 2106 2107 2108 2109 2110 2111 2112
			   ue->transmission_mode[eNB_id],0,
			   0)!=0) {  //  Nbundled, to be updated!!!!
	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
	  return;
	}
      }
	    
#ifdef PHY_ABSTRACTION
      else {
hbilel's avatar
hbilel committed
2113
	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0);
2114 2115
      }
	    
2116
#endif
2117 2118 2119 2120 2121 2122 2123 2124 2125
    } else {
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
      //reset_cba_uci(ue->ulsch[eNB_id]->o);
      LOG_N(PHY,"[UE %d] Frame %d, subframe %d: CBA transmission cancelled or postponed\n",
	    Mod_id, frame_tx,subframe_tx);
    }
  }
	
#endif // end CBA
2126

2127 2128
  	
  if (abstraction_flag == 0) {
hbilel's avatar
hbilel committed
2129
    ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
2130 2131 2132 2133 2134 2135 2136
  } // mode != PRACH
    
      
  if ((ue->UE_mode[eNB_id] == PRACH) && 
      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
	
    // check if we have PRACH opportunity
2137

2138
    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
2139

2140
      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
2141
    }
2142 2143 2144 2145 2146
  } // mode is PRACH
  else {
    ue->generate_prach=0;
  }
    
2147
  // reset DL ACK/NACK status
2148 2149 2150 2151 2152 2153 2154 2155
  if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0] != NULL)
    reset_ack(&ue->frame_parms,
               ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
               subframe_tx,
               ue->ulsch[eNB_id]->o_ACK,0);

  if (ue->dlsch_SI[eNB_id] != NULL)
    reset_ack(&ue->frame_parms,
2156 2157 2158
             ue->dlsch_SI[eNB_id]->harq_ack,
             subframe_tx,
             ue->ulsch[eNB_id]->o_ACK,0);
2159

2160
      
2161
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
2162
  stop_meas(&ue->phy_proc_tx);
2163 2164
}

2165
void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
2166
{
2167
  int aa;//i,aa;
2168
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2169
  
2170
  if (abstraction_flag==0) {
2171
    
2172
    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
2173
#if defined(EXMIMO) //this is the EXPRESS MIMO case
2174 2175
      int i;
      // set the whole tx buffer to RX
2176
      for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
2177 2178
	ue->common_vars.txdata[aa][i] = 0x00010001;
      
2179
#else //this is the normal case
2180
      memset(&ue->common_vars.txdata[aa][0],0,
2181
	     (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
2182
#endif //else EXMIMO
2183
      
2184 2185 2186 2187
    }
  }
}

2188 2189 2190 2191 2192
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,
    uint16_t slot, // slot index of each radio frame [0..19]    
    uint8_t abstraction_flag,runmode_t mode)
2193
{
2194
  
2195
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
Raymond Knopp's avatar
 
Raymond Knopp committed
2196

2197
  int subframe_rx = proc->subframe_rx;
2198

2199
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
2200 2201

  if (l==0) {
2202
    // UE measurements on symbol 0
2203
    if (abstraction_flag==0) {
2204
      LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
2205

2206
      lte_ue_measurements(ue,
2207 2208
			  (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,
2209
			  0,subframe_rx);
2210
    } else {
2211
      lte_ue_measurements(ue,
2212 2213
			  0,
			  0,
2214 2215
			  1,
      subframe_rx);
2216
    }
2217 2218 2219 2220 2221
#if T_TRACER
    if(slot == 0)
      T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
                             T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
                             T_INT((int)ue->measurements.rx_rssi_dBm[0]),
2222 2223 2224 2225 2226
                             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));
2227
#endif
2228 2229
  }

2230
  if (l==(6-ue->frame_parms.Ncp)) {
2231
	
2232
    // make sure we have signal from PSS/SSS for N0 measurement
2233

2234
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
2235
    ue_rrc_measurements(ue,
2236
			slot,
2237
			abstraction_flag);
2238
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
2239

Raymond Knopp's avatar
 
Raymond Knopp committed
2240
    if (abstraction_flag==1)
2241
      ue->sinr_eff =  sinr_eff_cqi_calc(ue, 0, subframe_rx);
2242

2243
  }
2244

2245
  if ((subframe_rx==0) && (slot == 0) && (l==(4-frame_parms->Ncp))) {
2246

2247
    // AGC
Raymond Knopp's avatar
 
Raymond Knopp committed
2248

2249
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2250

2251
#ifndef OAI_USRP
kaltenbe's avatar
kaltenbe committed
2252 2253
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
2254
    phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0);
kaltenbe's avatar
kaltenbe committed
2255 2256
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2257
#endif
2258

2259
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
2260

2261
    eNB_id = 0;
2262
    
2263 2264 2265 2266 2267
    if (abstraction_flag == 0) {
      if (ue->no_timing_correction==0)
	lte_adjust_synch(&ue->frame_parms,
			 ue,
			 eNB_id,
2268
			 subframe_rx,
2269 2270 2271
			 0,
			 16384);
    }      
2272

2273
  }
2274

2275
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
2276 2277 2278
}

#ifdef EMOS
2279
void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
2280
{
2281

2282 2283 2284
  uint8_t i,j;
  //uint16_t last_slot_emos;
  uint32_t bytes;
2285
  int Mod_id = ue->Mod_id;
2286 2287

  /*
2288
    if (last_slot<2)
2289
    last_slot_emos = last_slot;
2290
    else if (last_slot>9)
2291
    last_slot_emos = last_slot - 8;
2292
    else {
2293 2294
    LOG_E(PHY,"emos rx last_slot_emos %d, last_slot %d\n", last_slot_emos,last_slot);
    mac_xface->macphy_exit("should never happen");
2295
    }
2296 2297 2298
  */

#ifdef EMOS_CHANNEL
2299

2300
  if ((last_slot==10) || (last_slot==11)) {
2301 2302
    for (i=0; i<ue->frame_parms.nb_antennas_rx; i++)
      for (j=0; j<ue->frame_parms.nb_antennas_tx; j++) {
2303 2304 2305 2306 2307 2308 2309 2310
	// first OFDM symbol with pilots
	memcpy(&emos_dump_UE.channel[i][j][(last_slot%2)*2*ue->frame_parms.ofdm_symbol_size],
	       &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][0],
	       ue->frame_parms.ofdm_symbol_size*sizeof(int));
	// second OFDM symbol with pilots
	memcpy(&emos_dump_UE.channel[i][j][((last_slot%2)*2+1)*ue->frame_parms.ofdm_symbol_size],
	       &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][(ue->frame_parms.Ncp == 0 ? 4 : 3)*ue->frame_parms.ofdm_symbol_size],
	       ue->frame_parms.ofdm_symbol_size*sizeof(int));
2311 2312
      }
  }
2313

2314
#endif
2315

2316 2317
  if (last_slot==0) {
    emos_dump_UE.timestamp = rt_get_time_ns();
2318
    emos_dump_UE.frame_rx = proc->frame_rx;
2319 2320 2321 2322 2323 2324
    emos_dump_UE.UE_mode = ue->UE_mode[eNB_id];
    emos_dump_UE.mimo_mode = ue->transmission_mode[eNB_id];
    emos_dump_UE.freq_offset = ue->common_vars.freq_offset;
    emos_dump_UE.timing_advance = ue->timing_advance;
    emos_dump_UE.timing_offset  = ue->rx_offset;
    emos_dump_UE.rx_total_gain_dB = ue->rx_total_gain_dB;
2325
    emos_dump_UE.eNb_id = eNB_id;
2326
    memcpy(&emos_dump_UE.PHY_measurements,&measurements,sizeof(PHY_MEASUREMENTS));
2327
  }
2328

2329
  if (last_slot==1) {
2330 2331 2332 2333
    emos_dump_UE.pbch_errors = ue->pbch_vars[eNB_id]->pdu_errors;
    emos_dump_UE.pbch_errors_last = ue->pbch_vars[eNB_id]->pdu_errors_last;
    emos_dump_UE.pbch_errors_conseq = ue->pbch_vars[eNB_id]->pdu_errors_conseq;
    emos_dump_UE.pbch_fer = ue->pbch_vars[eNB_id]->pdu_fer;
2334
  }
2335

2336
  if (last_slot==19) {
2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347
    emos_dump_UE.dlsch_errors = ue->dlsch_errors[eNB_id];
    emos_dump_UE.dlsch_errors_last = ue->dlsch_errors_last[eNB_id];
    emos_dump_UE.dlsch_received = ue->dlsch_received[eNB_id];
    emos_dump_UE.dlsch_received_last = ue->dlsch_received_last[eNB_id];
    emos_dump_UE.dlsch_fer = ue->dlsch_fer[eNB_id];
    emos_dump_UE.dlsch_cntl_errors = ue->dlsch_SI_errors[eNB_id];
    emos_dump_UE.dlsch_ra_errors = ue->dlsch_ra_errors[eNB_id];
    emos_dump_UE.total_TBS = ue->total_TBS[eNB_id];
    emos_dump_UE.total_TBS_last = ue->total_TBS_last[eNB_id];
    emos_dump_UE.bitrate = ue->bitrate[eNB_id];
    emos_dump_UE.total_received_bits = ue->total_received_bits[eNB_id];
hbilel's avatar
hbilel committed
2348 2349
    emos_dump_UE.pmi_saved = ue->dlsch[subframe&0x1][eNB_id][0]->pmi_alloc;
    emos_dump_UE.mcs = ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mcs;
2350 2351 2352
    emos_dump_UE.use_ia_receiver = openair_daq_vars.use_ia_receiver;

    bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE));
2353

2354
    if (bytes!=sizeof(fifo_dump_emos_UE)) {
2355
      LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot);
2356
    } else {
2357 2358
      if (proc->frame_rx%100==0) {
	LOG_I(PHY,"[UE  %d] frame %d, slot %d, Writing %d bytes EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot, bytes);
2359 2360 2361
      }
    }
  }
2362

2363 2364 2365 2366
}
#endif


2367
void restart_phy(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag)
2368
{
2369

2370 2371
  //  uint8_t last_slot;
  uint8_t i;
2372
  LOG_I(PHY,"[UE  %d] frame %d, slot %d, restarting PHY!\n",ue->Mod_id,proc->frame_rx,proc->subframe_rx);
2373
  mac_xface->macphy_exit("restart_phy called");
2374
  //   first_run = 1;
2375

2376
  if (abstraction_flag ==0 ) {
2377
    ue->UE_mode[eNB_id] = NOT_SYNCHED;
2378
  } else {
2379 2380
    ue->UE_mode[eNB_id] = PRACH;
    ue->prach_resources[eNB_id]=NULL;
2381
  }
2382

2383 2384
  proc->frame_rx = -1;
  proc->frame_tx = -1;
2385 2386
  //  ue->synch_wait_cnt=0;
  //  ue->sched_cnt=-1;
2387

2388 2389
  ue->pbch_vars[eNB_id]->pdu_errors_conseq=0;
  ue->pbch_vars[eNB_id]->pdu_errors=0;
2390

hbilel's avatar
hbilel committed
2391 2392 2393 2394 2395 2396 2397 2398 2399
  ue->pdcch_vars[0][eNB_id]->dci_errors = 0;
  ue->pdcch_vars[0][eNB_id]->dci_missed = 0;
  ue->pdcch_vars[0][eNB_id]->dci_false  = 0;
  ue->pdcch_vars[0][eNB_id]->dci_received = 0;

  ue->pdcch_vars[1][eNB_id]->dci_errors = 0;
  ue->pdcch_vars[1][eNB_id]->dci_missed = 0;
  ue->pdcch_vars[1][eNB_id]->dci_false  = 0;
  ue->pdcch_vars[1][eNB_id]->dci_received = 0;
2400

2401 2402 2403 2404 2405 2406 2407
  ue->dlsch_errors[eNB_id] = 0;
  ue->dlsch_errors_last[eNB_id] = 0;
  ue->dlsch_received[eNB_id] = 0;
  ue->dlsch_received_last[eNB_id] = 0;
  ue->dlsch_fer[eNB_id] = 0;
  ue->dlsch_SI_received[eNB_id] = 0;
  ue->dlsch_ra_received[eNB_id] = 0;
2408
  ue->dlsch_p_received[eNB_id] = 0;
2409 2410
  ue->dlsch_SI_errors[eNB_id] = 0;
  ue->dlsch_ra_errors[eNB_id] = 0;
2411
  ue->dlsch_p_errors[eNB_id] = 0;
2412

2413
  ue->dlsch_mch_received[eNB_id] = 0;
2414 2415

  for (i=0; i < MAX_MBSFN_AREA ; i ++) {
2416 2417 2418 2419 2420 2421 2422
    ue->dlsch_mch_received_sf[i][eNB_id] = 0;
    ue->dlsch_mcch_received[i][eNB_id] = 0;
    ue->dlsch_mtch_received[i][eNB_id] = 0;
    ue->dlsch_mcch_errors[i][eNB_id] = 0;
    ue->dlsch_mtch_errors[i][eNB_id] = 0;
    ue->dlsch_mcch_trials[i][eNB_id] = 0;
    ue->dlsch_mtch_trials[i][eNB_id] = 0;
2423 2424
  }

2425 2426 2427 2428
  //ue->total_TBS[eNB_id] = 0;
  //ue->total_TBS_last[eNB_id] = 0;
  //ue->bitrate[eNB_id] = 0;
  //ue->total_received_bits[eNB_id] = 0;
2429 2430 2431
}


2432
void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag)
2433
{
2434 2435 2436

  //  int i;
  int pbch_tx_ant=0;
2437 2438 2439 2440
  uint8_t pbch_phase;
  uint16_t frame_tx;
  static uint8_t first_run = 1;
  uint8_t pbch_trials = 0;
2441

2442
  DevAssert(ue);
2443 2444 2445

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

2447
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
2448

Raymond Knopp's avatar
 
Raymond Knopp committed
2449
  pbch_phase=(frame_rx%4);
2450

2451 2452
  if (pbch_phase>=4)
    pbch_phase=0;
2453 2454 2455

  for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
    //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
2456
    //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);
2457
    if (abstraction_flag == 0) {
2458
      pbch_tx_ant = rx_pbch(&ue->common_vars,
2459 2460 2461 2462 2463 2464
			    ue->pbch_vars[eNB_id],
			    &ue->frame_parms,
			    eNB_id,
			    ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
			    ue->high_speed_flag,
			    pbch_phase);
2465 2466 2467 2468



    }
2469

2470 2471
#ifdef PHY_ABSTRACTION
    else {
2472
      pbch_tx_ant = rx_pbch_emul(ue,
2473 2474
				 eNB_id,
				 pbch_phase);
2475
    }
2476

2477 2478 2479 2480 2481
#endif

    if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {
      break;
    }
2482

2483
    pbch_phase++;
2484

2485 2486 2487 2488 2489 2490 2491 2492
    if (pbch_phase>=4)
      pbch_phase=0;
  }



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

2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503
    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);
    }

2504
    if (pbch_tx_ant>2) {
2505
      LOG_W(PHY,"[openair][SCHED][SYNCH] PBCH decoding: pbch_tx_ant>2 not supported\n");
2506
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2507 2508 2509 2510
      return;
    }


2511 2512 2513
    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));
2514 2515
    frame_tx += pbch_phase;

2516 2517 2518
    if (ue->mac_enabled==1) {
      mac_xface->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
2519 2520
    }
    
2521 2522
#ifdef EMOS
    //emos_dump_UE.frame_tx = frame_tx;
2523
    //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1];
2524 2525 2526 2527
#endif

    if (first_run) {
      first_run = 0;
2528 2529 2530 2531 2532 2533

      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
      proc->frame_tx = proc->frame_rx;
      ue->proc.proc_rxtx[1].frame_rx = proc->frame_rx;
      ue->proc.proc_rxtx[1].frame_tx = proc->frame_tx;
      LOG_I(PHY,"[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",
2534 2535 2536 2537 2538
	    ue->Mod_id,
	    frame_rx,
	    subframe_rx,
	    pbch_tx_ant,
	    frame_tx,
2539 2540 2541
	    pbch_phase,
	    ue->rx_offset,
	    proc->frame_rx);
2542
      frame_rx = proc->frame_rx;
2543
      
2544
    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
2545
      //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
Cedric Roux's avatar
Cedric Roux committed
2546
      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",
2547 2548 2549 2550 2551 2552 2553 2554 2555
	    ue->Mod_id,
	    proc->frame_rx,
	    subframe_rx,
	    pbch_tx_ant,
	    frame_tx,
	    frame_rx & 0x03FF,
	    pbch_phase);

      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
2556
      ue->proc.proc_rxtx[1].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
2557
      proc->frame_tx = proc->frame_rx;
2558
      ue->proc.proc_rxtx[1].frame_tx = proc->frame_rx;
2559 2560
      frame_rx = proc->frame_rx;

2561
    }
2562

2563
#ifdef DEBUG_PHY_PROC
2564 2565 2566 2567 2568 2569 2570 2571 2572 2573
    LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): mode1_flag %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
	  ue->Mod_id,
	  frame_rx,
	  subframe_rx,
	  ue->frame_parms.mode1_flag,
	  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);
2574
#endif
2575

2576
  } else { 
2577
    /*
2578
    LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
2579
	  ue->Mod_id,frame_rx, subframe_rx);
2580

2581 2582 2583 2584 2585
    LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);


    write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1);

2586 2587
    write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
    write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
2588

2589
    write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
2590 2591 2592 2593 2594
    write_output("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1);
    write_output("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1);
    write_output("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4);
    exit(-1);
    */
2595

2596 2597 2598 2599
    ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
    ue->pbch_vars[eNB_id]->pdu_errors++;
    if (ue->mac_enabled == 1) {
      mac_xface->out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2600 2601
    }
    else{
2602
      if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2603 2604 2605
	LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
	mac_xface->macphy_exit("More that 100 consecutive PBCH errors!");
      }
2606
    }
2607 2608
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
2609
  if (frame_rx % 100 == 0) {
2610 2611
    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;
2612
  }
2613 2614

#ifdef DEBUG_PHY_PROC
2615
  LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
2616 2617 2618
	ue->Mod_id,frame_rx, subframe_rx,
	ue->pbch_vars[eNB_id]->pdu_errors,
	ue->pbch_vars[eNB_id]->pdu_errors_conseq);
2619
#endif
2620
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2621 2622
}

2623
int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag)
2624
{
2625 2626

  unsigned int dci_cnt=0, i;
2627

2628 2629
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2630
  DCI_ALLOC_t dci_alloc_rx[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
2631

2632

2633 2634 2635 2636 2637 2638
#ifdef PHY_ABSTRACTION
  int CC_id;
  int UE_id;
  uint8_t harq_pid;
#endif

2639
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
2640
  start_meas(&ue->dlsch_rx_pdcch_stats);
2641

2642 2643
  //  if (subframe_rx != 5)
  //    return 0;
2644 2645
  if (abstraction_flag == 0)  {

2646
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
hbilel's avatar
hbilel committed
2647
    rx_pdcch(ue,
2648
	     proc->frame_rx,
2649 2650 2651 2652 2653
	     subframe_rx,
	     eNB_id,
	     (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
	     ue->high_speed_flag,
	     ue->is_secondary_ue);
2654 2655


2656 2657
    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);
2658
    dci_cnt = dci_decoding_procedure(ue,
2659 2660 2661 2662
				     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);
2663
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
2664
    //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d PHICH RX\n",ue->Mod_id,frame_rx,subframe_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2665

2666
    if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
2667
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
2668 2669
      rx_phich(ue,proc,
	       subframe_rx,eNB_id);
2670
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
2671 2672
    }
  }
2673

2674 2675
#ifdef PHY_ABSTRACTION
  else {
2676 2677
    for (i=0; i<NB_eNB_INST; i++) {
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
2678 2679
	if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
	  break;
2680

2681
      if (CC_id < MAX_NUM_CCs)
2682
	break;
2683
    }
2684

2685
    if (i==NB_eNB_INST) {
2686
      LOG_E(PHY,"[UE  %d] phy_procedures_lte_ue.c: FATAL : Could not find attached eNB for DCI emulation (Nid_cell %d)!!!!\n",ue->Mod_id,ue->frame_parms.Nid_cell);
2687
      mac_xface->macphy_exit("Could not find attached eNB for DCI emulation");
2688
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
2689 2690
      return(-1);
    }
2691

2692
    LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
hbilel's avatar
hbilel committed
2693
    dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars[subframe_rx&1],
2694 2695 2696 2697 2698
					  PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[subframe_rx&1],
					  PHY_vars_eNB_g[i][CC_id]->num_common_dci[subframe_rx&1],
					  PHY_vars_eNB_g[i][CC_id]->dci_alloc[subframe_rx&1],
					  dci_alloc_rx,
					  eNB_id);
2699
    //    printf("DCI: dci_cnt %d\n",dci_cnt);
hbilel's avatar
hbilel committed
2700
    UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
2701

2702
    if (UE_id>=0) {
2703
      //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
2704
      if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715
	harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,subframe_rx);

	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
	  // ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
	  ue->ulsch_Msg3_active[eNB_id] = 0;
	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
	  LOG_D(PHY,"Msg3 inactive\n");

	} // harq_pid is ACTIVE
2716 2717 2718
      } // This is a PHICH subframe
    } // UE_id exists
  }
2719

2720 2721
#endif

2722

2723
  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
2724 2725 2726 2727 2728
       ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],
       dci_cnt,
       dci_alloc_rx[0].rnti,
       ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
       dci_alloc_rx[0].format );
2729

hbilel's avatar
hbilel committed
2730
  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->dci_received += dci_cnt;
2731

2732
#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
2733
  //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt;
2734 2735
#endif

2736 2737 2738
  for (i=0; i<dci_cnt; i++) {


2739

2740
    if ((ue->UE_mode[eNB_id]>PRACH) &&
hbilel's avatar
hbilel committed
2741
	(dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti) &&
2742 2743
	(dci_alloc_rx[i].format != format0)) {
      
2744

2745
      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
2746
	    ue->Mod_id,dci_alloc_rx[i].rnti,
2747
	    frame_rx%1024,subframe_rx,
2748
	    dci_alloc_rx[i].format,
hbilel's avatar
hbilel committed
2749 2750
	    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
	    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->nCCE[subframe_rx],
2751
	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
2752 2753 2754 2755




2756
      
2757
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2758
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2759 2760
	  (generate_ue_dlsch_params_from_dci(frame_rx,
					     subframe_rx,
2761
					     (void *)&dci_alloc_rx[i].dci_pdu,
hbilel's avatar
hbilel committed
2762
					     ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
2763
					     dci_alloc_rx[i].format,
hbilel's avatar
hbilel committed
2764
					     ue->dlsch[subframe_rx&0x1][eNB_id],
2765 2766
					     &ue->frame_parms,
					     ue->pdsch_config_dedicated,
2767 2768
					     SI_RNTI,
					     0,
2769
					     P_RNTI,
2770
					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
hbilel's avatar
hbilel committed
2771
					     ue->pdcch_vars[0&0x1][eNB_id]->crnti_is_temporary? ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti: 0)==0)) {
2772

hbilel's avatar
hbilel committed
2773 2774 2775
          // update TPC for PUCCH
          if((dci_alloc_rx[i].format == format1)   ||
              (dci_alloc_rx[i].format == format1A) ||
2776
              (dci_alloc_rx[i].format == format1B) ||
hbilel's avatar
hbilel committed
2777
              (dci_alloc_rx[i].format == format2)  ||
2778 2779
              (dci_alloc_rx[i].format == format2A) ||
              (dci_alloc_rx[i].format == format2B))
hbilel's avatar
hbilel committed
2780
          {
hbilel's avatar
hbilel committed
2781
            ue->dlsch[subframe_rx&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH;
hbilel's avatar
hbilel committed
2782 2783
          }

2784
	ue->dlsch_received[eNB_id]++;
2785
	
2786
#ifdef DEBUG_PHY_PROC
2787 2788
	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]);
hbilel's avatar
hbilel committed
2789
	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_rx&0x1][eNB_id][0]->active);
2790
#endif
2791
	
2792 2793
	// we received a CRNTI, so we're in PUSCH
	if (ue->UE_mode[eNB_id] != PUSCH) {
2794
#ifdef DEBUG_PHY_PROC
hbilel's avatar
hbilel committed
2795
	  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);
2796
#endif
2797 2798 2799 2800
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	  ue->UE_mode[eNB_id] = PUSCH;
	  //mac_xface->macphy_exit("Connected. Exiting\n");
	}
2801
      } else {
2802 2803
	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]);
2804 2805 2806
      }
    }

2807
    else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
2808
	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2809

2810
#ifdef DEBUG_PHY_PROC
2811
      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);
2812 2813
#endif

2814

2815 2816
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2817 2818 2819 2820 2821 2822 2823 2824
					    (void *)&dci_alloc_rx[i].dci_pdu,
					    SI_RNTI,
					    dci_alloc_rx[i].format,
					    &ue->dlsch_SI[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    0,
2825
					    P_RNTI,
2826 2827
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
              0)==0) {
2828 2829

	ue->dlsch_SI_received[eNB_id]++;
2830 2831
 

2832
	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");
2833
	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2834 2835 2836

      }
    }
2837

2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848
    else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {

#ifdef DEBUG_PHY_PROC
      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);
#endif


      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
					    (void *)&dci_alloc_rx[i].dci_pdu,
2849
						P_RNTI,
2850 2851 2852 2853 2854 2855
					    dci_alloc_rx[i].format,
					    &ue->dlsch_SI[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    0,
2856
					    P_RNTI,
2857 2858
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
2859 2860 2861 2862 2863 2864 2865 2866 2867 2868

	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]);

      }
    }

2869
    else if ((ue->prach_resources[eNB_id]) &&
2870 2871
	     (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
2872

2873
#ifdef DEBUG_PHY_PROC
2874
      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);
2875 2876

      //if (((frame_rx%100) == 0) || (frame_rx < 20))
2877
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2878 2879 2880 2881
      //mac_xface->macphy_exit("so far so good...\n");
#endif


2882 2883
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2884 2885 2886 2887 2888 2889 2890 2891
					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
					    ue->prach_resources[eNB_id]->ra_RNTI,
					    format1A,
					    &ue->dlsch_ra[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    ue->prach_resources[eNB_id]->ra_RNTI,
2892
					    P_RNTI,
2893 2894
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
2895 2896

	ue->dlsch_ra_received[eNB_id]++;
2897

2898
#ifdef DEBUG_PHY_PROC
2899 2900
	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]);
2901
#endif
2902
      }
hbilel's avatar
hbilel committed
2903
    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti) &&
2904
	       (dci_alloc_rx[i].format == format0)) {
2905
#ifdef DEBUG_PHY_PROC
2906
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
2907
	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
2908 2909
#endif

2910 2911
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
2912

2913
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2914
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
hbilel's avatar
hbilel committed
2915
					     ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
2916 2917
					     subframe_rx,
					     format0,
2918
					     ue,
2919
					     proc,
2920 2921 2922 2923 2924 2925
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
2926

2927 2928
#if T_TRACER
    LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
2929 2930 2931 2932
    uint8_t harq_pid = subframe2harq_pid(frame_parms,
                                 pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,proc->subframe_rx),
                                 pdcch_alloc2ul_subframe(frame_parms,proc->subframe_rx));

hbilel's avatar
hbilel committed
2933
    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), T_INT(ue->Mod_id),
2934 2935 2936 2937 2938 2939
      T_INT(dci_alloc_rx[i].rnti), T_INT(harq_pid),
      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));
2940
#endif
2941
#ifdef DEBUG_PHY_PROC
2942
	LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
2943 2944
#endif

2945
      }
2946
    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
2947
	       (dci_alloc_rx[i].format == format0)) {
2948
      // UE could belong to more than one CBA group
2949
      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
2950
#ifdef DEBUG_PHY_PROC
2951
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
2952
	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
2953 2954 2955 2956
      /*
	if (((frame_rx%100) == 0) || (frame_rx < 20))
	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
      */
2957 2958
#endif

2959 2960
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
2961

2962
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2963
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
2964
					     ue->ulsch[eNB_id]->cba_rnti[0],
2965 2966
					     subframe_rx,
					     format0,
2967
					     ue,
2968
					     proc,
2969 2970 2971 2972 2973 2974
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
2975

2976
#ifdef DEBUG_PHY_PROC
2977
	LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
2978
#endif
2979
	ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
2980 2981 2982
      }
    }

2983 2984
    else {
#ifdef DEBUG_PHY_PROC
2985
      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,
hbilel's avatar
hbilel committed
2986
	    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
2987 2988
	    ue->ulsch[eNB_id]->cba_rnti[0],
	    dci_alloc_rx[i].format);
2989
      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2990 2991
#endif
    }
2992

2993
  }
2994

2995
  stop_meas(&ue->dlsch_rx_pdcch_stats);
2996
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
2997 2998 2999
  return(0);
}

3000

3001
void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
3002

3003
  int subframe_rx = proc->subframe_rx;
3004
  int frame_rx = proc->frame_rx;
3005
  int pmch_mcs=-1;
Cedric Roux's avatar
Cedric Roux committed
3006
#if defined(Rel10) || defined(Rel14)
3007
  int CC_id = ue->CC_id;
Cedric Roux's avatar
Cedric Roux committed
3008
#endif
3009 3010 3011 3012
  uint8_t sync_area=255;
  uint8_t mcch_active;
  int l;
  int ret=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3013

3014 3015 3016 3017 3018
  if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
    LOG_D(PHY,"ue calling pmch subframe ..\n ");
    
    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
	  ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
Cedric Roux's avatar
Cedric Roux committed
3019
#if defined(Rel10) || defined(Rel14)
3020 3021 3022 3023 3024 3025 3026 3027 3028 3029
    pmch_mcs = mac_xface->ue_query_mch(ue->Mod_id,
				       CC_id,
				       frame_rx,
				       subframe_rx,
				       eNB_id,
				       &sync_area,
				       &mcch_active);
    
#else
    pmch_mcs=-1;
3030
#endif
3031 3032 3033 3034
    
    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);
3035
      
3036 3037 3038 3039 3040 3041 3042 3043
      if (abstraction_flag == 0 ) {
	for (l=2; l<12; l++) {
	  
	  slot_fep_mbsfn(ue,
			 l,
			 subframe_rx,
			 0,0);//ue->rx_offset,0);
	}
3044

3045 3046 3047 3048 3049 3050
	for (l=2; l<12; l++) {
	  rx_pmch(ue,
		  0,
		  subframe_rx,
		  l);
	}
3051 3052


3053 3054 3055 3056 3057 3058
	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,
3059 3060 3061
						       frame_rx,
						       subframe_rx,
						       0);
3062 3063 3064 3065 3066 3067 3068 3069 3070 3071
	
	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],
3072
			     frame_rx,
3073 3074 3075 3076
			     subframe_rx,
			     0,
			     0,1);
      } else { // abstraction
3077
#ifdef PHY_ABSTRACTION
3078 3079 3080 3081
	ret = dlsch_decoding_emul(ue,
				  subframe_rx,
				  5, // PMCH
				  eNB_id);
3082
#endif
3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096
      }
      
      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
3097 3098
	      ue->Mod_id,
              frame_rx,subframe_rx,
3099 3100 3101 3102 3103 3104
	      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);
3105
#ifdef DEBUG_DLSCH
3106 3107 3108
	
	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]);
3109
	}
3110 3111
	
	LOG_T(PHY,"\n");
3112
#endif
3113 3114 3115 3116
	
	if (subframe_rx==9)
	  mac_xface->macphy_exit("Why are we exiting here?");
      } else { // decoding successful
Cedric Roux's avatar
Cedric Roux committed
3117
#if defined(Rel10) || defined(Rel14)
3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134
	
	if (mcch_active == 1) {
	  mac_xface->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);
	  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;
3135
	  }
3136 3137 3138
	  
	  
	}
Cedric Roux's avatar
Cedric Roux committed
3139
#endif // Rel10 || Rel14
3140 3141 3142 3143
      } // decoding sucessful
    } // pmch_mcs>=0
  } // is_pmch_subframe=true
}
3144

3145
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) {
3146

3147 3148 3149 3150 3151
  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;
3152

3153 3154
  if (dlsch0->active == 0)
    return;
3155

3156
  for (m=s0;m<=s1;m++) {
3157

3158 3159
    if (dlsch0 && (!dlsch1))  {
      harq_pid = dlsch0->current_harq_pid;
Cedric Roux's avatar
Cedric Roux committed
3160
      LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d\n",ue->Mod_id,subframe_rx,harq_pid);
3161 3162 3163 3164 3165 3166 3167 3168
	    
      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;
hbilel's avatar
hbilel committed
3169 3170 3171 3172 3173 3174 3175 3176
      }
      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 {
3177 3178 3179
	dual_stream_UE = 0;
	eNB_id_i = eNB_id+1;
	i_mod = 0;
3180
      }
3181

3182 3183 3184
      //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
3185
          if ((m==3) || (m==6) || (m==9) || (m==12))
3186 3187
            //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);
3188
        } else {
3189
          LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
3190
        }
3191
      }
3192
     
3193 3194
      if ((m==s0) && (m<4))
	first_symbol_flag = 1;
3195
      else
3196 3197 3198 3199 3200 3201 3202 3203
	first_symbol_flag = 0;

      start_meas(&ue->dlsch_llr_stats);
      // process DLSCH received in first slot
      rx_pdsch(ue,
	       pdsch,
	       eNB_id,
	       eNB_id_i,
3204
	       proc->frame_rx,
3205 3206 3207 3208 3209 3210 3211 3212
	       subframe_rx,  // subframe,
	       m,
	       first_symbol_flag,
	       dual_stream_UE,
	       i_mod,
	       dlsch0->current_harq_pid);
      stop_meas(&ue->dlsch_llr_stats);
    } // CRNTI active
3213
  }
3214
} 
3215

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

3218 3219 3220 3221 3222 3223
  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;
3224

3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241
  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
	ue->Mod_id,
	frame_rx,
	subframe_rx, ue->UE_mode[eNB_id]);
  
	
  if (ue->mac_enabled == 1) {
    if ((ue->UE_mode[eNB_id] != PUSCH) && 
	(ue->prach_resources[eNB_id]->Msg3!=NULL)) {
      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);
      
      timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
						 ue->CC_id,
						 frame_rx,
3242
						 ue->prach_resources[eNB_id]->ra_RNTI,
3243
						 dlsch0->harq_processes[0]->b,
hbilel's avatar
hbilel committed
3244
						 &ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
3245
						 ue->prach_resources[eNB_id]->ra_PreambleIndex);
3246 3247

      ue->pdcch_vars[(subframe_rx+1) & 0x1][eNB_id]->crnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti;
3248 3249 3250 3251
      
	    
      if (timing_advance!=0xffff) {
	      
3252 3253 3254 3255 3256 3257
	      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
              ue->Mod_id,
              frame_rx,
              subframe_rx,
              ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
              timing_advance);
3258
	      
3259
  // remember this c-rnti is still a tc-rnti
hbilel's avatar
hbilel committed
3260
  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti_is_temporary = 1;
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
	//timing_advance = 0;
	process_timing_advance_rar(ue,proc,timing_advance);
	      
	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;
	}
      } 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);
3293
      }
3294 3295 3296 3297 3298 3299 3300 3301 3302
    } // 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);
  }
  
}
3303

3304 3305 3306 3307 3308 3309 3310 3311 3312
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) {
3313

3314 3315 3316
  int harq_pid;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
hbilel's avatar
hbilel committed
3317
  int ret=0, ret1=0;
3318 3319
  int CC_id = ue->CC_id;
  LTE_UE_PDSCH *pdsch_vars;
hbilel's avatar
hbilel committed
3320 3321 3322 3323 3324
  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");
3325

hbilel's avatar
hbilel committed
3326 3327 3328 3329 3330 3331 3332 3333
  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);
3334

hbilel's avatar
hbilel committed
3335 3336 3337 3338 3339 3340 3341 3342 3343 3344
  if(is_cw0_active && is_cw1_active)
  {
      dlsch0->Kmimo = 2;
      dlsch1->Kmimo = 2;
  }
  else
  {
      dlsch0->Kmimo = 1;
  }
  if (1) {
3345 3346 3347 3348 3349 3350 3351
    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;
3352 3353 3354
    case P_PDSCH:
      pdsch_vars = ue->pdsch_vars_p[eNB_id];
      break;
3355
    case PDSCH:
3356
      pdsch_vars = ue->pdsch_vars[subframe_rx&0x1][eNB_id];
3357 3358 3359 3360 3361 3362 3363
      break;
    case PMCH:
    case PDSCH1:
      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
      pdsch_vars = NULL;
      return;
      break;
3364 3365 3366 3367 3368
    default:
      pdsch_vars = NULL;
      return;
      break;

3369
    }
3370

3371 3372
    if (frame_rx < *dlsch_errors)
      *dlsch_errors=0;
3373

3374 3375 3376 3377 3378 3379 3380
    if (pdsch==RA_PDSCH) {
      if (ue->prach_resources[eNB_id]!=NULL)
	dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
      else {
	LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
	mac_xface->macphy_exit("prach_resources is NULL");
	return;
3381 3382 3383
      }
    }

3384
    if (abstraction_flag == 0) {
3385

hbilel's avatar
hbilel committed
3386
      // start turbo decode for CW 0
3387 3388 3389 3390 3391
      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,
hbilel's avatar
hbilel committed
3392
						  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
3393 3394 3395
						  frame_rx,
						  subframe_rx,
						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
3396 3397 3398 3399 3400 3401 3402 3403 3404
      start_meas(&ue->dlsch_unscrambling_stats);
      dlsch_unscrambling(&ue->frame_parms,
			 0,
			 dlsch0,
			 dlsch0->harq_processes[harq_pid]->G,
			 pdsch_vars->llr[0],
			 0,
			 subframe_rx<<1);
      stop_meas(&ue->dlsch_unscrambling_stats);
hbilel's avatar
hbilel committed
3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415

#if 0
      LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
#endif
hbilel's avatar
hbilel committed
3416

3417
      start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
3418 3419 3420 3421 3422
      ret = dlsch_decoding(ue,
			   pdsch_vars->llr[0],
			   &ue->frame_parms,
			   dlsch0,
			   dlsch0->harq_processes[harq_pid],
3423
			   frame_rx,
3424 3425 3426
			   subframe_rx,
			   harq_pid,
			   pdsch==PDSCH?1:0,
3427
			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
3428
      stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
hbilel's avatar
hbilel committed
3429

3430
      LOG_D(PHY," --> Unscrambling for CW0 %5.3f\n",
hbilel's avatar
hbilel committed
3431
              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
3432 3433 3434
      LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx&0x1].p_time)/(cpuf*1000.0));

hbilel's avatar
hbilel committed
3435 3436 3437 3438 3439 3440 3441 3442 3443

      if(is_cw1_active)
      {
          // start turbo decode for CW 1
          dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
                  dlsch1->harq_processes[harq_pid]->nb_rb,
                  dlsch1->harq_processes[harq_pid]->rb_alloc_even,
                  dlsch1->harq_processes[harq_pid]->Qm,
                  dlsch1->harq_processes[harq_pid]->Nl,
hbilel's avatar
hbilel committed
3444
                  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
hbilel's avatar
hbilel committed
3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458
                  frame_rx,
                  subframe_rx,
                  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);

          start_meas(&ue->dlsch_unscrambling_stats);
          dlsch_unscrambling(&ue->frame_parms,
                  0,
                  dlsch1,
                  dlsch1->harq_processes[harq_pid]->G,
                  pdsch_vars->llr[1],
                  1,
                  subframe_rx<<1);
          stop_meas(&ue->dlsch_unscrambling_stats);

hbilel's avatar
hbilel committed
3459 3460 3461 3462 3463 3464 3465 3466 3467
#if 0
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
#endif
3468 3469 3470

          start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);

hbilel's avatar
hbilel committed
3471 3472 3473 3474 3475 3476 3477 3478 3479 3480
          ret1 = dlsch_decoding(ue,
                  pdsch_vars->llr[1],
                  &ue->frame_parms,
                  dlsch1,
                  dlsch1->harq_processes[harq_pid],
                  frame_rx,
                  subframe_rx,
                  harq_pid,
                  pdsch==PDSCH?1:0,
                  dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
3481 3482
          stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);

hbilel's avatar
hbilel committed
3483

3484
          LOG_D(PHY," --> Unscrambling for CW1 %5.3f\n",
hbilel's avatar
hbilel committed
3485
                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
3486 3487
          LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx&0x1].p_time)/(cpuf*1000.0));
hbilel's avatar
hbilel committed
3488
      }
hbilel's avatar
hbilel committed
3489

3490
      LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
3491 3492 3493 3494
    }
	
    else {
      LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
3495
#ifdef PHY_ABSTRACTION
3496 3497
      ret = dlsch_decoding_emul(ue,
				subframe_rx,
3498
				pdsch,
3499
				eNB_id);
3500
#endif
3501 3502
    }
	
hbilel's avatar
hbilel committed
3503
    // Check CRC for CW 0
3504 3505 3506
    if (ret == (1+dlsch0->max_turbo_iterations)) {
      *dlsch_errors=*dlsch_errors+1;
      
3507 3508
      if(dlsch0->rnti != 0xffff)
      {
3509
      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
3510 3511 3512
	    ue->Mod_id,dlsch0->rnti,
	    harq_pid,frame_rx,subframe_rx,
	    dlsch0->harq_processes[harq_pid]->rvidx,
3513
        dlsch0->harq_processes[harq_pid]->round,
3514 3515
	    dlsch0->harq_processes[harq_pid]->mcs,
	    dlsch0->harq_processes[harq_pid]->TBS);
3516
      }
3517
      
3518

3519
    } else {
3520 3521
        if(dlsch0->rnti != 0xffff)
        {
3522
      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
3523 3524 3525
	    ue->Mod_id,dlsch0->rnti,
	    harq_pid,frame_rx,subframe_rx,
	    dlsch0->harq_processes[harq_pid]->rvidx,
3526
        dlsch0->harq_processes[harq_pid]->round,
3527 3528
	    dlsch0->harq_processes[harq_pid]->mcs,
	    dlsch0->harq_processes[harq_pid]->TBS);
3529
        }
3530

3531 3532 3533 3534 3535 3536 3537 3538
#ifdef DEBUG_DLSCH
      int j;
      LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
      
      for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
	LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
      
      LOG_T(PHY,"\n");
3539
#endif
3540

3541 3542 3543 3544 3545 3546 3547
      
      if (ue->mac_enabled == 1) {
	switch (pdsch) {
	case PDSCH:
	  mac_xface->ue_send_sdu(ue->Mod_id,
				 CC_id,
				 frame_rx,
3548
         subframe_rx,
3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560
				 dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
				 dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
				 eNB_id);
	  break;
	case SI_PDSCH:
	  mac_xface->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);
	  break;
3561 3562 3563 3564 3565 3566 3567 3568
	case P_PDSCH:
	  mac_xface->ue_decode_p(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);
	  break;
3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580
	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;
	}
3581
      }
3582 3583 3584 3585 3586 3587
      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
3588 3589 3590 3591
    // Check CRC for CW 1
    if(is_cw1_active)
    {
        if (ret1 == (1+dlsch0->max_turbo_iterations)) {
hbilel's avatar
hbilel committed
3592
            LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n",
hbilel's avatar
hbilel committed
3593 3594 3595 3596 3597 3598 3599
                    ue->Mod_id,dlsch0->rnti,
                    harq_pid,frame_rx,subframe_rx,
                    dlsch0->harq_processes[harq_pid]->rvidx,
                    dlsch0->harq_processes[harq_pid]->mcs,
                    dlsch0->harq_processes[harq_pid]->TBS);

        } else {
hbilel's avatar
hbilel committed
3600
            LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n",
hbilel's avatar
hbilel committed
3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630
                    ue->Mod_id,dlsch0->rnti,
                    harq_pid,frame_rx,subframe_rx,
                    dlsch0->harq_processes[harq_pid]->rvidx,
                    dlsch0->harq_processes[harq_pid]->mcs,
                    dlsch0->harq_processes[harq_pid]->TBS);


            if (ue->mac_enabled == 1) {
                switch (pdsch) {
                case PDSCH:
                    if(is_cw1_active)
                        mac_xface->ue_send_sdu(ue->Mod_id,
                                CC_id,
                                frame_rx,
                                subframe_rx,
                                dlsch1->harq_processes[dlsch1->current_harq_pid]->b,
                                dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3,
                                eNB_id);
                    break;
                case SI_PDSCH:
                case P_PDSCH:
                case RA_PDSCH:
                case PDSCH1:
                case PMCH:
                    AssertFatal(0,"exiting");
                    break;
                }
            }
        }
    }
3631 3632
  
      
3633
#ifdef DEBUG_PHY_PROC
3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650
    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]);
    }
3651
    
3652 3653
#endif

3654
  }
3655

3656

3657 3658 3659
}
int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
			 relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) {
knopp's avatar
 
knopp committed
3660
 
3661 3662 3663 3664 3665
  int l,l2;
  int pilot1;
  int pmch_flag=0;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
3666

3667
  
3668

3669
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
3670

3671
#if T_TRACER
hbilel's avatar
hbilel committed
3672
  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
3673
#endif
3674

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

hbilel's avatar
hbilel committed
3679
  // start timers
hbilel's avatar
hbilel committed
3680

3681
  LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
hbilel's avatar
hbilel committed
3682 3683
  start_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
  start_meas(&ue->generic_stat);
3684

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


3688
  // deactivate reception until we scan pdcch
hbilel's avatar
hbilel committed
3689 3690 3691 3692
  if (ue->dlsch[subframe_rx&0x1][eNB_id][0])
    ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0;
  if (ue->dlsch[subframe_rx&0x1][eNB_id][1])
    ue->dlsch[subframe_rx&0x1][eNB_id][1]->active = 0;
3693

3694 3695
  if (ue->dlsch_SI[eNB_id])
    ue->dlsch_SI[eNB_id]->active = 0;
3696 3697
  if (ue->dlsch_p[eNB_id])
    ue->dlsch_p[eNB_id]->active = 0;
3698 3699
  if (ue->dlsch_ra[eNB_id])
    ue->dlsch_ra[eNB_id]->active = 0;
3700

3701
  
3702
#ifdef DEBUG_PHY_PROC
Cedric Roux's avatar
Cedric Roux committed
3703
  LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
3704 3705
	(r_type == multicast_relay) ? "RN/UE" : "UE",
	ue->Mod_id,frame_rx, subframe_rx);
3706 3707
#endif

3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722
  if (ue->frame_parms.Ncp == 0) {  // normal prefix
    pilot1 = 4;
  } else { // extended prefix
    pilot1 = 3;
  }
  
  
  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;
  }
  
3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734
  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
3735

3736 3737
  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);
3738
  for (; l<=l2; l++) {
3739 3740 3741 3742 3743 3744
    if (abstraction_flag == 0) {
      start_meas(&ue->ofdm_demod_stats);
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
      slot_fep(ue,
	       l,
	       (subframe_rx<<1),
3745
	       0,
3746 3747 3748 3749
	       0,
	       0);
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
      stop_meas(&ue->ofdm_demod_stats);
3750
    }
3751
    
3752
    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
3753 3754 3755 3756 3757 3758 3759 3760
    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);
      
      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);
      }
hbilel's avatar
hbilel committed
3761
      LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
3762
    }
3763 3764
    
  } // for l=1..l2
3765
  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); 
3766
  
3767
  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
3768 3769 3770 3771 3772
    // If this is PMCH, call procedures and return
  if (pmch_flag == 1) {
    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
    return 0;
  }
3773

3774 3775 3776
  slot_fep(ue,
	   0,
	   1+(subframe_rx<<1),
3777
	   0,
3778 3779
	   0,
	   0);
3780

3781
  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
hbilel's avatar
hbilel committed
3782
  stop_meas(&ue->generic_stat);
3783 3784
  LOG_D(PHY,"[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
hbilel's avatar
hbilel committed
3785 3786

  start_meas(&ue->generic_stat);
3787
  // do procedures for C-RNTI
hbilel's avatar
hbilel committed
3788
  if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
3789
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
3790 3791 3792 3793
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
hbilel's avatar
hbilel committed
3794
			ue->dlsch[subframe_rx&0x1][eNB_id][0],
3795
			NULL,
hbilel's avatar
hbilel committed
3796
			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
3797 3798
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3799
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
3800
  }
hbilel's avatar
hbilel committed
3801

3802
  LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
3803 3804
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
3805
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
3806 3807 3808 3809 3810 3811
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			SI_PDSCH,
			ue->dlsch_SI[eNB_id],
			NULL,
hbilel's avatar
hbilel committed
3812
			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
3813 3814
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3815
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
3816
  }
3817 3818 3819

  // do procedures for SI-RNTI
  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
3820
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
3821 3822 3823 3824 3825 3826
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			P_PDSCH,
			ue->dlsch_p[eNB_id],
			NULL,
hbilel's avatar
hbilel committed
3827
			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
3828 3829
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3830
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
3831 3832
  }

3833 3834
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
3835
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
3836 3837 3838 3839 3840 3841
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			RA_PDSCH,
			ue->dlsch_ra[eNB_id],
			NULL,
hbilel's avatar
hbilel committed
3842
			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
3843 3844
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3845
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
3846 3847
  }    
  
3848 3849
  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
3850

3851 3852 3853 3854 3855 3856 3857 3858
  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) {
	start_meas(&ue->ofdm_demod_stats);
	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),
3859
		 0,
3860 3861 3862 3863 3864 3865
		 0,
		 0);
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
	stop_meas(&ue->ofdm_demod_stats);
      }
      
3866
      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
3867 3868
      
    } // for l=1..l2
3869 3870 3871 3872 3873 3874 3875 3876

    // 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),
3877
         0,
3878 3879 3880
         0,
         0);
    }
3881
  } // not an S-subframe
3882

hbilel's avatar
hbilel committed
3883 3884
  stop_meas(&ue->generic_stat);

3885 3886 3887
  LOG_D(PHY,"[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);

3888 3889
  if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
  {
3890
    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
3891
  }
3892 3893
   
  // do procedures for C-RNTI
3894
  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
hbilel's avatar
hbilel committed
3895
  if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
3896
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
hbilel's avatar
hbilel committed
3897
    start_meas(&ue->pdsch_procedures_stat);
3898 3899 3900 3901
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
hbilel's avatar
hbilel committed
3902
			ue->dlsch[subframe_rx&0x1][eNB_id][0],
3903 3904 3905 3906
			NULL,
			1+(ue->frame_parms.symbols_per_tti>>1),
			ue->frame_parms.symbols_per_tti-1,
			abstraction_flag);
hbilel's avatar
hbilel committed
3907 3908
    stop_meas(&ue->pdsch_procedures_stat);

3909 3910 3911
    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);

hbilel's avatar
hbilel committed
3912
    start_meas(&ue->dlsch_procedures_stat);
3913 3914 3915 3916
    ue_dlsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
hbilel's avatar
hbilel committed
3917 3918
			ue->dlsch[subframe_rx&0x1][eNB_id][0],
			ue->dlsch[subframe_rx&0x1][eNB_id][1],
3919 3920 3921
			&ue->dlsch_errors[eNB_id],
			mode,
			abstraction_flag);
hbilel's avatar
hbilel committed
3922
    stop_meas(&ue->dlsch_procedures_stat);
3923 3924
    LOG_D(PHY,"[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0));
    LOG_D(PHY,"[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
hbilel's avatar
hbilel committed
3925

3926
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
3927

3928
  }
3929

hbilel's avatar
hbilel committed
3930
  start_meas(&ue->generic_stat);
3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941
  // 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,
			1+(ue->frame_parms.symbols_per_tti>>1),
			ue->frame_parms.symbols_per_tti-1,
			abstraction_flag);
3942

3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953
    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;
  }
3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977

  // 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,
			1+(ue->frame_parms.symbols_per_tti>>1),
			ue->frame_parms.symbols_per_tti-1,
			abstraction_flag);

    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;
  }
3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999
  // 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,
			1+(ue->frame_parms.symbols_per_tti>>1),
			ue->frame_parms.symbols_per_tti-1,
			abstraction_flag);
    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;
  }
4000

4001
  if (subframe_rx==9) {
Raymond Knopp's avatar
 
Raymond Knopp committed
4002
    if (frame_rx % 10 == 0) {
4003
      if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
4004
	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]);
4005

4006 4007
      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
4008
    }
4009 4010


4011 4012
    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];
4013
    LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
4014 4015
	  ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
	  ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
4016 4017 4018 4019 4020 4021 4022

  #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);
    }
  #endif

4023
  }
4024

hbilel's avatar
hbilel committed
4025 4026
  stop_meas(&ue->generic_stat);
  //printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
jiangx's avatar
jiangx committed
4027 4028

#ifdef EMOS
4029
  phy_procedures_emos_UE_RX(ue,slot,eNB_id);
jiangx's avatar
jiangx committed
4030 4031
#endif

4032
     
4033
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
hbilel's avatar
hbilel committed
4034 4035
  stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]);

4036 4037
  LOG_D(PHY,"------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0));
  LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
4038
  return (0);
4039
}
4040
   
Cedric Roux's avatar
Cedric Roux committed
4041
#if defined(Rel10) || defined(Rel14)
4042 4043
int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
{
4044
   
4045
  int do_proc =0; // do nothing by default
4046
   
4047
  switch(r_type) {
4048
  case no_relay:
4049
    do_proc=no_relay; // perform the normal UE operation
4050
    break;
4051
     
4052
  case multicast_relay:
Raymond Knopp's avatar
 
Raymond Knopp committed
4053
    if (slot_rx > 12)
4054 4055
      do_proc = 0; // do nothing
    else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
4056
      do_proc = multicast_relay ; // do PHY procedures UE RX
4057
     
4058
    break;
4059
     
4060 4061 4062 4063 4064
  default: // should'not be here
    LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
    do_proc= 0;
    break;
  }
4065
   
4066 4067
  return do_proc;
}
4068
#endif
4069 4070 4071 4072
 
 
void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
			   relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn)
4073
{
4074
#if defined(ENABLE_ITTI)
4075 4076 4077 4078 4079
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  unsigned int  Mod_id;
  int           result;
4080
#endif
4081 4082 4083 4084 4085
   
  int           frame_rx = proc->frame_rx;
  int           frame_tx = proc->frame_tx;
  int           subframe_rx = proc->subframe_rx;
  int           subframe_tx = proc->subframe_tx;
4086
#undef DEBUG_PHY_PROC
4087
   
4088
  UE_L2_STATE_t ret;
4089
  int slot;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
4090

4091 4092
  if (ue->mac_enabled == 0) {
    ue->UE_mode[eNB_id]=PUSCH;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
4093
  }
4094 4095
   
   
4096
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
4097
  start_meas(&ue->phy_proc);
4098
#if defined(ENABLE_ITTI)
4099

4100 4101
  do {
    // Checks if a message has been sent to PHY sub-task
4102
    itti_poll_msg (TASK_PHY_UE, &msg_p);
4103
     
4104 4105 4106 4107
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance - NB_eNB_INST;
4108
       
4109
      switch (ITTI_MSG_ID(msg_p)) {
4110
      case PHY_FIND_CELL_REQ:
4111 4112 4113 4114 4115
	LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
	 
	/* TODO process the message */
	break;
	 
4116
      default:
4117 4118
	LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
	break;
4119
      }
4120
       
4121 4122
      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
4123 4124
    }
  } while(msg_p != NULL);
4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136
   
#endif
   
  for (slot=0;slot<2;slot++) {
     
    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
	(ue->frame_parms.frame_type == FDD)) {
      phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode,r_type);
    }
     
    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
	(ue->frame_parms.frame_type == FDD)) {
Cedric Roux's avatar
Cedric Roux committed
4137
#if defined(Rel10) || defined(Rel14)
4138 4139
       
      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
4140
#endif
4141 4142 4143 4144 4145 4146 4147 4148 4149 4150
	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
    }
     
    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
	(slot==1)) {
      phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag,r_type);
    }
       
    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
	(slot==0)) {
Cedric Roux's avatar
Cedric Roux committed
4151
#if defined(Rel10) || defined(Rel14)
4152 4153
	 
      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
4154
#endif
4155
	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
4156
    }
4157 4158 4159
       
    if (ue->mac_enabled==1) {
      if (slot==0) {
4160 4161 4162 4163 4164 4165 4166 4167
        ret = mac_xface->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*/);
4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190
	   
	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;
	}
      }
    }
       
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
    stop_meas(&ue->phy_proc);
  } // slot
4191
}
4192 4193