phy_procedures_lte_ue.c 136 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 78 79 80
#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;




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

85

86

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

  coded_bits_per_codeword = get_G(&ue->frame_parms,
                                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb,
                                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
                                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm,
                                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl,
                                  ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
98
                                  proc->frame_rx,
99
				  subframe,
100
				  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
101

102 103 104
  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);
105
  /*
106 107 108 109
    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);
110
  */
111 112
  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);
113

114 115
  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);
116 117
}

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

123 124 125
  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,
126
                                  2,
127
                                  1,
128
                                  ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
129
                                  proc->frame_rx,
130
				  subframe,
131
				  0);
132
  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",
133 134
        ue->Mod_id,
	ue->frame_parms.ofdm_symbol_size,
135
	nsymb,
136 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,
        ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
140
        coded_bits_per_codeword);
141

142
  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);
143

144
  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);
145 146
  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);
147
  /*
148 149 150 151
    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);
152
  */
153 154
  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);
155

156 157
  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);
158
  sleep(1);
159 160 161
  exit(-1);
}

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

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

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

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

221 222
#endif

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

228 229 230
  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,
231
                                  2,
232
                                  1,
233
                                  ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
234
                                  proc->frame_rx,
235
				  subframe,
236
				  0);
237
  LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
238 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,
        ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
243
        coded_bits_per_codeword);
244

245
  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);
246 247
  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);
248
  /*
249 250 251 252
    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);
253
  */
254 255
  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);
256

257 258
  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);
259
}
260

261

262 263
void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
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

271
  //[NUMBER_OF_CONNECTED_eNB_MAX][2];
272 273
  for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
    for(j=0; j<2; j++) {
274
      //DL HARQ
275 276 277
      if(ue->dlsch[i][j]) {
        for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->dlsch[i][j]->harq_processes[k]; k++) {
          ue->dlsch[i][j]->harq_processes[k]->status = SCH_IDLE;
278 279 280 281 282 283 284
          for (s=0; s<10; s++) {
            // reset ACK/NACK bit to DTX for all subframes s = 0..9
            ue->dlsch[i][j]->harq_ack[s].ack = 2;
            ue->dlsch[i][j]->harq_ack[s].send_harq_status = 0;
            ue->dlsch[i][j]->harq_ack[s].vDAI_UL = 0xff;
            ue->dlsch[i][j]->harq_ack[s].vDAI_DL = 0xff;
          }
285
        }
286 287
      }
    }
288

289
    //UL HARQ
290 291 292
    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;
293
        //Set NDIs for all UL HARQs to 0
294
        //  ue->ulsch[i]->harq_processes[k]->Ndi = 0;
295

296 297
      }
    }
298

299
    // flush Msg3 buffer
300
    ue->ulsch_Msg3_active[i] = 0;
301

302 303 304
  }
}

305 306
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
307 308

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

316 317
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
318 319 320

  int i;

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

323
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti_is_temporary = 0;
324
  PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
325
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
326

327
  for (i=0; i<8; i++) {
328 329 330
    if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE;
      PHY_vars_UE_g[Mod_id][CC_id]->dlsch[eNB_index][0]->harq_processes[i]->round=0;
331
    }
332 333 334 335 336
  }


}

337 338
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
339

Raymond Knopp's avatar
 
Raymond Knopp committed
340
  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
341 342

}
343
void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) {
344

345
  ue->timing_advance = timing_advance*4;
346 347


348
#ifdef DEBUG_PHY_PROC
Cedric Roux's avatar
Cedric Roux committed
349 350 351
  /* 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);
352 353 354 355
#endif

}

356 357
void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
{
358

359
  //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
360

361
  // timing advance has Q1.5 format
362
  timing_advance = timing_advance - 31;
363

364 365
  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!!!

366

367
  LOG_I(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
368

369 370 371

}

372
uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
373 374
{

375 376
  int subframe=proc->subframe_tx;

377
  LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
378
        ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,proc->frame_tx,subframe,
379
        ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
380

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

  return(0);
}

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
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));

  if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
    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));

  if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
    return(1);
  else
    return(0);
}

hbilel's avatar
hbilel committed
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 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 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset)
{
    if(TDD == frameType)
    {
        if(isrs<10)
        {
            mac_xface->macphy_exit("2 ms SRS periodicity not supported");
        }

        if((isrs>9)&&(isrs<15))
        {
            *psrsPeriodicity=5;
            *psrsOffset=isrs-10;
        }
        if((isrs>14)&&(isrs<25))
        {
            *psrsPeriodicity=10;
            *psrsOffset=isrs-15;
        }
        if((isrs>24)&&(isrs<45))
        {
            *psrsPeriodicity=20;
            *psrsOffset=isrs-25;
        }
        if((isrs>44)&&(isrs<85))
        {
            *psrsPeriodicity=40;
            *psrsOffset=isrs-45;
        }
        if((isrs>84)&&(isrs<165))
        {
            *psrsPeriodicity=80;
            *psrsOffset=isrs-85;
        }
        if((isrs>164)&&(isrs<325))
        {
            *psrsPeriodicity=160;
            *psrsOffset=isrs-165;
        }
        if((isrs>324)&&(isrs<645))
        {
            *psrsPeriodicity=320;
            *psrsOffset=isrs-325;
        }

        if(isrs>644)
        {
            mac_xface->macphy_exit("Isrs out of range");
        }

    }
    else
    {
        if(isrs<2)
        {
            *psrsPeriodicity=2;
            *psrsOffset=isrs;
        }
        if((isrs>1)&&(isrs<7))
        {
            *psrsPeriodicity=5;
            *psrsOffset=isrs-2;
        }
        if((isrs>6)&&(isrs<17))
        {
            *psrsPeriodicity=10;
            *psrsOffset=isrs-7;
        }
        if((isrs>16)&&(isrs<37))
        {
            *psrsPeriodicity=20;
            *psrsOffset=isrs-17;
        }
        if((isrs>36)&&(isrs<77))
        {
            *psrsPeriodicity=40;
            *psrsOffset=isrs-37;
        }
        if((isrs>76)&&(isrs<157))
        {
            *psrsPeriodicity=80;
            *psrsOffset=isrs-77;
        }
        if((isrs>156)&&(isrs<317))
        {
            *psrsPeriodicity=160;
            *psrsOffset=isrs-157;
        }
        if((isrs>316)&&(isrs<637))
        {
            *psrsPeriodicity=320;
            *psrsOffset=isrs-317;
        }
        if(isrs>636)
        {
            mac_xface->macphy_exit("Isrs out of range");
        }
    }
}

void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
{
    LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
    int frame_tx    = proc->frame_tx;
    int subframe_tx = proc->subframe_tx;
    uint8_t isSubframeSRS   = 0; // SRS Cell Occasion

545 546 547
    uint8_t is_pucch2_subframe = 0;
    uint8_t is_sr_an_subframe  = 0;

hbilel's avatar
hbilel committed
548 549 550 551 552
    SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];

  // check for SRS opportunity
  pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
  pSoundingrs_ul_config_dedicated->srsCellSubframe = 0;
fnabet's avatar
fnabet committed
553 554 555

  ue->ulsch[eNB_id]->srs_active   = 0;
  ue->ulsch[eNB_id]->Nsymb_pusch  = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active;
hbilel's avatar
hbilel committed
556 557 558
  if(frame_parms->soundingrs_ul_config_common.enabled_flag)
  {

fnabet's avatar
fnabet committed
559
      LOG_D(PHY," SRS SUBFRAMECONFIG: %d, Isrs: %d \n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig, pSoundingrs_ul_config_dedicated->srs_ConfigIndex);
hbilel's avatar
hbilel committed
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592

      uint8_t  TSFC;
      uint16_t deltaTSFC; // bitmap
      uint8_t  srs_SubframeConfig;
      uint16_t srsPeriodicity;
      uint16_t srsOffset;

      // table resuming TSFC (Period) and deltaSFC (offset)
      const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} };      // Table 5.5.3.3-2 3GPP 36.211 FDD
      const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD

      srs_SubframeConfig = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig;
      if (FDD == frame_parms->frame_type)
      {
          // srs_SubframeConfig =< 14
          deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
          TSFC      = deltaTSFCTabType1[srs_SubframeConfig][1];
      }
      else
      {
          // srs_SubframeConfig =< 13
          deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
          TSFC      = deltaTSFCTabType2[srs_SubframeConfig][1];
      }

      // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
      uint16_t tmp = (subframe_tx %  TSFC);
      if((1<<tmp) & deltaTSFC)
      {
          // This is a Sounding reference signal subframes
          isSubframeSRS = 1;
          pSoundingrs_ul_config_dedicated->srsCellSubframe  = 1;
      }
fnabet's avatar
fnabet committed
593 594
      LOG_D(PHY," ISTDD: %d, TSFC: %d, deltaTSFC: %d, AbsSubframeTX: %d.%d, srsCellSubframe: %d \n", frame_parms->frame_type, TSFC, deltaTSFC, frame_tx, subframe_tx, pSoundingrs_ul_config_dedicated->srsCellSubframe);
      LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
fnabet's avatar
fnabet committed
595 596
      if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
      {
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
          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,
                              ue->pdcch_vars[eNB_id]->crnti,
                              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,
                      ue->dlsch[eNB_id][0]->harq_ack,
642
                      subframe_tx,pucch_ack_payload,0) > 0)
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
              {
                  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
664
      }
fnabet's avatar
fnabet committed
665
      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
666 667 668
  }
}

Raymond Knopp's avatar
Raymond Knopp committed
669 670 671 672 673 674 675 676 677 678 679 680
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;
681
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
Raymond Knopp's avatar
Raymond Knopp committed
682 683
    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
      cqirep->Npd = 10;
684
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
Raymond Knopp's avatar
Raymond Knopp committed
685 686
    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
      cqirep->Npd = 20;
687
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
Raymond Knopp's avatar
Raymond Knopp committed
688 689
    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
      cqirep->Npd = 40;
690
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
Raymond Knopp's avatar
Raymond Knopp committed
691 692
    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
      cqirep->Npd = 80;
693
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
Raymond Knopp's avatar
Raymond Knopp committed
694 695
    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
      cqirep->Npd = 160;
696
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
Raymond Knopp's avatar
Raymond Knopp committed
697 698 699 700 701
    }
    else if (cqi_PMI_ConfigIndex > 317) {
      
      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
	cqirep->Npd = 32;
702
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
Raymond Knopp's avatar
Raymond Knopp committed
703 704 705
      }
      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
	cqirep->Npd = 64;
706
	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
Raymond Knopp's avatar
Raymond Knopp committed
707 708 709
      }
      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
	cqirep->Npd = 128;
710
	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
Raymond Knopp's avatar
Raymond Knopp committed
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
      }  
    }
  }
  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;
   }
  }
}

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
                             lte_prefix_type_t cyclic_prefix_type,
                             uint8_t SR_payload,
                             uint8_t nb_cw,
                             uint8_t cqi_status,
                             uint8_t ri_status)
{
  if((cqi_status == 0) && (ri_status==0))
  {
      // PUCCH Format 1 1a 1b
      // 1- SR only ==> PUCCH format 1
      // 2- 1bit Ack/Nack with/without SR  ==> PUCCH format 1a
      // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
      if(nb_cw == 1)
      {
          return pucch_format1a;
      }
      if(nb_cw == 2)
      {
          return pucch_format1b;
      }
      if(SR_payload == 1)
      {
          return pucch_format1;
      }
  }
  else
  {
      // PUCCH Format 2 2a 2b
      // 1- CQI only or RI only  ==> PUCCH format 2
      // 2- CQI or RI + 1bit Ack/Nack for normal CP  ==> PUCCH format 2a
      // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b
      // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2
      if(nb_cw == 0)
      {
          return pucch_format2;
      }
      if(cyclic_prefix_type == NORMAL)
      {
          if(nb_cw == 1)
          {
              return pucch_format2a;
          }
          if(nb_cw == 2)
          {
              return pucch_format2b;
          }
      }
      else
      {
          return pucch_format2;
      }
  }
}
794
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
795
		      UE_rxtx_proc_t *proc,
796
                      harq_status_t *harq_ack,
797 798 799 800
                      uint8_t eNB_id,
                      uint8_t *b,
                      uint8_t SR)
{
801

802
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
803
  uint8_t nCCE0,nCCE1,harq_ack1,harq_ack0;
804
  ANFBmode_t bundling_flag;
805
  uint16_t n1_pucch0=0,n1_pucch1=0;
806 807
  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
808 809 810
  int sf;
  int M;
  // clear this, important for case where n1_pucch selection is not used
811
  int subframe=proc->subframe_tx;
812

813
  ue->pucch_sel[subframe] = 0;
814 815 816

  if (frame_parms->frame_type == FDD ) { // FDD
    sf = (subframe<4)? subframe+6 : subframe-4;
817
    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[eNB_id]->nCCE[sf]);
818 819

    if (SR == 0)
820
      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[eNB_id]->nCCE[sf]);
821
    else
822
      return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
823
  } else {
824

825
    bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
826
#ifdef DEBUG_PHY_PROC
827 828

    if (bundling_flag==bundling) {
829
      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,
830
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
831
    } else {
832
      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,
833
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
834
    }
835

836
#endif
837

838 839 840 841 842
    switch (frame_parms->tdd_config) {
    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL

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

844
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
845 846 847
      if (subframe == 2) {  // ACK subframes 5,6
        candidate_dl[0] = 6;
        candidate_dl[1] = 5;
848 849
        M=2;
      } else if (subframe == 3) { // ACK subframe 9
850 851 852 853
        candidate_dl[0] = 9;
      } else if (subframe == 7) { // ACK subframes 0,1
        candidate_dl[0] = 1;
        candidate_dl[1] = 0;
854 855
        M=2;
      } else if (subframe == 8) { // ACK subframes 4
856
        candidate_dl[0] = 4;
857 858
      } else {
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
859
              ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config);
860
        return(0);
861 862
      }

863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
      // 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);
881 882

      // i=0
883
      nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[last_dl];
884
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
885

886
      harq_ack0 = b[0];
887 888

      if (harq_ack0!=2) {  // DTX
889 890 891 892
        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)
893
          ue->pucch_sel[subframe] = 0;
894 895 896
            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;
897
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
898 899 900 901 902 903 904 905 906 907 908 909
          }
        } 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);
          }
910
        }
911 912 913 914
      }


      break;
915

916 917 918 919 920 921 922
    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)
923
      last_dl = (subframe-2)<<1;
924
      // i=0
925
      nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[5+last_dl];
926
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
927
      // i=1
928
      nCCE1 = ue->pdcch_vars[eNB_id]->nCCE[(6+last_dl)%10];
929
      n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
930 931

      // set ACK/NAK to values if not DTX
932 933
      if (ue->dlsch[eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
        harq_ack1 = ue->dlsch[eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
934

935 936
      if (ue->dlsch[eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
        harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[5+last_dl].ack;
937

938 939

      if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
940 941 942 943 944 945 946 947 948

        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;

949
          ue->pucch_sel[subframe] = 1;
950 951 952 953 954 955 956 957 958 959
          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)) {
960
            ue->pucch_sel[subframe] = 0;
961 962
            return(n1_pucch0);
          } else {
963
            ue->pucch_sel[subframe] = 1;
964 965 966 967 968 969 970 971 972
            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;
973
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
974 975 976 977
        }
      } 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;
978
          ue->pucch_sel[subframe] = 0;
979 980 981 982
          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];
983
          ue->pucch_sel[subframe] = 0;
984 985 986 987
          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];
988
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
989
        }
990
      }
991

992 993
      break;

994
    }  // switch tdd_config
995
  }
996

Cedric Roux's avatar
Cedric Roux committed
997
  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n", ue->Mod_id, proc->frame_tx);
998 999 1000 1001 1002 1003
  return(-1);
}


#ifdef EMOS
/*
1004
  void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) {
1005
  uint8_t harq_pid;
1006

1007 1008

  if (next_slot%2==0) {
1009 1010 1011 1012 1013 1014 1015
  // 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;
  }
1016

1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
  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;
  }
  }
1030 1031 1032 1033
  }
*/
#endif

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

1036
  int aa;
1037
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
1038

1039 1040 1041 1042
  int nsymb;
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  int ulsch_start;
1043
  int overflow=0;
1044
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1045
  int k,l;
1046
  int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
1047 1048
#endif

1049 1050
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);

1051 1052 1053 1054 1055
  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-
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
         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);
1068 1069 1070
#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
1071

1072
//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
hbilel's avatar
hbilel committed
1073 1074 1075 1076 1077 1078
  if (empty_subframe)
  {
//#if 1
      overflow = ulsch_start - 9*frame_parms->samples_per_tti;
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {

1079 1080
          memset(&ue->common_vars.txdata[aa][ulsch_start],0,
                 4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti));
hbilel's avatar
hbilel committed
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100

          if (overflow> 0)
              memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
      }
/*#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;
  }
1101
//#endif
hbilel's avatar
hbilel committed
1102

1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167
  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;
    }
1168
#endif
1169
#endif
1170 1171 1172 1173 1174 1175 1176 1177 1178
    /*
    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);
    }
    */
1179 1180 1181 1182
    
  } //nb_antennas_tx
  
  stop_meas(&ue->ofdm_mod_stats);
1183

1184
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
1185

1186
}
1187

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

1190 1191 1192 1193
  int frame_tx = proc->frame_tx;
  int subframe_tx = proc->subframe_tx;
  int prach_power;
  PRACH_RESOURCES_t prach_resources_local;
1194

1195 1196
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);

1197
  ue->generate_prach=0;
1198

1199 1200 1201 1202 1203
  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;
  }
1204

1205 1206 1207
  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) ) {
1208
      LOG_D(PHY,"Getting PRACH resources\n");
1209 1210 1211 1212 1213
      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
1214
      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);
1215
      LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
    }
  }
  
  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
1231 1232

      LOG_I(PHY,"mode %d\n",mode);
1233 1234
      
      if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
1235
	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);
1236
      }
1237
      else {
1238
	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1239
	ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1240
      }
1241
      
1242
      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
1243 1244 1245 1246
	    ue->Mod_id,
	    frame_tx,
	    subframe_tx,
	    ue->prach_resources[eNB_id]->ra_PreambleIndex,
1247
		get_PL(ue->Mod_id,ue->CC_id,eNB_id),
1248
		ue->tx_power_dBm[subframe_tx],
Rohit Gupta's avatar
Rohit Gupta committed
1249 1250 1251 1252
	    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);

1253
      ue->tx_total_RE[subframe_tx] = 96;
1254 1255
      
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1256
      ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
					       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,
1268
	      ue->tx_power_dBm[subframe_tx],
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279
	      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),
1280
	    ue->tx_power_dBm[subframe_tx],
1281 1282 1283 1284 1285 1286 1287
	    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;
    }
    
1288 1289 1290 1291 1292 1293 1294
    if (ue->mac_enabled==1){
      mac_xface->Msg1_transmitted(ue->Mod_id,
          ue->CC_id,
          frame_tx,
          eNB_id);
    }

1295 1296 1297 1298 1299 1300 1301 1302
    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));
    
  }	  
  
1303

1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
  // 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;
1315 1316

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
1317
}
1318

1319
void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1320

1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
  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;
1332
  uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32)));
1333
  uint8_t access_mode;
1334 1335
  uint8_t Nbundled=0;
  uint8_t ack_status=0;
1336

1337 1338
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN);

1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
  // 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) {
1367 1368
	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);
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
	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;
    }
  }
  
1379 1380 1381 1382 1383 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 1414 1415 1416 1417
  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) {
1418
      LOG_D(PHY,"Skip PUSCH generation!\n");
1419 1420 1421
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
    }
  }
1422 1423 1424 1425 1426
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
    
    ue->generate_ul_signal[eNB_id] = 1;
    
    // deactivate service request
1427
    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
1428
    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);
1429
    if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1))
1430
    {
Cedric Roux's avatar
Cedric Roux committed
1431
        LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n");
1432 1433 1434
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
    }
1435
    
1436
    ack_status = reset_ack(&ue->frame_parms,
1437 1438
			 ue->dlsch[eNB_id][0]->harq_ack,
			 subframe_tx,
1439
			 ue->ulsch[eNB_id]->o_ACK,0);
1440
    Nbundled = ack_status;
1441 1442 1443 1444 1445 1446
    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
    
    
    
    
1447 1448 1449 1450 1451

    if (ack_status > 0) {

      // check if we received a PDSCH at subframe_tx - 4
      // ==> send ACK/NACK on PUSCH
1452
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1;
1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468

#if T_TRACER
    if(ue->ulsch[eNB_id]->o_ACK[0])
    {
    	LOG_I(PHY,"PUSCH ACK\n");
        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
                      T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
    }
    else
    {
    	LOG_I(PHY,"PUSCH NACK\n");
        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
                      T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
    }
#endif

1469
      LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
1470 1471 1472 1473 1474 1475 1476
        Mod_id,
        ue->ulsch[eNB_id]->rnti,
        frame_tx,subframe_tx,
        ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
    }

1477
#ifdef DEBUG_PHY_PROC
1478
        LOG_D(PHY,
1479
              "[UE  %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n",
1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
	  Mod_id,harq_pid,frame_tx,subframe_tx,
	  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],
1492 1493
	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK,
	  ue->ulsch[eNB_id]->bundling);
1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
#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,
			   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);
	  return;
	}
      }
      
1533
#ifdef PHY_ABSTRACTION
1534 1535 1536 1537
      else {
	ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,harq_pid,0);
      }
      
1538
#endif
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567
      
      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);
	}
	
1568 1569
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
1570 1571 1572 1573 1574 1575
	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");
1576 1577
#endif
#endif
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594
      }
      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,
1595 1596
         ue->transmission_mode[eNB_id],0,
         Nbundled)!=0) {
1597 1598 1599 1600
	  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
1601
	}
1602 1603
      }
      
1604
#ifdef PHY_ABSTRACTION
1605 1606 1607 1608
      else {
	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
      }
      
1609
#endif
1610 1611 1612 1613 1614 1615
      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);
1616
	ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
1617 1618
      }
      else {
1619
	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1620
      }
1621
      ue->tx_total_RE[subframe_tx] = nb_rb*12;
1622
      
kaltenbe's avatar
kaltenbe committed
1623
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1624
      tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
1625 1626 1627
			  ue->tx_power_max_dBm,
			  ue->frame_parms.N_RB_UL,
			  nb_rb);
1628
#else
1629
      tx_amp = AMP;
1630 1631 1632
#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]),
1633
                    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));
1634 1635
#endif
      LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
1636
	    Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647
      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
1648
			   tx_amp,
1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661
			   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
1662 1663 1664

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT);

1665
}
1666

hbilel's avatar
hbilel committed
1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693
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
1694 1695
    if (ue->mac_enabled==1)
    {
hbilel's avatar
hbilel committed
1696 1697 1698 1699
    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
1700 1701 1702 1703 1704
    }
    else
    {
        tx_amp = AMP;
    }
hbilel's avatar
hbilel committed
1705 1706 1707
#else
      tx_amp = AMP;
#endif
fnabet's avatar
fnabet committed
1708
    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
1709 1710 1711 1712 1713 1714 1715 1716
            Po_SRS,
            ue->frame_parms.N_RB_UL,
            nb_rb_srs,
            tx_amp);

    generate_srs_tx(ue, eNB_id, tx_amp, subframe_tx);
  }
}
1717

Raymond Knopp's avatar
Raymond Knopp committed
1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740
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);
}
1741

1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800

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

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

    case pucch_format1a:
    case pucch_format1b:
    {
        pucch_resource[0] = get_n1_pucch(ue,
                                         proc,
                                         ue->dlsch[eNB_id][0]->harq_ack,
                                         eNB_id,
                                         ack_payload,
                                         SR);
        pucch_payload[0]  = ack_payload[0];
        //pucch_payload[1]  = ack_payload[1];
        pucch_payload[1]  = 1;
    }
    break;

    case pucch_format2:
    {
        pucch_resource[0]    = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
        if(cqi_report)
        {
            pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,plength);
        }
        else
        {
            *plength = 1;
            pucch_payload[0] = get_pucch2_ri(ue,eNB_id);
        }
    }
    break;

    case pucch_format2a:
    case pucch_format2b:
        LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n");
    break;
    }
}

1801
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1802 1803


1804 1805 1806
  uint8_t  pucch_ack_payload[2];
  uint8_t  n1_pucch,n2_pucch;
  uint16_t pucch_resource;
1807 1808
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
Raymond Knopp's avatar
Raymond Knopp committed
1809

1810
  uint8_t  SR_payload;
Raymond Knopp's avatar
Raymond Knopp committed
1811 1812
  uint16_t CQI_payload;
  uint16_t RI_payload;
1813 1814
  uint8_t  pucch_payload[2];
  uint16_t len;
Raymond Knopp's avatar
Raymond Knopp committed
1815

1816 1817 1818 1819 1820 1821
  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;
1822
  int16_t Po_PUCCH;
1823
  uint8_t ack_status=0;
1824 1825 1826 1827 1828
  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;
1829
  uint8_t ack_sr_generated = 0;
1830

1831 1832
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
  
hbilel's avatar
hbilel committed
1833
  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
1834 1835 1836 1837 1838 1839

  // 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
  */
1840 1841 1842 1843 1844 1845 1846 1847

  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);
1848
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
1849 1850 1851
      return;
  }

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

1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865
  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");
  }
  
1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886
  // Part - I
  // Collect feedback that should be transmitted at this subframe
  // - SR
  // - ACK/NACK
  // - CQI
  // - RI

  SR_payload = 0;
  if (is_SR_TXOp(ue,proc,eNB_id)==1)
  {
      if (ue->mac_enabled==1) {
          SR_payload = mac_xface->ue_get_SR(Mod_id,
                  CC_id,
                  frame_tx,
                  eNB_id,
                  ue->pdcch_vars[eNB_id]->crnti,
                  subframe_tx); // subframe used for meas gap
      }
      else {
          SR_payload = 1;
      }
1887
  }
Raymond Knopp's avatar
Raymond Knopp committed
1888

1889 1890 1891 1892 1893
  ack_status_cw0 = reset_ack(&ue->frame_parms,
                       ue->dlsch[eNB_id][0]->harq_ack,
                       subframe_tx,
                       pucch_ack_payload,
                       0);
1894

1895 1896 1897 1898 1899
  ack_status_cw1 = reset_ack(&ue->frame_parms,
                       ue->dlsch[eNB_id][1]->harq_ack,
                       subframe_tx,
                       pucch_ack_payload,
                       1);
Raymond Knopp's avatar
Raymond Knopp committed
1900

1901
  nb_cw = ack_status_cw0 + ack_status_cw1;
Raymond Knopp's avatar
Raymond Knopp committed
1902

1903 1904
  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
1905

1906 1907
  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
1908

1909 1910 1911 1912
  // Part - II
  // if nothing to report ==> exit function
  if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0))
  {
1913 1914
      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);
1915 1916
      return;
  }
Raymond Knopp's avatar
Raymond Knopp committed
1917

1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937
  // Part - III
  // Decide which PUCCH format should be used if needed
  format = get_pucch_format(frame_parms->frame_type,
                            frame_parms->Ncp,
                            SR_payload,
                            nb_cw,
                            cqi_status,
                            ri_status);
  // Determine PUCCH resources and payload: mandatory for pucch encoding
  get_pucch_param(ue,
                  proc,
                  pucch_ack_payload,
                  format,
                  eNB_id,
                  SR_payload,
                  cqi_status,
                  &pucch_resource,
                  &pucch_payload,
                  &len);

1938
  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949


  // 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
1950
      if (ue->mac_enabled == 1) {
1951
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
1952 1953
      }
      else {
1954
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
1955 1956 1957
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
1958

Raymond Knopp's avatar
Raymond Knopp committed
1959
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1960 1961 1962 1963
      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
1964 1965
#else
      tx_amp = AMP;
1966 1967 1968
#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]),
1969
              T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
Raymond Knopp's avatar
Raymond Knopp committed
1970
#endif
1971 1972
      if(format == pucch_format1)
      {
1973
          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",
1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
                  Mod_id,
                  ue->dlsch[eNB_id][0]->rnti,
                  frame_tx, subframe_tx,
                  frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                  isShortenPucch,
                  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
                  Po_PUCCH);
      }
      else
      {
          if (SR_payload>0) {
1985
              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",
1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997
                      Mod_id,
                      ue->dlsch[eNB_id][0]->rnti,
                      frame_tx % 1024, subframe_tx,
                      (format == pucch_format1a? "1a": (
                              format == pucch_format1b? "1b" : "??")),
                              pucch_ack_payload[0],pucch_ack_payload[1],
                              frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                              isShortenPucch,
                              pucch_resource,
                              Po_PUCCH,
                              tx_amp);
          } else {
1998
              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",
1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
                      Mod_id,
                      ue->dlsch[eNB_id][0]->rnti,
                      frame_tx%1024, subframe_tx,ue->rx_offset_diff,
                      (format == pucch_format1a? "1a": (
                              format == pucch_format1b? "1b" : "??")),
                              frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                              isShortenPucch,
                              pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload,
                              Po_PUCCH,
                              tx_amp);
          }
      }
2011

2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
#if T_TRACER
      if(pucch_payload[0])
      {
          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
                  T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
      }
      else
      {
          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
                  T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
      }
#endif
2024

2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050
      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;
2051

Raymond Knopp's avatar
Raymond Knopp committed
2052

2053 2054
  case pucch_format2:
  {
Raymond Knopp's avatar
Raymond Knopp committed
2055
      if (ue->mac_enabled == 1) {
2056
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
2057 2058
      }
      else {
2059
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
2060 2061 2062
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
2063

Raymond Knopp's avatar
Raymond Knopp committed
2064 2065
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
      tx_amp =  get_tx_amp(Po_PUCCH,
2066 2067 2068
              ue->tx_power_max_dBm,
              ue->frame_parms.N_RB_UL,
              1);
Raymond Knopp's avatar
Raymond Knopp committed
2069 2070 2071
#else
      tx_amp = AMP;
#endif
2072 2073 2074 2075
#if T_TRACER
      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
              T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
#endif
Raymond Knopp's avatar
Raymond Knopp committed
2076

2077
      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",
2078 2079 2080 2081 2082 2083 2084
              Mod_id,
              ue->dlsch[eNB_id][0]->rnti,
              frame_tx%1024, subframe_tx,
              n2_pucch,
              Po_PUCCH,
              isShortenPucch,
              tx_amp);
Raymond Knopp's avatar
Raymond Knopp committed
2085 2086

      generate_pucch2x(ue->common_vars.txdataF,
2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114
              &ue->frame_parms,
              ue->ncs_cell,
              format,
              &ue->pucch_config_dedicated[eNB_id],
              pucch_resource,
              pucch_payload,
              len,          // A
              0,            // B2 not needed
              tx_amp,
              subframe_tx,
              ue->pdcch_vars[eNB_id]->crnti);
  }
  break;

  case pucch_format2a:
      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
              Mod_id,
              ue->dlsch[eNB_id][0]->rnti,
              frame_tx%1024, subframe_tx);
      break;
  case pucch_format2b:
      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
              Mod_id,
              ue->dlsch[eNB_id][0]->rnti,
              frame_tx%1024, subframe_tx);
      break;
  default:
      break;
Raymond Knopp's avatar
Raymond Knopp committed
2115
  }
2116 2117 2118

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);

2119
}
2120

2121 2122
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) {
  
2123

2124
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2125
  //int32_t ulsch_start=0;
2126 2127 2128
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  unsigned int aa;
2129
  
2130 2131 2132



2133
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
2134

2135
#if T_TRACER
hbilel's avatar
hbilel committed
2136
  T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx));
2137
#endif
2138

2139
  ue->generate_ul_signal[eNB_id] = 0;
2140

2141
  start_meas(&ue->phy_proc_tx);
2142

2143 2144
#ifdef EMOS
  //phy_procedures_emos_UE_TX(next_slot);
2145 2146
#endif

2147
  ue->tx_power_dBm[subframe_tx]=-127;
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157
      
  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
2158 2159
    // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding
    ue_compute_srs_occasion(ue,proc,eNB_id);
2160

2161
    ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
2162

2163 2164
  }
  	  
hbilel's avatar
hbilel committed
2165 2166 2167 2168 2169
  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);
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218
  } // 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,
			   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 {
	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
      }
	    
2219
#endif
2220 2221 2222 2223 2224 2225 2226 2227 2228
    } 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
2229

2230 2231
  	
  if (abstraction_flag == 0) {
hbilel's avatar
hbilel committed
2232
    ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
2233 2234 2235 2236 2237 2238 2239
  } // 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
2240

2241
    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
2242

2243
      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
2244
    }
2245 2246 2247 2248 2249
  } // mode is PRACH
  else {
    ue->generate_prach=0;
  }
    
2250 2251 2252 2253
  // reset DL ACK/NACK status
  reset_ack(&ue->frame_parms,
             ue->dlsch[eNB_id][0]->harq_ack,
             subframe_tx,
2254 2255 2256 2257 2258 2259
             ue->ulsch[eNB_id]->o_ACK,0);

  reset_ack(&ue->frame_parms,
             ue->dlsch_SI[eNB_id]->harq_ack,
             subframe_tx,
             ue->ulsch[eNB_id]->o_ACK,0);
2260

2261
      
2262
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
2263
  stop_meas(&ue->phy_proc_tx);
2264 2265
}

2266
void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
2267
{
2268
  int aa;//i,aa;
2269
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2270
  
2271
  if (abstraction_flag==0) {
2272
    
2273
    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
2274
#if defined(EXMIMO) //this is the EXPRESS MIMO case
2275 2276
      int i;
      // set the whole tx buffer to RX
2277
      for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
2278 2279
	ue->common_vars.txdata[aa][i] = 0x00010001;
      
2280
#else //this is the normal case
2281
      memset(&ue->common_vars.txdata[aa][0],0,
2282
	     (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
2283
#endif //else EXMIMO
2284
      
2285 2286 2287 2288
    }
  }
}

2289 2290 2291 2292 2293
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)
2294
{
2295
  
2296
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
Raymond Knopp's avatar
 
Raymond Knopp committed
2297

2298
  int subframe_rx = proc->subframe_rx;
2299

2300
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
2301 2302

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

2307
      lte_ue_measurements(ue,
2308 2309
			  (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,
2310
			  0,subframe_rx);
2311
    } else {
2312
      lte_ue_measurements(ue,
2313 2314
			  0,
			  0,
2315 2316
			  1,
      subframe_rx);
2317
    }
2318 2319 2320 2321 2322
#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]),
2323 2324 2325 2326 2327
                             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));
2328
#endif
2329 2330
  }

2331
  if (l==(6-ue->frame_parms.Ncp)) {
2332
	
2333
    // make sure we have signal from PSS/SSS for N0 measurement
2334

2335
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
2336
    ue_rrc_measurements(ue,
2337
			slot,
2338
			abstraction_flag);
2339
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
2340

Raymond Knopp's avatar
 
Raymond Knopp committed
2341
    if (abstraction_flag==1)
2342
      ue->sinr_eff =  sinr_eff_cqi_calc(ue, 0, subframe_rx);
2343

2344
  }
2345

2346
  if ((subframe_rx==0) && (slot == 0) && (l==(4-frame_parms->Ncp))) {
2347

2348
    // AGC
Raymond Knopp's avatar
 
Raymond Knopp committed
2349

2350
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2351

2352
#ifndef OAI_USRP
kaltenbe's avatar
kaltenbe committed
2353 2354
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
2355
    phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0);
kaltenbe's avatar
kaltenbe committed
2356 2357
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2358
#endif
2359

2360
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
2361

2362
    eNB_id = 0;
2363
    
2364 2365 2366 2367 2368
    if (abstraction_flag == 0) {
      if (ue->no_timing_correction==0)
	lte_adjust_synch(&ue->frame_parms,
			 ue,
			 eNB_id,
2369
			 subframe_rx,
2370 2371 2372
			 0,
			 16384);
    }      
2373

2374
  }
2375

2376
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
2377 2378 2379
}

#ifdef EMOS
2380
void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
2381
{
2382

2383 2384 2385
  uint8_t i,j;
  //uint16_t last_slot_emos;
  uint32_t bytes;
2386
  int Mod_id = ue->Mod_id;
2387 2388

  /*
2389
    if (last_slot<2)
2390
    last_slot_emos = last_slot;
2391
    else if (last_slot>9)
2392
    last_slot_emos = last_slot - 8;
2393
    else {
2394 2395
    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");
2396
    }
2397 2398 2399
  */

#ifdef EMOS_CHANNEL
2400

2401
  if ((last_slot==10) || (last_slot==11)) {
2402 2403
    for (i=0; i<ue->frame_parms.nb_antennas_rx; i++)
      for (j=0; j<ue->frame_parms.nb_antennas_tx; j++) {
2404 2405 2406 2407 2408 2409 2410 2411
	// 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));
2412 2413
      }
  }
2414

2415
#endif
2416

2417 2418
  if (last_slot==0) {
    emos_dump_UE.timestamp = rt_get_time_ns();
2419
    emos_dump_UE.frame_rx = proc->frame_rx;
2420 2421 2422 2423 2424 2425
    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;
2426
    emos_dump_UE.eNb_id = eNB_id;
2427
    memcpy(&emos_dump_UE.PHY_measurements,&measurements,sizeof(PHY_MEASUREMENTS));
2428
  }
2429

2430
  if (last_slot==1) {
2431 2432 2433 2434
    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;
2435
  }
2436

2437
  if (last_slot==19) {
2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450
    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];
    emos_dump_UE.pmi_saved = ue->dlsch[eNB_id][0]->pmi_alloc;
    emos_dump_UE.mcs = ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->mcs;
2451 2452 2453
    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));
2454

2455
    if (bytes!=sizeof(fifo_dump_emos_UE)) {
2456
      LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot);
2457
    } else {
2458 2459
      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);
2460 2461 2462
      }
    }
  }
2463

2464 2465 2466 2467
}
#endif


2468
void restart_phy(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag)
2469
{
2470

2471 2472
  //  uint8_t last_slot;
  uint8_t i;
2473
  LOG_I(PHY,"[UE  %d] frame %d, slot %d, restarting PHY!\n",ue->Mod_id,proc->frame_rx,proc->subframe_rx);
2474
  mac_xface->macphy_exit("restart_phy called");
2475
  //   first_run = 1;
2476

2477
  if (abstraction_flag ==0 ) {
2478
    ue->UE_mode[eNB_id] = NOT_SYNCHED;
2479
  } else {
2480 2481
    ue->UE_mode[eNB_id] = PRACH;
    ue->prach_resources[eNB_id]=NULL;
2482
  }
2483

2484 2485
  proc->frame_rx = -1;
  proc->frame_tx = -1;
2486 2487
  //  ue->synch_wait_cnt=0;
  //  ue->sched_cnt=-1;
2488

2489 2490
  ue->pbch_vars[eNB_id]->pdu_errors_conseq=0;
  ue->pbch_vars[eNB_id]->pdu_errors=0;
2491

2492 2493 2494 2495
  ue->pdcch_vars[eNB_id]->dci_errors = 0;
  ue->pdcch_vars[eNB_id]->dci_missed = 0;
  ue->pdcch_vars[eNB_id]->dci_false  = 0;
  ue->pdcch_vars[eNB_id]->dci_received = 0;
2496

2497 2498 2499 2500 2501 2502 2503
  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;
2504
  ue->dlsch_p_received[eNB_id] = 0;
2505 2506
  ue->dlsch_SI_errors[eNB_id] = 0;
  ue->dlsch_ra_errors[eNB_id] = 0;
2507
  ue->dlsch_p_errors[eNB_id] = 0;
2508

2509
  ue->dlsch_mch_received[eNB_id] = 0;
2510 2511

  for (i=0; i < MAX_MBSFN_AREA ; i ++) {
2512 2513 2514 2515 2516 2517 2518
    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;
2519 2520
  }

2521 2522 2523 2524
  //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;
2525 2526 2527
}


2528
void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag)
2529
{
2530 2531 2532

  //  int i;
  int pbch_tx_ant=0;
2533 2534 2535 2536
  uint8_t pbch_phase;
  uint16_t frame_tx;
  static uint8_t first_run = 1;
  uint8_t pbch_trials = 0;
2537

2538
  DevAssert(ue);
2539 2540 2541

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

2543
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
2544

Raymond Knopp's avatar
 
Raymond Knopp committed
2545
  pbch_phase=(frame_rx%4);
2546

2547 2548
  if (pbch_phase>=4)
    pbch_phase=0;
2549 2550 2551

  for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
    //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
2552
    //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);
2553
    if (abstraction_flag == 0) {
2554
      pbch_tx_ant = rx_pbch(&ue->common_vars,
2555 2556 2557 2558 2559 2560
			    ue->pbch_vars[eNB_id],
			    &ue->frame_parms,
			    eNB_id,
			    ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
			    ue->high_speed_flag,
			    pbch_phase);
2561 2562 2563 2564



    }
2565

2566 2567
#ifdef PHY_ABSTRACTION
    else {
2568
      pbch_tx_ant = rx_pbch_emul(ue,
2569 2570
				 eNB_id,
				 pbch_phase);
2571
    }
2572

2573 2574 2575 2576 2577
#endif

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

2579
    pbch_phase++;
2580

2581 2582 2583 2584 2585 2586 2587 2588
    if (pbch_phase>=4)
      pbch_phase=0;
  }



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

2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599
    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);
    }

2600
    if (pbch_tx_ant>2) {
2601
      LOG_W(PHY,"[openair][SCHED][SYNCH] PBCH decoding: pbch_tx_ant>2 not supported\n");
2602
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2603 2604 2605 2606
      return;
    }


2607 2608 2609
    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));
2610 2611
    frame_tx += pbch_phase;

2612 2613 2614
    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
2615 2616
    }
    
2617 2618
#ifdef EMOS
    //emos_dump_UE.frame_tx = frame_tx;
2619
    //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1];
2620 2621 2622 2623
#endif

    if (first_run) {
      first_run = 0;
2624 2625 2626 2627 2628 2629

      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",
2630 2631 2632 2633 2634
	    ue->Mod_id,
	    frame_rx,
	    subframe_rx,
	    pbch_tx_ant,
	    frame_tx,
2635 2636 2637
	    pbch_phase,
	    ue->rx_offset,
	    proc->frame_rx);
2638
      frame_rx = proc->frame_rx;
2639
      
2640
    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
2641
      //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
Cedric Roux's avatar
Cedric Roux committed
2642
      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",
2643 2644 2645 2646 2647 2648 2649 2650 2651
	    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);
2652
      ue->proc.proc_rxtx[1].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
2653
      proc->frame_tx = proc->frame_rx;
2654
      ue->proc.proc_rxtx[1].frame_tx = proc->frame_rx;
2655 2656
      frame_rx = proc->frame_rx;

2657
    }
2658

2659
#ifdef DEBUG_PHY_PROC
2660 2661 2662 2663 2664 2665 2666 2667 2668 2669
    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);
2670
#endif
2671

2672
  } else { 
2673
    /*
2674
    LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
2675
	  ue->Mod_id,frame_rx, subframe_rx);
2676

2677 2678 2679 2680 2681
    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);

2682 2683
    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);
2684

2685
    write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
2686 2687 2688 2689 2690
    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);
    */
2691

2692 2693 2694 2695
    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
2696 2697
    }
    else{
2698
      if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2699 2700 2701
	LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
	mac_xface->macphy_exit("More that 100 consecutive PBCH errors!");
      }
2702
    }
2703 2704
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
2705
  if (frame_rx % 100 == 0) {
2706 2707
    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;
2708
  }
2709 2710

#ifdef DEBUG_PHY_PROC
2711
  LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
2712 2713 2714
	ue->Mod_id,frame_rx, subframe_rx,
	ue->pbch_vars[eNB_id]->pdu_errors,
	ue->pbch_vars[eNB_id]->pdu_errors_conseq);
2715
#endif
2716
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2717 2718
}

2719
int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag)
2720
{
2721 2722

  unsigned int dci_cnt=0, i;
2723

2724 2725
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2726
  DCI_ALLOC_t dci_alloc_rx[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
2727

2728

2729 2730 2731 2732 2733 2734
#ifdef PHY_ABSTRACTION
  int CC_id;
  int UE_id;
  uint8_t harq_pid;
#endif

2735
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
2736
  start_meas(&ue->dlsch_rx_pdcch_stats);
2737

2738 2739
  //  if (subframe_rx != 5)
  //    return 0;
2740 2741
  if (abstraction_flag == 0)  {

2742
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
2743
    rx_pdcch(&ue->common_vars,
2744 2745
	     ue->pdcch_vars,
	     &ue->frame_parms,
2746
	     proc->frame_rx,
2747 2748 2749 2750 2751
	     subframe_rx,
	     eNB_id,
	     (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
	     ue->high_speed_flag,
	     ue->is_secondary_ue);
2752 2753


2754 2755
    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);
2756
    dci_cnt = dci_decoding_procedure(ue,
2757 2758 2759 2760
				     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);
2761
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
2762
    //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
2763

2764
    if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
2765
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
2766 2767
      rx_phich(ue,proc,
	       subframe_rx,eNB_id);
2768
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
2769 2770
    }
  }
2771

2772 2773
#ifdef PHY_ABSTRACTION
  else {
2774 2775
    for (i=0; i<NB_eNB_INST; i++) {
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
2776 2777
	if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
	  break;
2778

2779
      if (CC_id < MAX_NUM_CCs)
2780
	break;
2781
    }
2782

2783
    if (i==NB_eNB_INST) {
2784
      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);
2785
      mac_xface->macphy_exit("Could not find attached eNB for DCI emulation");
2786
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
2787 2788
      return(-1);
    }
2789

2790
    LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
2791
    dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars,
2792 2793 2794 2795 2796
					  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);
2797
    //    printf("DCI: dci_cnt %d\n",dci_cnt);
2798
    UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
2799

2800
    if (UE_id>=0) {
2801
      //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
2802
      if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813
	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
2814 2815 2816
      } // This is a PHICH subframe
    } // UE_id exists
  }
2817

2818 2819
#endif

2820

2821
  LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt);
2822

2823
  ue->pdcch_vars[eNB_id]->dci_received += dci_cnt;
2824

2825
#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
2826
  //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt;
2827 2828
#endif

2829 2830 2831
  for (i=0; i<dci_cnt; i++) {


2832

2833 2834
    if ((ue->UE_mode[eNB_id]>PRACH) &&
	(dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) &&
2835 2836
	(dci_alloc_rx[i].format != format0)) {
      
2837

2838
      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
2839
	    ue->Mod_id,dci_alloc_rx[i].rnti,
2840
	    frame_rx%1024,subframe_rx,
2841 2842 2843 2844
	    dci_alloc_rx[i].format,
	    ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
	    ue->pdcch_vars[eNB_id]->nCCE[subframe_rx],
	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
2845 2846 2847 2848




2849
      
2850
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2851
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2852 2853
	  (generate_ue_dlsch_params_from_dci(frame_rx,
					     subframe_rx,
2854
					     (void *)&dci_alloc_rx[i].dci_pdu,
2855
					     ue->pdcch_vars[eNB_id]->crnti,
2856
					     dci_alloc_rx[i].format,
2857 2858 2859
					     ue->dlsch[eNB_id],
					     &ue->frame_parms,
					     ue->pdsch_config_dedicated,
2860 2861
					     SI_RNTI,
					     0,
2862
					     P_RNTI,
2863 2864
					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
					     ue->pdcch_vars[eNB_id]->crnti_is_temporary? ue->pdcch_vars[eNB_id]->crnti: 0)==0)) {
2865

hbilel's avatar
hbilel committed
2866 2867 2868
          // update TPC for PUCCH
          if((dci_alloc_rx[i].format == format1)   ||
              (dci_alloc_rx[i].format == format1A) ||
2869
              (dci_alloc_rx[i].format == format1B) ||
hbilel's avatar
hbilel committed
2870
              (dci_alloc_rx[i].format == format2)  ||
2871 2872
              (dci_alloc_rx[i].format == format2A) ||
              (dci_alloc_rx[i].format == format2B))
hbilel's avatar
hbilel committed
2873 2874 2875 2876
          {
            ue->dlsch[eNB_id][0]->g_pucch += ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->delta_PUCCH;
          }

2877
	ue->dlsch_received[eNB_id]++;
2878
	
2879
#ifdef DEBUG_PHY_PROC
2880 2881 2882
	LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[eNB_id][0]->active);
2883
#endif
2884
	
2885 2886
	// we received a CRNTI, so we're in PUSCH
	if (ue->UE_mode[eNB_id] != PUSCH) {
2887
#ifdef DEBUG_PHY_PROC
2888
	  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[eNB_id]->crnti);
2889
#endif
2890 2891 2892 2893
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	  ue->UE_mode[eNB_id] = PUSCH;
	  //mac_xface->macphy_exit("Connected. Exiting\n");
	}
2894
      } else {
2895 2896
	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]);
2897 2898 2899
      }
    }

2900
    else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
2901
	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2902

2903
#ifdef DEBUG_PHY_PROC
2904
      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);
2905 2906
#endif

2907

2908 2909
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2910 2911 2912 2913 2914 2915 2916 2917
					    (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,
2918
					    P_RNTI,
2919 2920
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
              0)==0) {
2921 2922

	ue->dlsch_SI_received[eNB_id]++;
2923 2924
 

2925
	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");
2926
	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2927 2928 2929

      }
    }
2930

2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941
    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,
2942
						P_RNTI,
2943 2944 2945 2946 2947 2948
					    dci_alloc_rx[i].format,
					    &ue->dlsch_SI[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    0,
2949
					    P_RNTI,
2950 2951
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
2952 2953 2954 2955 2956 2957 2958 2959 2960 2961

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

      }
    }

2962
    else if ((ue->prach_resources[eNB_id]) &&
2963 2964
	     (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
2965

2966
#ifdef DEBUG_PHY_PROC
2967
      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);
2968 2969

      //if (((frame_rx%100) == 0) || (frame_rx < 20))
2970
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2971 2972 2973 2974
      //mac_xface->macphy_exit("so far so good...\n");
#endif


2975 2976
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2977 2978 2979 2980 2981 2982 2983 2984
					    (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,
2985
					    P_RNTI,
2986 2987
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
2988 2989

	ue->dlsch_ra_received[eNB_id]++;
2990

2991
#ifdef DEBUG_PHY_PROC
2992 2993
	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]);
2994
#endif
2995
      }
2996
    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) &&
2997
	       (dci_alloc_rx[i].format == format0)) {
2998
#ifdef DEBUG_PHY_PROC
2999
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
3000
	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
3001 3002
#endif

3003 3004
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
3005

3006
      if ((ue->UE_mode[eNB_id] > PRACH) &&
3007
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
3008
					     ue->pdcch_vars[eNB_id]->crnti,
3009 3010
					     subframe_rx,
					     format0,
3011
					     ue,
3012
					     proc,
3013 3014 3015 3016 3017 3018
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
3019

3020 3021
#if T_TRACER
    LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
3022 3023 3024 3025
    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
3026
    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),
3027 3028 3029 3030 3031 3032
      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));
3033
#endif
3034
#ifdef DEBUG_PHY_PROC
3035
	LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
3036 3037
#endif

3038
      }
3039
    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
3040
	       (dci_alloc_rx[i].format == format0)) {
3041
      // UE could belong to more than one CBA group
3042
      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
3043
#ifdef DEBUG_PHY_PROC
3044
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
3045
	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
3046 3047 3048 3049
      /*
	if (((frame_rx%100) == 0) || (frame_rx < 20))
	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
      */
3050 3051
#endif

3052 3053
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
3054

3055
      if ((ue->UE_mode[eNB_id] > PRACH) &&
3056
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
3057
					     ue->ulsch[eNB_id]->cba_rnti[0],
3058 3059
					     subframe_rx,
					     format0,
3060
					     ue,
3061
					     proc,
3062 3063 3064 3065 3066 3067
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
3068

3069
#ifdef DEBUG_PHY_PROC
3070
	LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
3071
#endif
3072
	ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
3073 3074 3075
      }
    }

3076 3077
    else {
#ifdef DEBUG_PHY_PROC
3078
      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,
3079 3080 3081
	    ue->pdcch_vars[eNB_id]->crnti,
	    ue->ulsch[eNB_id]->cba_rnti[0],
	    dci_alloc_rx[i].format);
3082
      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
3083 3084
#endif
    }
3085

3086
  }
3087

3088
  stop_meas(&ue->dlsch_rx_pdcch_stats);
3089
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
3090 3091 3092
  return(0);
}

3093

3094
void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
3095

3096
  int subframe_rx = proc->subframe_rx;
3097
  int frame_rx = proc->frame_rx;
3098
  int pmch_mcs=-1;
3099
  int CC_id = ue->CC_id;
3100 3101 3102 3103
  uint8_t sync_area=255;
  uint8_t mcch_active;
  int l;
  int ret=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3104

3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120
  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);
#ifdef Rel10
    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;
3121
#endif
3122 3123 3124 3125
    
    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);
3126
      
3127 3128 3129 3130 3131 3132 3133 3134
      if (abstraction_flag == 0 ) {
	for (l=2; l<12; l++) {
	  
	  slot_fep_mbsfn(ue,
			 l,
			 subframe_rx,
			 0,0);//ue->rx_offset,0);
	}
3135

3136 3137 3138 3139 3140 3141
	for (l=2; l<12; l++) {
	  rx_pmch(ue,
		  0,
		  subframe_rx,
		  l);
	}
3142 3143


3144 3145 3146 3147 3148 3149
	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,
3150 3151 3152
						       frame_rx,
						       subframe_rx,
						       0);
3153 3154 3155 3156 3157 3158 3159 3160 3161 3162
	
	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],
3163
			     frame_rx,
3164 3165 3166 3167
			     subframe_rx,
			     0,
			     0,1);
      } else { // abstraction
3168
#ifdef PHY_ABSTRACTION
3169 3170 3171 3172
	ret = dlsch_decoding_emul(ue,
				  subframe_rx,
				  5, // PMCH
				  eNB_id);
3173
#endif
3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187
      }
      
      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
3188 3189
	      ue->Mod_id,
              frame_rx,subframe_rx,
3190 3191 3192 3193 3194 3195
	      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);
3196
#ifdef DEBUG_DLSCH
3197 3198 3199
	
	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]);
3200
	}
3201 3202
	
	LOG_T(PHY,"\n");
3203
#endif
3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225
	
	if (subframe_rx==9)
	  mac_xface->macphy_exit("Why are we exiting here?");
      } else { // decoding successful
#ifdef Rel10
	
	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;
3226
	  }
3227 3228 3229 3230 3231 3232 3233 3234
	  
	  
	}
#endif // Rel10
      } // decoding sucessful
    } // pmch_mcs>=0
  } // is_pmch_subframe=true
}
3235

3236
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) {
3237

3238 3239 3240 3241 3242
  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;
3243

3244 3245
  if (dlsch0->active == 0)
    return;
3246

3247
  for (m=s0;m<=s1;m++) {
3248

3249 3250
    if (dlsch0 && (!dlsch1))  {
      harq_pid = dlsch0->current_harq_pid;
Cedric Roux's avatar
Cedric Roux committed
3251
      LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d\n",ue->Mod_id,subframe_rx,harq_pid);
3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263
	    
      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;
      } else {
	dual_stream_UE = 0;
	eNB_id_i = eNB_id+1;
	i_mod = 0;
3264
      }
3265

3266 3267 3268
      //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
3269
          if ((m==3) || (m==6) || (m==9) || (m==12))
3270 3271
            //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);
3272
        } else {
3273
          LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
3274
        }
3275
      }
3276
     
3277 3278
      if ((m==s0) && (m<4))
	first_symbol_flag = 1;
3279
      else
3280 3281 3282 3283 3284 3285 3286 3287
	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,
3288
	       proc->frame_rx,
3289 3290 3291 3292 3293 3294 3295 3296
	       subframe_rx,  // subframe,
	       m,
	       first_symbol_flag,
	       dual_stream_UE,
	       i_mod,
	       dlsch0->current_harq_pid);
      stop_meas(&ue->dlsch_llr_stats);
    } // CRNTI active
3297
  }
3298
} 
3299

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

3302 3303 3304 3305 3306 3307
  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;
3308

3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325
  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,
3326
						 ue->prach_resources[eNB_id]->ra_RNTI,
3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340
						 dlsch0->harq_processes[0]->b,
						 &ue->pdcch_vars[eNB_id]->crnti,
						 ue->prach_resources[eNB_id]->ra_PreambleIndex);
      
	    
      if (timing_advance!=0xffff) {
	      
	LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
	      ue->Mod_id,
	      frame_rx,
	      subframe_rx,
	      ue->pdcch_vars[eNB_id]->crnti,
	      timing_advance);
	      
3341 3342 3343
  // remember this c-rnti is still a tc-rnti
  ue->pdcch_vars[eNB_id]->crnti_is_temporary = 1;	     
	      
3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374
	//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);
3375
      }
3376 3377 3378 3379 3380 3381 3382 3383 3384
    } // 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);
  }
  
}
3385

3386 3387 3388 3389 3390 3391 3392 3393 3394
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) {
3395

3396 3397 3398 3399 3400 3401
  int harq_pid;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
  int ret=0;
  int CC_id = ue->CC_id;
  LTE_UE_PDSCH *pdsch_vars;
3402

3403 3404 3405 3406 3407 3408 3409 3410
  if (dlsch0 && (!dlsch1)) {
    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;
3411 3412 3413
    case P_PDSCH:
      pdsch_vars = ue->pdsch_vars_p[eNB_id];
      break;
3414
    case PDSCH:
3415
      pdsch_vars = ue->pdsch_vars[subframe_rx&0x1][eNB_id];
3416 3417 3418 3419 3420 3421 3422
      break;
    case PMCH:
    case PDSCH1:
      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
      pdsch_vars = NULL;
      return;
      break;
3423 3424 3425 3426 3427
    default:
      pdsch_vars = NULL;
      return;
      break;

3428 3429 3430
    }
  
    harq_pid = dlsch0->current_harq_pid;
3431

3432 3433
    if (frame_rx < *dlsch_errors)
      *dlsch_errors=0;
3434

3435 3436 3437 3438 3439 3440 3441
    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;
3442 3443 3444
      }
    }

3445
    if (abstraction_flag == 0) {
3446

3447 3448 3449 3450 3451 3452
      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,
						  ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
3453 3454 3455
						  frame_rx,
						  subframe_rx,
						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471
      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);
      
      start_meas(&ue->dlsch_decoding_stats);
      ret = dlsch_decoding(ue,
			   pdsch_vars->llr[0],
			   &ue->frame_parms,
			   dlsch0,
			   dlsch0->harq_processes[harq_pid],
3472
			   frame_rx,
3473 3474 3475
			   subframe_rx,
			   harq_pid,
			   pdsch==PDSCH?1:0,
3476
			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
3477 3478 3479 3480 3481
      stop_meas(&ue->dlsch_decoding_stats);
    }
	
    else {
      LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
3482
#ifdef PHY_ABSTRACTION
3483 3484
      ret = dlsch_decoding_emul(ue,
				subframe_rx,
3485
				pdsch,
3486
				eNB_id);
3487
#endif
3488 3489 3490 3491 3492
    }
	
    if (ret == (1+dlsch0->max_turbo_iterations)) {
      *dlsch_errors=*dlsch_errors+1;
      
3493 3494
      if(dlsch0->rnti != 0xffff)
      {
3495 3496 3497 3498 3499 3500
      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d,TBS %d)\n",
	    ue->Mod_id,dlsch0->rnti,
	    harq_pid,frame_rx,subframe_rx,
	    dlsch0->harq_processes[harq_pid]->rvidx,
	    dlsch0->harq_processes[harq_pid]->mcs,
	    dlsch0->harq_processes[harq_pid]->TBS);
3501
      }
3502
      
3503

3504
    } else {
3505 3506
        if(dlsch0->rnti != 0xffff)
        {
3507 3508 3509 3510 3511 3512
      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d,TBS %d)\n",
	    ue->Mod_id,dlsch0->rnti,
	    harq_pid,frame_rx,subframe_rx,
	    dlsch0->harq_processes[harq_pid]->rvidx,
	    dlsch0->harq_processes[harq_pid]->mcs,
	    dlsch0->harq_processes[harq_pid]->TBS);
3513
        }
3514

3515 3516 3517 3518 3519 3520 3521 3522
#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");
3523
#endif
3524

3525 3526 3527 3528 3529 3530 3531
      
      if (ue->mac_enabled == 1) {
	switch (pdsch) {
	case PDSCH:
	  mac_xface->ue_send_sdu(ue->Mod_id,
				 CC_id,
				 frame_rx,
3532
         subframe_rx,
3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544
				 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;
3545 3546 3547 3548 3549 3550 3551 3552
	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;
3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564
	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;
	}
3565
      }
3566 3567 3568 3569 3570 3571 3572 3573
      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;
    }
  
  
      
3574
#ifdef DEBUG_PHY_PROC
3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591
    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]);
    }
3592
    
3593 3594
#endif

3595
  }
3596

3597

3598 3599 3600
}
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
3601
 
3602 3603 3604 3605 3606
  int l,l2;
  int pilot1;
  int pmch_flag=0;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
3607

3608
  
3609

3610
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
3611

3612
#if T_TRACER
hbilel's avatar
hbilel committed
3613
  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
3614
#endif
3615

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

3620
  start_meas(&ue->phy_proc_rx);
3621

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


3625 3626 3627 3628 3629
  // deactivate reception until we scan pdcch
  if (ue->dlsch[eNB_id][0])
    ue->dlsch[eNB_id][0]->active = 0;
  if (ue->dlsch[eNB_id][1])
    ue->dlsch[eNB_id][1]->active = 0;
3630

3631 3632
  if (ue->dlsch_SI[eNB_id])
    ue->dlsch_SI[eNB_id]->active = 0;
3633 3634
  if (ue->dlsch_p[eNB_id])
    ue->dlsch_p[eNB_id]->active = 0;
3635 3636
  if (ue->dlsch_ra[eNB_id])
    ue->dlsch_ra[eNB_id]->active = 0;
3637

3638
  
3639
#ifdef DEBUG_PHY_PROC
Cedric Roux's avatar
Cedric Roux committed
3640
  LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
3641 3642
	(r_type == multicast_relay) ? "RN/UE" : "UE",
	ue->Mod_id,frame_rx, subframe_rx);
3643 3644
#endif

3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659
  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;
  }
  
3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672
  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;
  }
  for (; l<=l2; l++) {
3673 3674 3675 3676 3677 3678
    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),
3679
	       0,
3680 3681 3682 3683
	       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);
3684
    }
3685
    
3686
    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
3687 3688 3689 3690 3691 3692 3693 3694
    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);
      }
3695
      LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[eNB_id]->num_pdcch_symbols);
3696
    }
3697 3698
    
  } // for l=1..l2
3699
  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); 
3700 3701 3702 3703 3704 3705
  
    // If this is PMCH, call procedures and return
  if (pmch_flag == 1) {
    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
    return 0;
  }
3706

3707 3708 3709
  slot_fep(ue,
	   0,
	   1+(subframe_rx<<1),
3710
	   0,
3711 3712
	   0,
	   0);
3713

3714 3715 3716 3717
  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
 
  // do procedures for C-RNTI
  if (ue->dlsch[eNB_id][0]->active == 1) {
3718
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
3719 3720 3721 3722 3723 3724 3725 3726 3727
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
			ue->dlsch[eNB_id][0],
			NULL,
			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3728
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
3729 3730 3731
  }
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
3732
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
3733 3734 3735 3736 3737 3738 3739 3740 3741
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			SI_PDSCH,
			ue->dlsch_SI[eNB_id],
			NULL,
			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3742
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
3743
  }
3744 3745 3746

  // do procedures for SI-RNTI
  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
3747
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
3748 3749 3750 3751 3752 3753 3754 3755 3756
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			P_PDSCH,
			ue->dlsch_p[eNB_id],
			NULL,
			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3757
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
3758 3759
  }

3760 3761
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
3762
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
3763 3764 3765 3766 3767 3768 3769 3770 3771
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			RA_PDSCH,
			ue->dlsch_ra[eNB_id],
			NULL,
			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
3772
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
3773 3774 3775 3776 3777 3778 3779 3780 3781 3782
  }    
  
  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),
3783
		 0,
3784 3785 3786 3787 3788 3789
		 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);
      }
      
3790
      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
3791 3792
      
    } // for l=1..l2
3793 3794 3795 3796 3797 3798 3799 3800

    // 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),
3801
         0,
3802 3803 3804
         0,
         0);
    }
3805
  } // not an S-subframe
3806

3807 3808 3809 3810 3811 3812
  // run pbch procedures if subframe is 0
  if (subframe_rx == 0)
    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
   
  // do procedures for C-RNTI
  if (ue->dlsch[eNB_id][0]->active == 1) {
3813
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
			ue->dlsch[eNB_id][0],
			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,
			PDSCH,
			ue->dlsch[eNB_id][0],
			NULL,
			&ue->dlsch_errors[eNB_id],
			mode,
			abstraction_flag);
3832
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
3833

3834
  }
3835

3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846
  // 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);
3847

3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858
    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;
  }
3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882

  // 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;
  }
3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904
  // 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;
  }
3905

3906
  if (subframe_rx==9) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3907
    if (frame_rx % 10 == 0) {
3908
      if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
3909
	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]);
3910

3911 3912
      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
3913
    }
3914 3915


3916 3917
    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];
3918
    LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
3919 3920
	  ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
	  ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
3921 3922 3923 3924 3925 3926 3927

  #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

3928
  }
3929 3930


jiangx's avatar
jiangx committed
3931 3932

#ifdef EMOS
3933
  phy_procedures_emos_UE_RX(ue,slot,eNB_id);
jiangx's avatar
jiangx committed
3934 3935
#endif

3936
     
3937
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
3938
  stop_meas(&ue->phy_proc_rx);
3939
  return (0);
3940
}
3941
   
3942
#ifdef Rel10
3943 3944
int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
{
3945
   
3946
  int do_proc =0; // do nothing by default
3947
   
3948
  switch(r_type) {
3949
  case no_relay:
3950
    do_proc=no_relay; // perform the normal UE operation
3951
    break;
3952
     
3953
  case multicast_relay:
Raymond Knopp's avatar
 
Raymond Knopp committed
3954
    if (slot_rx > 12)
3955 3956
      do_proc = 0; // do nothing
    else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
3957
      do_proc = multicast_relay ; // do PHY procedures UE RX
3958
     
3959
    break;
3960
     
3961 3962 3963 3964 3965
  default: // should'not be here
    LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
    do_proc= 0;
    break;
  }
3966
   
3967 3968
  return do_proc;
}
3969
#endif
3970 3971 3972 3973
 
 
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)
3974
{
3975
#if defined(ENABLE_ITTI)
3976 3977 3978 3979 3980
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  unsigned int  Mod_id;
  int           result;
3981
#endif
3982 3983 3984 3985 3986
   
  int           frame_rx = proc->frame_rx;
  int           frame_tx = proc->frame_tx;
  int           subframe_rx = proc->subframe_rx;
  int           subframe_tx = proc->subframe_tx;
3987
#undef DEBUG_PHY_PROC
3988
   
3989
  UE_L2_STATE_t ret;
3990
  int slot;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3991

3992 3993
  if (ue->mac_enabled == 0) {
    ue->UE_mode[eNB_id]=PUSCH;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3994
  }
3995 3996
   
   
3997
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
3998
  start_meas(&ue->phy_proc);
3999
#if defined(ENABLE_ITTI)
4000

4001 4002
  do {
    // Checks if a message has been sent to PHY sub-task
4003
    itti_poll_msg (TASK_PHY_UE, &msg_p);
4004
     
4005 4006 4007 4008
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance - NB_eNB_INST;
4009
       
4010
      switch (ITTI_MSG_ID(msg_p)) {
4011
      case PHY_FIND_CELL_REQ:
4012 4013 4014 4015 4016
	LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
	 
	/* TODO process the message */
	break;
	 
4017
      default:
4018 4019
	LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
	break;
4020
      }
4021
       
4022 4023
      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
4024 4025
    }
  } while(msg_p != NULL);
4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037
   
#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)) {
4038
#ifdef Rel10
4039 4040
       
      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
4041
#endif
4042 4043 4044 4045 4046 4047 4048 4049 4050 4051
	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)) {
4052
#ifdef Rel10
4053 4054
	 
      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
4055
#endif
4056
	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
4057
    }
4058 4059 4060
       
    if (ue->mac_enabled==1) {
      if (slot==0) {
4061 4062 4063 4064 4065 4066 4067 4068
        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*/);
4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091
	   
	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
4092
}
4093 4094