phy_procedures_lte_ue.c 95.6 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


ghaddab's avatar
ghaddab committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
19
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
ghaddab's avatar
ghaddab committed
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

28
*******************************************************************************/
29 30 31

/*! \file phy_procedures_lte_ue.c
 * \brief Implementation of UE procedures from 36.213 LTE specifications
32
 * \author R. Knopp, F. Kaltenberger, N. Nikaein
33 34 35
 * \date 2011
 * \version 0.1
 * \company Eurecom
36
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
37 38 39 40
 * \note
 * \warning
 */

41
#include "assertions.h"
42 43 44 45 46 47 48 49 50 51
#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
52
#define DEBUG_PHY_PROC
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

#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"

68 69 70 71
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

72 73 74 75 76 77 78 79 80 81 82

#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
83
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
84
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
85 86
#endif

87

88

89
void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid)
90
{
91
  unsigned int coded_bits_per_codeword;
92 93 94 95 96 97 98 99
  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,
100
                                  proc->frame_rx,subframe);
101 102 103 104

  write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[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[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[0]->rxdataF_comp0[0],300*12,1,1);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[0]->llr[0],coded_bits_per_codeword,1,0);
113

114 115
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[0]->dl_ch_mag0,300*12,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[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,subframe);
130
  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",
131 132
        ue->Mod_id,
	ue->frame_parms.ofdm_symbol_size,
133
	nsymb,
134 135 136 137
        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,
138
        coded_bits_per_codeword);
139

140
  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);
141

142 143 144
  write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  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);
145
  /*
146 147 148 149
    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);
150
  */
151 152
  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);
153

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

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

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

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

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;

208 209
  if (gain_dB < -20)
    return(AMP/10);
Raymond Knopp's avatar
 
Raymond Knopp committed
210 211 212 213 214 215 216 217 218 219 220 221

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

222 223
#endif

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

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

244 245 246
  write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
  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);
247
  /*
248 249 250 251
    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);
252
  */
253 254
  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);
255

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

260

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

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

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

270
  //[NUMBER_OF_CONNECTED_eNB_MAX][2];
271 272
  for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
    for(j=0; j<2; j++) {
273
      //DL HARQ
274 275 276
      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;
277
        }
278 279
      }
    }
280

281
    //UL HARQ
282 283 284
    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;
285
        //Set NDIs for all UL HARQs to 0
286
        //  ue->ulsch[i]->harq_processes[k]->Ndi = 0;
287

288 289
      }
    }
290

291
    // flush Msg3 buffer
292
    ue->ulsch_Msg3_active[i] = 0;
293

294 295 296
  }
}

297 298
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
299 300

  // if contention resolution fails, go back to PRACH
Raymond Knopp's avatar
 
Raymond Knopp committed
301
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
302
  LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0 and State RRC_IDLE\n",Mod_id);
303 304 305
  //mac_xface->macphy_exit("");
}

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

  int i;

311
  LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded\n",Mod_id);
312

313
  PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
314
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
315

316
  for (i=0; i<8; i++) {
317 318 319
    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;
320
    }
321 322 323 324 325
  }


}

326 327
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
328

Raymond Knopp's avatar
 
Raymond Knopp committed
329
  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
330 331

}
332
void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) {
333

334
  ue->timing_advance = timing_advance*4;
335 336


337
#ifdef DEBUG_PHY_PROC
338
  LOG_I(PHY,"[UE %d] Frame %d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, ue->timing_advance);
339 340 341 342
#endif

}

343 344
void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
{
345

346
  //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
347

348
  // timing advance has Q1.5 format
349
  timing_advance = timing_advance - 31;
350

351 352
  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!!!

353

354
  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);
355

356 357 358

}

359
uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
360 361
{

362 363
  int subframe=proc->subframe_tx;

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

368 369
  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)
370
      return(1);
371 372
  } 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))
373
      return(1);
374
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 34) { // 20 ms SR period
375
    if ((10*(proc->frame_tx&1)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
376
      return(1);
377
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 74) { // 40 ms SR period
378
    if ((10*(proc->frame_tx&3)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
379
      return(1);
380
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 154) { // 80 ms SR period
381
    if ((10*(proc->frame_tx&7)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
382 383 384 385 386 387
      return(1);
  }

  return(0);
}

388
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
389
		      UE_rxtx_proc_t *proc,
390 391 392 393
                      uint8_t eNB_id,
                      uint8_t *b,
                      uint8_t SR)
{
394

395
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
396
  uint8_t nCCE0,nCCE1,harq_ack1,harq_ack0;
397
  ANFBmode_t bundling_flag;
398
  uint16_t n1_pucch0=0,n1_pucch1=0;
399 400 401 402
  int subframe_offset;
  int sf;
  int M;
  // clear this, important for case where n1_pucch selection is not used
403
  int subframe=proc->subframe_tx;
404

405
  ue->pucch_sel[subframe] = 0;
406 407 408

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

    if (SR == 0)
412
      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[eNB_id]->nCCE[sf]);
413
    else
414
      return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
415
  } else {
416

417
    bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
418
#ifdef DEBUG_PHY_PROC
419 420

    if (bundling_flag==bundling) {
421
      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,
422
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
423
    } else {
424
      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,
425
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
426
    }
427

428
#endif
429

430 431 432 433 434
    switch (frame_parms->tdd_config) {
    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL

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

436 437
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
      if (subframe == 2) {  // ACK subframes 5 (forget 6)
438 439 440 441 442 443 444 445 446 447 448
        subframe_offset = 5;
        M=2;
      } else if (subframe == 3) { // ACK subframe 9
        subframe_offset = 9;
      } else if (subframe == 7) { // ACK subframes 0 (forget 1)
        subframe_offset = 0;
        M=2;
      } else if (subframe == 8) { // ACK subframes 4
        subframe_offset = 4;
      } else {
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
449
              ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config);
450
        return(0);
451 452 453 454
      }


      // i=0
455
      nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[subframe_offset];
456
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
457 458

      // set ACK/NAK to values if not DTX
459 460
      if (ue->dlsch[eNB_id][0]->harq_ack[subframe_offset].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
        harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[subframe_offset].ack;
461

462 463

      if (harq_ack0!=2) {  // DTX
464 465 466
        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)
467
          ue->pucch_sel[subframe] = 0;
468 469 470
          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;
471
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
472
        }
473 474 475 476
      }


      break;
477

478 479 480 481 482 483 484 485 486
    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)
      subframe_offset = (subframe-2)<<1;
      // i=0
487
      nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[5+subframe_offset];
488
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
489
      // i=1
490
      nCCE1 = ue->pdcch_vars[eNB_id]->nCCE[(6+subframe_offset)%10];
491
      n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
492 493

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

497 498
      if (ue->dlsch[eNB_id][0]->harq_ack[5+subframe_offset].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
        harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[5+subframe_offset].ack;
499

500 501

      if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
502 503 504 505 506 507 508 509 510

        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;

511
          ue->pucch_sel[subframe] = 1;
512 513 514 515 516 517 518 519 520 521
          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)) {
522
            ue->pucch_sel[subframe] = 0;
523 524
            return(n1_pucch0);
          } else {
525
            ue->pucch_sel[subframe] = 1;
526 527 528 529 530 531 532 533 534
            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;
535
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
536 537 538 539
        }
      } 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;
540
          ue->pucch_sel[subframe] = 0;
541 542 543 544
          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];
545
          ue->pucch_sel[subframe] = 0;
546 547 548 549
          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];
550
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
551
        }
552
      }
553

554 555
      break;

556
    }  // switch tdd_config
557
  }
558

559
  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n",proc->frame_tx);
560 561 562 563 564 565
  return(-1);
}


#ifdef EMOS
/*
566
  void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) {
567
  uint8_t harq_pid;
568

569 570

  if (next_slot%2==0) {
571 572 573 574 575 576 577
  // 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;
  }
578

579 580 581 582 583 584 585 586 587 588 589 590 591
  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;
  }
  }
592 593 594 595
  }
*/
#endif

596
void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc) {
597

598
  int aa;
599
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
600

601 602 603 604
  int nsymb;
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  int ulsch_start;
kaltenbe's avatar
kaltenbe committed
605
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
606
  int overflow=0;
607
  int k,l;
608
  int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
609 610
#endif

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 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
  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-
		 ue->hw_timing_advance-
		 ue->timing_advance-
		 ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
#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
  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;
    }
687
#endif
688 689 690 691 692
#endif
    
  } //nb_antennas_tx
  
  stop_meas(&ue->ofdm_mod_stats);
693 694 695



696
}
697

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

700 701 702 703
  int frame_tx = proc->frame_tx;
  int subframe_tx = proc->subframe_tx;
  int prach_power;
  PRACH_RESOURCES_t prach_resources_local;
704

705
  ue->generate_prach=0;
706

707 708 709 710 711
  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;
  }
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 740 741 742 743 744 745 746 747
  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) ) {
      ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,
							   ue->CC_id,
							   frame_tx,
							   eNB_id,
							   subframe_tx);
      //    LOG_I(PHY,"Got prach_resources for eNB %d address %d, RRCCommon %d\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[Mod_id].radioResourceConfigCommon);
    }
  }
  
  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) {
      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
	    ue->Mod_id,
	    frame_tx,
	    subframe_tx,
	    ue->prach_resources[eNB_id]->ra_PreambleIndex,
	    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);
      
      if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
	ue->tx_power_dBm = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
748
      }
749 750 751
      else {
	ue->tx_power_dBm = ue->tx_power_max_dBm;
	ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
Florian Kaltenberger's avatar
Florian Kaltenberger committed
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 794 795 796 797 798 799 800 801 802
      
      ue->tx_total_RE = 96;
      
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
      ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm,
					       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,
	      ue->tx_power_dBm,
	      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),
	    ue->tx_power_dBm,
	    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;
      if (ue->mac_enabled==1){
	mac_xface->Msg1_transmitted(ue->Mod_id,
				    ue->CC_id,
				    frame_tx,
				    eNB_id);
      }
    }
    
    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));
    
  }	  
  
803

804 805 806 807 808 809 810 811 812 813 814 815
  // 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;
}
816

817
void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
818

819 820 821 822 823 824 825 826 827 828 829 830
  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;
  uint8_t ack_status=0;
  uint16_t first_rb, nb_rb;
  unsigned int input_buffer_length;
  int i;
  int aa;
  int tx_amp;
831 832
  uint8_t ulsch_input_buffer[2700] __attribute__ ((aligned(16)));
  uint8_t access_mode;
833

834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891
  // 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) {
	LOG_E(PHY,"[UE%d] Frame %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
	      Mod_id,frame_tx);
	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;
    }
  }
  
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
    
    ue->generate_ul_signal[eNB_id] = 1;
    
    // deactivate service request
    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
    
    ack_status = get_ack(&ue->frame_parms,
			 ue->dlsch[eNB_id][0]->harq_ack,
			 subframe_tx,
			 ue->ulsch[eNB_id]->o_ACK);
    
    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
    
    
    
    
892
#ifdef DEBUG_PHY_PROC
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955
    LOG_D(PHY,
	  "[UE  %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d\n",
	  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],
	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
#endif
    
    if (ack_status > 0) {
      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
	    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);
    }
    
    
    
    
    
    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;
	}
      }
      
956
#ifdef PHY_ABSTRACTION
957 958 959 960
      else {
	ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,harq_pid,0);
      }
      
961
#endif
962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
      
      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);
	}
	
991 992
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
993 994 995 996 997 998
	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");
999 1000
#endif
#endif
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
      }
      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,
			   ue->transmission_mode[eNB_id],0,
			   0)!=0) {  //  Nbundled, to be updated!!!!
	  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
1024
	}
1025 1026
      }
      
1027
#ifdef PHY_ABSTRACTION
1028 1029 1030 1031
      else {
	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
      }
      
1032
#endif
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
      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);
	ue->tx_power_dBm = ue->ulsch[eNB_id]->Po_PUSCH;
      }
      else {
	ue->tx_power_dBm = ue->tx_power_max_dBm;
      }
      ue->tx_total_RE = nb_rb*12;
      
kaltenbe's avatar
kaltenbe committed
1046
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1047 1048 1049 1050
      tx_amp = get_tx_amp(ue->tx_power_dBm,
			  ue->tx_power_max_dBm,
			  ue->frame_parms.N_RB_UL,
			  nb_rb);
1051
#else
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
      tx_amp = AMP;
#endif
      LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
	    Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm,ue->tx_power_max_dBm, tx_amp);
      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
1067
			   tx_amp,
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
			   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
}
1082

1083

1084
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1085 1086


1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
  uint8_t pucch_ack_payload[2];
  uint8_t n1_pucch;
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
  uint8_t SR_payload;
  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;
  int8_t Po_PUCCH;
1099

1100 1101 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
  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");
  }
  
  // Check for SR and do ACK/NACK accordingly
  if (is_SR_TXOp(ue,proc,eNB_id)==1) {
    LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d: got SR_TXOp, Checking for SR for PUSCH from MAC\n",
	  Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx);
    
    if (ue->mac_enabled==1) {
      SR_payload = mac_xface->ue_get_SR(Mod_id,
					CC_id,
					frame_tx,
					eNB_id,
					ue->pdcch_vars[eNB_id]->crnti,
					subframe_tx); // subframe used for meas gap
    }
    else {
      SR_payload = 1;
    }
	    
    if (SR_payload>0) {
      ue->generate_ul_signal[eNB_id] = 1;
      LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d got the SR for PUSCH is %d\n",
	    Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx,SR_payload);
    } else {
      ue->sr[subframe_tx]=0;
    }
  } else {
    SR_payload=0;
  }
        	  
  if (get_ack(&ue->frame_parms,
	      ue->dlsch[eNB_id][0]->harq_ack,
	      subframe_tx,pucch_ack_payload) > 0) {
    // we need to transmit ACK/NAK in this subframe
	    
    ue->generate_ul_signal[eNB_id] = 1;
	    
    n1_pucch = get_n1_pucch(ue,
			    proc,
			    eNB_id,
			    pucch_ack_payload,
			    SR_payload);
	    
    if (ue->mac_enabled == 1) {
      Po_PUCCH = pucch_power_cntl(ue,proc,eNB_id,format);
    } 
    else {
      Po_PUCCH = ue->tx_power_max_dBm;
    }
    ue->tx_power_dBm = Po_PUCCH;
    ue->tx_total_RE = 12;
	    
kaltenbe's avatar
kaltenbe committed
1162
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1163 1164 1165 1166
    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
1167
#else
1168
    tx_amp = AMP;
Raymond Knopp's avatar
 
Raymond Knopp committed
1169
#endif
1170 1171 1172 1173 1174
	    
    if (SR_payload>0) {
      LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), n1_pucch %d, Po_PUCCH, amp %d\n",
	    Mod_id,
	    ue->dlsch[eNB_id][0]->rnti,
Raymond Knopp's avatar
 
Raymond Knopp committed
1175
	    frame_tx, subframe_tx,
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
	    pucch_ack_payload[0],pucch_ack_payload[1],
	    ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
	    Po_PUCCH,
	    tx_amp);
    } else {
      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
	    Mod_id,
	    ue->dlsch[eNB_id][0]->rnti,
	    frame_tx, subframe_tx,
	    n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
	    Po_PUCCH,
	    tx_amp);
    }
	    
    if (abstraction_flag == 0) {
	      
      generate_pucch(ue->common_vars.txdataF,
		     &ue->frame_parms,
		     ue->ncs_cell,
		     format,
		     &ue->pucch_config_dedicated[eNB_id],
		     n1_pucch,
		     0,  // n2_pucch
		     1,  // shortened format
		     pucch_ack_payload,
		     tx_amp,
		     subframe_tx);
	      
    } else {
1205
#ifdef PHY_ABSTRACTION
1206 1207 1208 1209 1210 1211
      LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
      generate_pucch_emul(ue,
			  proc,
			  format,
			  ue->frame_parms.pucch_config_common.nCS_AN,
			  pucch_ack_payload,
1212
			  SR_payload);
1213
#endif
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
    }
  } else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC
	    
    if (ue->mac_enabled == 1) {
      Po_PUCCH = pucch_power_cntl(ue,proc,eNB_id,pucch_format1);
    }
    else {
      Po_PUCCH = ue->tx_power_max_dBm;
    }
    ue->tx_power_dBm = Po_PUCCH;
    ue->tx_total_RE = 12;
	    
kaltenbe's avatar
kaltenbe committed
1226
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1227 1228 1229 1230
    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
1231
#else
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
    tx_amp = AMP;
#endif
    LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), n1_pucch %d, Po_PUCCH %d\n",
	  Mod_id,
	  ue->dlsch[eNB_id][0]->rnti,
	  frame_tx, subframe_tx,
	  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
	  Po_PUCCH);
	    
    if (abstraction_flag == 0) {
	      
      generate_pucch(ue->common_vars.txdataF,
		     &ue->frame_parms,
		     ue->ncs_cell,
		     pucch_format1,
		     &ue->pucch_config_dedicated[eNB_id],
		     ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
		     0,  // n2_pucch
		     1,  // shortened format
		     pucch_ack_payload,  // this is ignored anyway, we just need a pointer
		     tx_amp,
		     subframe_tx);
    } else {
      LOG_D(PHY,"Calling generate_pucch_emul ...\n");
      generate_pucch_emul(ue,
			  proc,
			  pucch_format1,
			  ue->frame_parms.pucch_config_common.nCS_AN,
			  pucch_ack_payload,
			  SR_payload);
1262

1263 1264 1265
    }
  } // SR_Payload==1
}
1266

1267 1268
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) {
  
1269

1270 1271 1272 1273 1274
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
  int32_t ulsch_start=0;
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  unsigned int aa;
1275 1276 1277 1278




1279
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
1280

1281
  ue->generate_ul_signal[eNB_id] = 0;
1282

1283
  start_meas(&ue->phy_proc_tx);
1284

1285 1286
#ifdef EMOS
  //phy_procedures_emos_UE_TX(next_slot);
1287 1288
#endif

1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
  ue->tx_power_dBm=-127;
      
  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) {
1300

1301
    ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
1302

1303 1304 1305 1306
  }
  	  
  if (ue->UE_mode[eNB_id] == PUSCH) { // check if we need to use PUCCH 1a/1b
  
1307

1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
  } // 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);
      }
	    
1357
#endif
1358 1359 1360 1361 1362 1363 1364 1365 1366
    } 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
1367

1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
  	
  if (abstraction_flag == 0) {
	  
    if (ue->generate_ul_signal[eNB_id] == 1 )
      ulsch_common_procedures(ue,proc);
    else {  // no uplink so clear signal buffer instead
#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-
		     ue->hw_timing_advance-
		     ue->timing_advance-
		     ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
#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
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
	memset(&ue->common_vars.txdata[aa][ulsch_start],0,frame_parms->samples_per_tti<<2);
1384
      }
1385
    }
1386

1387 1388 1389 1390 1391 1392 1393 1394
  } // 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
    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
1395

1396
      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
1397
    }
1398 1399 1400 1401 1402 1403
  } // mode is PRACH
  else {
    ue->generate_prach=0;
  }
    
      
1404
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
1405
  stop_meas(&ue->phy_proc_tx);
1406 1407
}

1408
void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
1409
{
1410
  int aa;//i,aa;
1411
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
1412
  
1413
  if (abstraction_flag==0) {
1414
    
1415
    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
1416
#if defined(EXMIMO) //this is the EXPRESS MIMO case
1417 1418
      int i;
      // set the whole tx buffer to RX
1419
      for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
1420 1421
	ue->common_vars.txdata[aa][i] = 0x00010001;
      
1422
#else //this is the normal case
1423
      memset(&ue->common_vars.txdata[aa][0],0,
1424
	     (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
1425
#endif //else EXMIMO
1426
      
1427 1428 1429 1430
    }
  }
}

1431
void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode)
1432
{
1433
  
1434
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
Raymond Knopp's avatar
 
Raymond Knopp committed
1435

1436
  int subframe_rx = proc->subframe_rx;
1437

1438
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
1439 1440

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

1445
      lte_ue_measurements(ue,
1446 1447 1448
			  (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
			  (subframe_rx == 1) ? 1 : 0,
			  0);
1449
    } else {
1450
      lte_ue_measurements(ue,
1451 1452 1453
			  0,
			  0,
			  1);
1454 1455 1456
    }
  }

1457
  if (l==(6-ue->frame_parms.Ncp)) {
1458
	
1459
    // make sure we have signal from PSS/SSS for N0 measurement
1460

1461
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
1462
    ue_rrc_measurements(ue,
1463 1464
			subframe_rx,
			abstraction_flag);
1465
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
1466

Raymond Knopp's avatar
 
Raymond Knopp committed
1467
    if (abstraction_flag==1)
1468
      ue->sinr_eff =  sinr_eff_cqi_calc(ue, 0);
1469

1470
  }
1471

1472
  if ((subframe_rx==0) && (l==(4-frame_parms->Ncp))) {
1473

1474
    // AGC
Raymond Knopp's avatar
 
Raymond Knopp committed
1475

1476
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
Raymond Knopp's avatar
 
Raymond Knopp committed
1477

1478
#ifndef OAI_USRP
kaltenbe's avatar
kaltenbe committed
1479 1480
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
1481
    phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0);
kaltenbe's avatar
kaltenbe committed
1482 1483
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1484
#endif
1485

1486 1487
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
1488
    eNB_id = 0;
1489
    
1490
    if (abstraction_flag == 0)
1491
      lte_adjust_synch(&ue->frame_parms,
1492 1493 1494 1495
		       ue,
		       eNB_id,
		       0,
		       16384);
1496
    
1497
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
1498

1499
  }
1500

1501
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
1502 1503 1504
}

#ifdef EMOS
1505
void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
1506
{
1507

1508 1509 1510
  uint8_t i,j;
  //uint16_t last_slot_emos;
  uint32_t bytes;
1511
  int Mod_id = ue->Mod_id;
1512 1513

  /*
1514
    if (last_slot<2)
1515
    last_slot_emos = last_slot;
1516
    else if (last_slot>9)
1517
    last_slot_emos = last_slot - 8;
1518
    else {
1519 1520
    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");
1521
    }
1522 1523 1524
  */

#ifdef EMOS_CHANNEL
1525

1526
  if ((last_slot==10) || (last_slot==11)) {
1527 1528
    for (i=0; i<ue->frame_parms.nb_antennas_rx; i++)
      for (j=0; j<ue->frame_parms.nb_antennas_tx; j++) {
1529 1530 1531 1532 1533 1534 1535 1536
	// 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));
1537 1538
      }
  }
1539

1540
#endif
1541

1542 1543
  if (last_slot==0) {
    emos_dump_UE.timestamp = rt_get_time_ns();
1544
    emos_dump_UE.frame_rx = proc->frame_rx;
1545 1546 1547 1548 1549 1550
    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;
1551
    emos_dump_UE.eNb_id = eNB_id;
1552
    memcpy(&emos_dump_UE.PHY_measurements,&measurements,sizeof(PHY_MEASUREMENTS));
1553
  }
1554

1555
  if (last_slot==1) {
1556 1557 1558 1559
    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;
1560
  }
1561

1562
  if (last_slot==19) {
1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575
    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;
1576 1577 1578
    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));
1579

1580
    if (bytes!=sizeof(fifo_dump_emos_UE)) {
1581
      LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot);
1582
    } else {
1583 1584
      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);
1585 1586 1587
      }
    }
  }
1588

1589 1590 1591 1592
}
#endif


1593
void restart_phy(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag)
1594
{
1595

1596 1597
  //  uint8_t last_slot;
  uint8_t i;
1598
  LOG_I(PHY,"[UE  %d] frame %d, slot %d, restarting PHY!\n",ue->Mod_id,proc->frame_rx,proc->subframe_rx);
1599
  mac_xface->macphy_exit("restart_phy called");
1600
  //   first_run = 1;
1601

1602
  if (abstraction_flag ==0 ) {
1603
    ue->UE_mode[eNB_id] = NOT_SYNCHED;
1604
  } else {
1605 1606
    ue->UE_mode[eNB_id] = PRACH;
    ue->prach_resources[eNB_id]=NULL;
1607
  }
1608

1609 1610
  proc->frame_rx = -1;
  proc->frame_tx = -1;
1611 1612
  //  ue->synch_wait_cnt=0;
  //  ue->sched_cnt=-1;
1613

1614 1615
  ue->pbch_vars[eNB_id]->pdu_errors_conseq=0;
  ue->pbch_vars[eNB_id]->pdu_errors=0;
1616

1617 1618 1619 1620
  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;
1621

1622 1623 1624 1625 1626 1627 1628 1629 1630
  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;
  ue->dlsch_SI_errors[eNB_id] = 0;
  ue->dlsch_ra_errors[eNB_id] = 0;
1631

1632
  ue->dlsch_mch_received[eNB_id] = 0;
1633 1634

  for (i=0; i < MAX_MBSFN_AREA ; i ++) {
1635 1636 1637 1638 1639 1640 1641
    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;
1642 1643
  }

1644 1645 1646 1647
  //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;
1648 1649 1650
}


1651
void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag)
1652
{
1653 1654 1655

  //  int i;
  int pbch_tx_ant=0;
1656 1657 1658 1659
  uint8_t pbch_phase;
  uint16_t frame_tx;
  static uint8_t first_run = 1;
  uint8_t pbch_trials = 0;
1660

1661
  DevAssert(ue);
1662 1663 1664

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

1666
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
1667

Raymond Knopp's avatar
 
Raymond Knopp committed
1668
  pbch_phase=(frame_rx%4);
1669

1670 1671
  if (pbch_phase>=4)
    pbch_phase=0;
1672 1673 1674

  for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
    //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
1675
    //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);
1676
    if (abstraction_flag == 0) {
1677
      pbch_tx_ant = rx_pbch(&ue->common_vars,
1678 1679 1680 1681 1682 1683
			    ue->pbch_vars[eNB_id],
			    &ue->frame_parms,
			    eNB_id,
			    ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
			    ue->high_speed_flag,
			    pbch_phase);
1684 1685 1686 1687



    }
1688

1689 1690
#ifdef PHY_ABSTRACTION
    else {
1691
      pbch_tx_ant = rx_pbch_emul(ue,
1692 1693
				 eNB_id,
				 pbch_phase);
1694
    }
1695

1696 1697 1698 1699 1700
#endif

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

1702
    pbch_phase++;
1703

1704 1705 1706 1707 1708 1709 1710 1711
    if (pbch_phase>=4)
      pbch_phase=0;
  }



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

1712
    if (pbch_tx_ant>2) {
1713
      LOG_W(PHY,"[openair][SCHED][SYNCH] PBCH decoding: pbch_tx_ant>2 not supported\n");
1714
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
1715 1716 1717 1718
      return;
    }


1719 1720 1721
    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));
1722 1723
    frame_tx += pbch_phase;

1724 1725 1726
    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
1727 1728
    }
    
1729 1730
#ifdef EMOS
    //emos_dump_UE.frame_tx = frame_tx;
1731
    //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1];
1732 1733 1734 1735
#endif

    if (first_run) {
      first_run = 0;
1736 1737 1738 1739 1740 1741

      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",
1742 1743 1744 1745 1746
	    ue->Mod_id,
	    frame_rx,
	    subframe_rx,
	    pbch_tx_ant,
	    frame_tx,
1747 1748 1749
	    pbch_phase,
	    ue->rx_offset,
	    proc->frame_rx);
1750
      frame_rx = proc->frame_rx;
1751
      
1752
    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
1753
      //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763
      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",
	    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);
1764
      ue->proc.proc_rxtx[1].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
1765
      proc->frame_tx = proc->frame_rx;
1766
      ue->proc.proc_rxtx[1].frame_tx = proc->frame_rx;
1767 1768
      frame_rx = proc->frame_rx;

1769
    }
1770

1771
#ifdef DEBUG_PHY_PROC
1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
    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);
1782
#endif
1783

1784
  } else { 
1785
    /*
1786
    LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
1787
	  ue->Mod_id,frame_rx, subframe_rx);
1788

1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802
    LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);


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

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

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

1804 1805 1806 1807
    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
1808 1809
    }
    else{
1810
      if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1811 1812 1813
	LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
	mac_xface->macphy_exit("More that 100 consecutive PBCH errors!");
      }
1814
    }
1815 1816
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
1817
  if (frame_rx % 100 == 0) {
1818 1819
    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;
1820
  }
1821 1822

#ifdef DEBUG_PHY_PROC
1823
  LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
1824 1825 1826
	ue->Mod_id,frame_rx, subframe_rx,
	ue->pbch_vars[eNB_id]->pdu_errors,
	ue->pbch_vars[eNB_id]->pdu_errors_conseq);
1827
#endif
1828
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
1829 1830
}

1831
int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag)
1832
{
1833 1834

  unsigned int dci_cnt=0, i;
1835

1836 1837
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
1838
  DCI_ALLOC_t dci_alloc_rx[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
1839

1840

1841 1842 1843 1844 1845 1846
#ifdef PHY_ABSTRACTION
  int CC_id;
  int UE_id;
  uint8_t harq_pid;
#endif

1847
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
1848
  start_meas(&ue->dlsch_rx_pdcch_stats);
1849

1850 1851
  //  if (subframe_rx != 5)
  //    return 0;
1852 1853
  if (abstraction_flag == 0)  {

1854
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
1855
    rx_pdcch(&ue->common_vars,
1856 1857 1858 1859 1860 1861 1862
	     ue->pdcch_vars,
	     &ue->frame_parms,
	     subframe_rx,
	     eNB_id,
	     (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
	     ue->high_speed_flag,
	     ue->is_secondary_ue);
1863 1864


1865 1866
    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);
1867
    dci_cnt = dci_decoding_procedure(ue,
1868 1869 1870 1871
				     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);
1872
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
1873
    //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
1874

1875
    if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
1876
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
1877 1878
      rx_phich(ue,proc,
	       subframe_rx,eNB_id);
1879
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
1880 1881
    }
  }
1882

1883 1884
#ifdef PHY_ABSTRACTION
  else {
1885 1886
    for (i=0; i<NB_eNB_INST; i++) {
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
1887 1888
	if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
	  break;
1889

1890
      if (CC_id < MAX_NUM_CCs)
1891
	break;
1892
    }
1893

1894
    if (i==NB_eNB_INST) {
1895
      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);
1896
      mac_xface->macphy_exit("Could not find attached eNB for DCI emulation");
1897
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
1898 1899
      return(-1);
    }
1900

1901
    LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
1902
    dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars,
1903 1904 1905 1906 1907
					  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);
1908
    //    printf("DCI: dci_cnt %d\n",dci_cnt);
1909
    UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
1910

1911
    if (UE_id>=0) {
1912
      //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
1913
      if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924
	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
1925 1926 1927
      } // This is a PHICH subframe
    } // UE_id exists
  }
1928

1929 1930
#endif

1931

1932
  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt);
1933 1934

 
1935

1936
  ue->pdcch_vars[eNB_id]->dci_received += dci_cnt;
1937

1938
#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
1939
  //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt;
1940 1941
#endif

1942 1943 1944
  for (i=0; i<dci_cnt; i++) {


1945

1946 1947
    if ((ue->UE_mode[eNB_id]>PRACH) &&
	(dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) &&
1948 1949
	(dci_alloc_rx[i].format != format0)) {
      
1950

Raymond Knopp's avatar
 
Raymond Knopp committed
1951
      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
1952 1953 1954 1955 1956 1957
	    ue->Mod_id,dci_alloc_rx[i].rnti,
	    frame_rx,subframe_rx,
	    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)));
1958 1959 1960 1961




1962
      
1963 1964
      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
      if ((ue->UE_mode[eNB_id] > PRACH) &&
1965 1966
	  (generate_ue_dlsch_params_from_dci(frame_rx,
					     subframe_rx,
1967
					     (void *)&dci_alloc_rx[i].dci_pdu,
1968
					     ue->pdcch_vars[eNB_id]->crnti,
1969
					     dci_alloc_rx[i].format,
1970 1971 1972
					     ue->dlsch[eNB_id],
					     &ue->frame_parms,
					     ue->pdsch_config_dedicated,
1973 1974 1975
					     SI_RNTI,
					     0,
					     P_RNTI)==0)) {
1976

1977
	ue->dlsch_received[eNB_id]++;
1978
	
1979
#ifdef DEBUG_PHY_PROC
1980 1981 1982
	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);
1983
#endif
1984
	
1985 1986
	// we received a CRNTI, so we're in PUSCH
	if (ue->UE_mode[eNB_id] != PUSCH) {
1987
#ifdef DEBUG_PHY_PROC
1988
	  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);
1989
#endif
1990 1991 1992 1993
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	  ue->UE_mode[eNB_id] = PUSCH;
	  //mac_xface->macphy_exit("Connected. Exiting\n");
	}
1994
      } else {
1995 1996
	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]);
1997 1998 1999
      }
    }

2000
    else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
2001
	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2002

2003
#ifdef DEBUG_PHY_PROC
2004
      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);
2005 2006
#endif

2007

2008 2009
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
					    (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,
					    P_RNTI)==0) {

	ue->dlsch_SI_received[eNB_id]++;
2021 2022
 

2023
	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");
2024
	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2025 2026 2027

      }
    }
2028

2029
    else if ((ue->prach_resources[eNB_id]) &&
2030 2031
	     (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
2032

2033
#ifdef DEBUG_PHY_PROC
2034
      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);
2035 2036

      //if (((frame_rx%100) == 0) || (frame_rx < 20))
2037
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2038 2039 2040 2041
      //mac_xface->macphy_exit("so far so good...\n");
#endif


2042 2043
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054
					    (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,
					    P_RNTI)==0) {

	ue->dlsch_ra_received[eNB_id]++;
2055

2056
#ifdef DEBUG_PHY_PROC
2057 2058
	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]);
2059
#endif
2060
      }
2061
    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) &&
2062
	       (dci_alloc_rx[i].format == format0)) {
2063
#ifdef DEBUG_PHY_PROC
2064
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
2065
	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
2066 2067
#endif

2068 2069
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
2070

2071
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2072
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
2073
					     ue->pdcch_vars[eNB_id]->crnti,
2074 2075
					     subframe_rx,
					     format0,
2076
					     ue,
2077
					     proc,
2078 2079 2080 2081 2082 2083
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
2084

2085
#ifdef DEBUG_PHY_PROC
2086
	LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
2087 2088
#endif

2089
      }
2090
    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
2091
	       (dci_alloc_rx[i].format == format0)) {
2092
      // UE could belong to more than one CBA group
2093
      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
2094
#ifdef DEBUG_PHY_PROC
2095
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
2096
	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
2097
      /*
2098 2099
	if (((frame_rx%100) == 0) || (frame_rx < 20))
	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2100 2101 2102
      */
#endif

2103 2104
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
2105

2106
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2107
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
2108
					     ue->ulsch[eNB_id]->cba_rnti[0],
2109 2110
					     subframe_rx,
					     format0,
2111
					     ue,
2112
					     proc,
2113 2114 2115 2116 2117 2118
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
2119

2120
#ifdef DEBUG_PHY_PROC
2121
	LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
2122
#endif
2123
	ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
2124
      }
2125 2126
    }

2127 2128
    else {
#ifdef DEBUG_PHY_PROC
2129
      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,
2130 2131 2132
	    ue->pdcch_vars[eNB_id]->crnti,
	    ue->ulsch[eNB_id]->cba_rnti[0],
	    dci_alloc_rx[i].format);
2133
      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2134 2135
#endif
    }
2136

2137
  }
2138

2139
  stop_meas(&ue->dlsch_rx_pdcch_stats);
2140
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
2141 2142 2143
  return(0);
}

2144

2145
void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
2146

2147
  int subframe_rx = proc->subframe_rx;
2148
  int frame_rx = proc->frame_rx;
2149
  int pmch_mcs=-1;
2150
  int CC_id = ue->CC_id;
2151 2152 2153 2154
  uint8_t sync_area=255;
  uint8_t mcch_active;
  int l;
  int ret=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2155

2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171
  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;
2172
#endif
2173 2174 2175 2176
    
    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);
2177
      
2178 2179 2180 2181 2182 2183 2184 2185
      if (abstraction_flag == 0 ) {
	for (l=2; l<12; l++) {
	  
	  slot_fep_mbsfn(ue,
			 l,
			 subframe_rx,
			 0,0);//ue->rx_offset,0);
	}
2186

2187 2188 2189 2190 2191 2192
	for (l=2; l<12; l++) {
	  rx_pmch(ue,
		  0,
		  subframe_rx,
		  l);
	}
2193 2194


2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215
	ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
						       ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
						       ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
						       ue->dlsch_MCH[0]->harq_processes[0]->Qm,
						       1,
						       2,
						       frame_rx,subframe_rx);
	
	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],
			     subframe_rx,
			     0,
			     0,1);
      } else { // abstraction
2216
#ifdef PHY_ABSTRACTION
2217 2218 2219 2220
	ret = dlsch_decoding_emul(ue,
				  subframe_rx,
				  5, // PMCH
				  eNB_id);
2221
#endif
2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
      }
      
      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",
	      frame_rx,subframe_rx,
	      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);
2243
#ifdef DEBUG_DLSCH
2244 2245 2246
	
	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]);
2247
	}
2248 2249
	
	LOG_T(PHY,"\n");
2250
#endif
2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272
	
	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;
2273
	  }
2274 2275 2276 2277 2278 2279 2280 2281
	  
	  
	}
#endif // Rel10
      } // decoding sucessful
    } // pmch_mcs>=0
  } // is_pmch_subframe=true
}
2282

2283
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) {
2284

2285 2286 2287 2288 2289
  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;
2290

2291 2292
  if (dlsch0->active == 0)
    return;
2293

2294
  for (m=s0;m<=s1;m++) {
2295

2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
    if (dlsch0 && (!dlsch1))  {
      harq_pid = dlsch0->current_harq_pid;
      LOG_D(PHY,"[UE %d] PDSCH active in subframe %d (%d), harq_pid %d\n",ue->Mod_id,subframe_rx,harq_pid);
	    
      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;
2311
      }
2312 2313 2314
      
      if ((m==s0) && (m<4))
	first_symbol_flag = 1;
2315
      else
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331
	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,
	       subframe_rx,  // subframe,
	       m,
	       first_symbol_flag,
	       dual_stream_UE,
	       i_mod,
	       dlsch0->current_harq_pid);
      stop_meas(&ue->dlsch_llr_stats);
    } // CRNTI active
2332
  }
2333
} 
2334

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

2337 2338 2339 2340 2341 2342
  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;
2343

2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405
  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,
						 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);
	      
	//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);
2406
      }
2407 2408 2409 2410 2411 2412 2413 2414 2415
    } // 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);
  }
  
}
2416

2417 2418 2419 2420 2421 2422 2423 2424 2425
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) {
2426

2427 2428 2429 2430 2431 2432
  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;
2433

2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453
  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;
    case PDSCH:
      pdsch_vars = ue->pdsch_vars[eNB_id];
      break;
    case PMCH:
    case PDSCH1:
      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
      pdsch_vars = NULL;
      return;
      break;
    }
  
    harq_pid = dlsch0->current_harq_pid;
2454

2455 2456
    if (frame_rx < *dlsch_errors)
      *dlsch_errors=0;
2457

2458 2459 2460 2461 2462 2463 2464
    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;
2465 2466 2467
      }
    }

2468
    if (abstraction_flag == 0) {
2469

2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501
      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,
						  frame_rx,subframe_rx);
      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],
			   subframe_rx,
			   harq_pid,
			   pdsch==PDSCH?1:0,
			   dlsch0->harq_processes[harq_pid]->nb_rb>10?1:0);
      stop_meas(&ue->dlsch_decoding_stats);
    }
	
    else {
      LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
2502
#ifdef PHY_ABSTRACTION
2503 2504
      ret = dlsch_decoding_emul(ue,
				subframe_rx,
2505
				pdsch,
2506
				eNB_id);
2507
#endif
2508 2509 2510 2511 2512
    }
	
    if (ret == (1+dlsch0->max_turbo_iterations)) {
      *dlsch_errors=*dlsch_errors+1;
      
2513

2514 2515 2516 2517 2518 2519 2520
      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);
      
2521

2522 2523 2524 2525 2526 2527 2528
    } else {
      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);
2529

2530 2531 2532 2533 2534 2535 2536 2537
#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");
2538
#endif
2539

2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570
      
      if (ue->mac_enabled == 1) {
	switch (pdsch) {
	case PDSCH:
	  mac_xface->ue_send_sdu(ue->Mod_id,
				 CC_id,
				 frame_rx,
				 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;
	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;
	}
2571
      }
2572 2573 2574 2575 2576 2577 2578 2579
      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;
    }
  
  
      
2580
#ifdef DEBUG_PHY_PROC
2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597
    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]);
    }
2598
    
2599 2600
#endif

2601
  }
2602

2603

2604 2605 2606
}
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
2607
 
2608 2609 2610 2611 2612
  int l,l2;
  int pilot1;
  int pmch_flag=0;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2613

2614 2615


2616
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
2617

2618

2619
  start_meas(&ue->phy_proc_rx);
2620

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


2624 2625 2626 2627 2628
  // 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;
2629

2630 2631 2632 2633
  if (ue->dlsch_SI[eNB_id])
    ue->dlsch_SI[eNB_id]->active = 0;
  if (ue->dlsch_ra[eNB_id])
    ue->dlsch_ra[eNB_id]->active = 0;
2634

2635
  
2636
#ifdef DEBUG_PHY_PROC
2637 2638 2639
  LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX (%d)\n",
	(r_type == multicast_relay) ? "RN/UE" : "UE",
	ue->Mod_id,frame_rx, subframe_rx);
2640 2641
#endif

2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672
  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;
  }
  
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
  for (l=1; l<=l2; 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,
	       (subframe_rx<<1),
	       ue->rx_offset,
	       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);
2673
    }
2674
    
2675 2676 2677 2678 2679 2680 2681 2682 2683
    ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode);
    if ((l==pilot1) ||
	((pmch_flag==1)&(l==l2)))  {
      LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
      
      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);
      }
2684
      LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[eNB_id]->num_pdcch_symbols);
2685
    }
2686 2687 2688 2689 2690 2691 2692 2693
    
  } // for l=1..l2
  
    // If this is PMCH, call procedures and return
  if (pmch_flag == 1) {
    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
    return 0;
  }
2694

2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766
  slot_fep(ue,
	   0,
	   1+(subframe_rx<<1),
	   ue->rx_offset,
	   0,
	   0);
  
  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
 
  // do procedures for C-RNTI
  if (ue->dlsch[eNB_id][0]->active == 1) {
    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);
  }
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			SI_PDSCH,
			ue->dlsch_SI[eNB_id],
			NULL,
			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
  }
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			RA_PDSCH,
			ue->dlsch_ra[eNB_id],
			NULL,
			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
  }    
  
  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),
		 ue->rx_offset,
		 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);
      }
      
      ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode);
      
    } // for l=1..l2
      // do first symbol of next subframe for channel estimation
    slot_fep(ue,
	     0,
	     (2+(subframe_rx<<1))%20,
	     ue->rx_offset,
	     0,
	     0);
  } // not an S-subframe
2767

2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792
  // 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) {
    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);
      
2793

2794 2795 2796 2797 2798
  }
  else {
    //  printf("PDSCH inactive in subframe %d\n",subframe_rx-1);
    ue->dlsch[eNB_id][0]->harq_ack[subframe_rx].send_harq_status = 0;
  }
2799

2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810
  // 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);
2811

2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844
    ue_dlsch_procedures(ue,
			proc,
			eNB_id,
			SI_PDSCH,
			ue->dlsch_SI[eNB_id],
			NULL,
			&ue->dlsch_SI_errors[eNB_id],
			mode,
			abstraction_flag);
    ue->dlsch_SI[eNB_id]->active = 0;
  }
  // do procedures for 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;
  }
2845

2846
  if (subframe_rx==9) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2847
    if (frame_rx % 10 == 0) {
2848
      if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
2849
	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]);
2850

2851 2852
      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
2853
    }
2854 2855


2856 2857
    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];
2858
    LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
2859 2860
	  ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
	  ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
2861
  }
2862 2863


jiangx's avatar
jiangx committed
2864 2865

#ifdef EMOS
2866
  phy_procedures_emos_UE_RX(ue,slot,eNB_id);
jiangx's avatar
jiangx committed
2867 2868
#endif

2869
     
2870
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
2871
  stop_meas(&ue->phy_proc_rx);
2872
  return (0);
2873
}
2874
   
2875
#ifdef Rel10
2876 2877
int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
{
2878
   
2879
  int do_proc =0; // do nothing by default
2880
   
2881
  switch(r_type) {
2882
  case no_relay:
2883
    do_proc=no_relay; // perform the normal UE operation
2884
    break;
2885
     
2886
  case multicast_relay:
Raymond Knopp's avatar
 
Raymond Knopp committed
2887
    if (slot_rx > 12)
2888 2889
      do_proc = 0; // do nothing
    else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
2890
      do_proc = multicast_relay ; // do PHY procedures UE RX
2891
     
2892
    break;
2893
     
2894 2895 2896 2897 2898
  default: // should'not be here
    LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
    do_proc= 0;
    break;
  }
2899
   
2900 2901
  return do_proc;
}
2902
#endif
2903 2904 2905 2906
 
 
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)
2907
{
2908
#if defined(ENABLE_ITTI)
2909 2910 2911 2912 2913
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  unsigned int  Mod_id;
  int           result;
2914
#endif
2915 2916 2917 2918 2919
   
  int           frame_rx = proc->frame_rx;
  int           frame_tx = proc->frame_tx;
  int           subframe_rx = proc->subframe_rx;
  int           subframe_tx = proc->subframe_tx;
2920
#undef DEBUG_PHY_PROC
2921
   
2922
  UE_L2_STATE_t ret;
2923
  int slot;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2924

2925 2926
  if (ue->mac_enabled == 0) {
    ue->UE_mode[eNB_id]=PUSCH;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2927
  }
2928 2929
   
   
2930
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
2931
  start_meas(&ue->phy_proc);
2932
#if defined(ENABLE_ITTI)
2933

2934 2935
  do {
    // Checks if a message has been sent to PHY sub-task
2936
    itti_poll_msg (TASK_PHY_UE, &msg_p);
2937
     
2938 2939 2940 2941
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance - NB_eNB_INST;
2942
       
2943
      switch (ITTI_MSG_ID(msg_p)) {
2944
      case PHY_FIND_CELL_REQ:
2945 2946 2947 2948 2949
	LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
	 
	/* TODO process the message */
	break;
	 
2950
      default:
2951 2952
	LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
	break;
2953
      }
2954
       
2955 2956
      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
2957 2958
    }
  } while(msg_p != NULL);
2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970
   
#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)) {
2971
#ifdef Rel10
2972 2973
       
      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
2974
#endif
2975 2976 2977 2978 2979 2980 2981 2982 2983 2984
	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)) {
2985
#ifdef Rel10
2986 2987
	 
      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
2988
#endif
2989
	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
2990
    }
2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022
       
    if (ue->mac_enabled==1) {
      if (slot==0) {
	ret = mac_xface->ue_scheduler(ue->Mod_id,
				      frame_tx,
				      subframe_rx,
				      subframe_select(&ue->frame_parms,subframe_tx),
				      eNB_id,
				      0/*FIXME CC_id*/);
	   
	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
3023
}
3024 3025