phy_procedures_lte_eNb.c 122 KB
Newer Older
Raymond Knopp's avatar
Raymond Knopp committed
1

2
/*******************************************************************************
3
    OpenAirInterface
ghaddab's avatar
ghaddab committed
4
    Copyright(c) 1999 - 2014 Eurecom
5

ghaddab's avatar
ghaddab committed
6 7 8 9
    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.
10 11


ghaddab's avatar
ghaddab committed
12 13 14 15
    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.
16

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

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

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

ghaddab's avatar
ghaddab committed
29
 *******************************************************************************/
30 31 32

/*! \file phy_procedures_lte_eNB.c
 * \brief Implementation of eNB procedures from 36.213 LTE specifications
33
 * \author R. Knopp, F. Kaltenberger, N. Nikaein
34 35 36
 * \date 2011
 * \version 0.1
 * \company Eurecom
37
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr
38 39 40 41 42 43 44 45 46 47 48 49 50
 * \note
 * \warning
 */

#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

51
//#define DEBUG_PHY_PROC (Already defined in cmake)
52 53 54 55 56 57 58
//#define DEBUG_ULSCH

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

59
#include "assertions.h"
Lionel Gauthier's avatar
Lionel Gauthier committed
60
#include "msc.h"
61

62
#if defined(ENABLE_ITTI)
Lionel Gauthier's avatar
Lionel Gauthier committed
63
#   include "intertask_interface.h"
64
#   if ENABLE_RAL
Lionel Gauthier's avatar
Lionel Gauthier committed
65 66
#     include "timer.h"
#   endif
67 68
#endif

69 70 71 72 73 74 75 76 77
//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

extern int exit_openair;


78 79 80
unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(32)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(32)));
int eNB_sync_buffer1[640*6] __attribute__ ((aligned(32)));
81 82
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

83
extern uint16_t hundred_times_log10_NPRB[100];
84

85
unsigned int max_peak_val;
86
int max_sync_pos;
87 88 89 90 91 92 93

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

94
#if defined(SMBV) 
95 96
extern const char smbv_fname[];
extern unsigned short config_frames[4];
97
extern uint8_t smbv_frame_cnt;
98 99 100 101 102 103
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

104 105
uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_subframe)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
106

Lionel Gauthier's avatar
Lionel Gauthier committed
107 108
  const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
  const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
109

110
  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
111 112 113
        phy_vars_eNB->Mod_id,phy_vars_eNB->ulsch_eNB[UE_id]->rnti,frame,subframe,
        phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex);

114
  if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
115 116
    if ((subframe%5) == phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
      return(1);
117
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
118 119
    if (subframe==(phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
      return(1);
120
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
Raymond Knopp's avatar
 
Raymond Knopp committed
121
    if ((10*(frame&1)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
122
      return(1);
123
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
Raymond Knopp's avatar
 
Raymond Knopp committed
124
    if ((10*(frame&3)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
125
      return(1);
126
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
Raymond Knopp's avatar
 
Raymond Knopp committed
127
    if ((10*(frame&7)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
128
      return(1);
129 130 131 132
  }

  return(0);
}
133

134 135 136 137 138 139
void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
{
  DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->tail_freelist] = harq_pid;
  DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10;
}

Cedric Roux's avatar
Cedric Roux committed
140
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
141 142 143 144 145
{
  if (DLSCH_ptr->head_freelist == DLSCH_ptr->tail_freelist) {
    LOG_E(PHY, "%s:%d: you cannot read this!\n", __FILE__, __LINE__);
    abort();
  }
Cedric Roux's avatar
Cedric Roux committed
146 147 148 149 150 151 152 153 154
  /* basic check, in case several threads deal with the free list at the same time
   * in normal situations it should not happen, that's also why we don't use any
   * locking mechanism to protect the free list
   * to be refined in case things don't work properly
   */
  if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
    LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
    abort();
  }
155 156 157
  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}

158 159
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
{
160
  uint8_t i;
161

Raymond Knopp's avatar
 
Raymond Knopp committed
162
#ifdef DEBUG_PHY_PROC
163 164 165 166
  LOG_I(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
        phy_vars_eNB->Mod_id,
        phy_vars_eNB->CC_id,
        (uint16_t)rnti);
Raymond Knopp's avatar
 
Raymond Knopp committed
167
#endif
168 169

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
170
    if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
171
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
172 173
      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
      return(-1);
174
    } else {
175
      if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) {
176
        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
177
        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
178 179 180
        phy_vars_eNB->dlsch_eNB[i][0]->rnti = rnti;
        phy_vars_eNB->ulsch_eNB[i]->rnti = rnti;
        phy_vars_eNB->eNB_UE_stats[i].crnti = rnti;
181 182 183 184

	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_below = 0;
	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
185
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
186 187 188 189
	      phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
	      phy_vars_eNB->rx_total_gain_eNB_dB,
	      phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH);
  
190
        return(i);
191
      }
192
    }
193 194 195 196
  }
  return(-1);
}

197
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
198
  uint8_t i;
199 200 201 202 203 204 205 206 207 208 209 210 211
  int j,CC_id;
  PHY_VARS_eNB *phy_vars_eNB;

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    phy_vars_eNB = PHY_vars_eNB_g[Mod_idP][CC_id];
    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
      if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
	MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti);
	LOG_E(PHY,"Can't remove UE, not enough memory allocated\n");
	return(-1);
      } else {
	if (phy_vars_eNB->eNB_UE_stats[i].crnti==rntiP) {
	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
212
#ifdef DEBUG_PHY_PROC
213 214
	  LOG_I(PHY,"eNB %d removing UE %d with rnti %x\n",phy_vars_eNB->Mod_id,i,rnti);
#endif
215
	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
216 217 218 219 220 221 222 223 224 225 226 227 228 229
	  clean_eNb_dlsch(phy_vars_eNB->dlsch_eNB[i][0]);
	  clean_eNb_ulsch(phy_vars_eNB->ulsch_eNB[i]);
	  //phy_vars_eNB->eNB_UE_stats[i].crnti = 0;
	  memset(&phy_vars_eNB->eNB_UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
	  //  mac_exit_wrapper("Removing UE");
	  
	  /* clear the harq pid freelist */
	  phy_vars_eNB->dlsch_eNB[i][0]->head_freelist = 0;
	  phy_vars_eNB->dlsch_eNB[i][0]->tail_freelist = 0;
	  for (j = 0; j < 8; j++)
	    put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], j);
	  
	  return(i);
	}
230
      }
231
    }
232
  }
233
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
234 235 236
  return(-1);
}

237 238
int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB)
{
239
  uint8_t i;
240

241
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
242
    if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) {
243 244 245
      /*if ((phy_vars_eNB->dlsch_eNB[i]) &&
      (phy_vars_eNB->dlsch_eNB[i][0]) &&
      (phy_vars_eNB->dlsch_eNB[i][0]->rnti==0))*/
246 247 248
      LOG_D(PHY,"Next free UE id is %d\n",i);
      return(i);
    }
249
  }
250

251 252 253
  return(-1);
}

Lionel Gauthier's avatar
Lionel Gauthier committed
254
int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag)
255 256 257 258
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
259
  uint8_t i;
Raymond Knopp's avatar
 
Raymond Knopp committed
260
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
261
  int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
262 263

  if (UE_id==-1) {
264
    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
265 266
    *round=0;
    return(-1);
267 268 269
  }

  if (ul_flag == 0)  {// this is a DL request
Raymond Knopp's avatar
 
Raymond Knopp committed
270
    DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0];
271

272 273 274 275 276
    // set to no available process first
    *harq_pid = -1;

    for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
      if (DLSCH_ptr->harq_processes[i]!=NULL) {
277
	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
	  sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
	  if (sf2<=sf1)
	    sfdiff = sf1-sf2;
	  else // this happens when wrapping around 1024 frame barrier
	    sfdiff = 10240 + sf1-sf2;
	  LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff);

	  if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms)
	    sfdiff_max = sfdiff; 
	    *harq_pid = i;
	    *round = DLSCH_ptr->harq_processes[i]->round;
	  }
	}
      } else { // a process is not defined
	LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
	return(-1);
294
      }
295
    }
296 297 298 299 300 301 302 303

    /* if no active harq pid, get the oldest in the freelist, if any */
    if (*harq_pid == 255 && DLSCH_ptr->head_freelist != DLSCH_ptr->tail_freelist) {
      *harq_pid = DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist];
      *round = 0;
      LOG_D(PHY,"process %d is first free process\n", *harq_pid);
    }

304 305
    LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
	  frame,subframe,*harq_pid);
306
  } else { // This is a UL request
307

Raymond Knopp's avatar
 
Raymond Knopp committed
308 309 310
    ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch_eNB[(uint32_t)UE_id];
    ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,subframe);
    ulsch_frame    = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,frame,subframe);
311
    // Note this is for TDD configuration 3,4,5 only
Raymond Knopp's avatar
 
Raymond Knopp committed
312
    *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,
313 314
                                  ulsch_frame,
                                  ulsch_subframe);
315
    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
316
    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
317
  }
318

319 320 321
  return(0);
}

322
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
323
{
324 325
  //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
  return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
326 327
}

328 329 330 331 332 333
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
  //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
  return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
}

334
#ifdef EMOS
335 336
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *phy_vars_eNB)
{
337 338 339 340 341 342

}
#endif



343 344 345
void phy_procedures_eNB_S_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type)
{
  UNUSED(r_type);
346

347
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
348

349
#ifdef DEBUG_PHY_PROC
350
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_rx, subframe);
351
#endif
352

353

Raymond Knopp's avatar
 
Raymond Knopp committed
354 355
  if (abstraction_flag == 0) {
    lte_eNB_I0_measurements(phy_vars_eNB,
356
			    subframe,
357 358
                            0,
                            phy_vars_eNB->first_run_I0_measurements);
Raymond Knopp's avatar
 
Raymond Knopp committed
359
  }
360

361
#ifdef PHY_ABSTRACTION
Raymond Knopp's avatar
 
Raymond Knopp committed
362 363
  else {
    lte_eNB_I0_measurements_emul(phy_vars_eNB,
364
                                 0);
365
  }
366

Raymond Knopp's avatar
 
Raymond Knopp committed
367 368
#endif

369

370 371
}

Raymond Knopp's avatar
 
Raymond Knopp committed
372 373


374
#ifdef EMOS
375 376 377
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *phy_vars_eNB)
{

378 379 380 381
  uint8_t aa;
  uint16_t last_subframe_emos;
  uint16_t pilot_pos1 = 3 - phy_vars_eNB->lte_frame_parms.Ncp, pilot_pos2 = 10 - 2*phy_vars_eNB->lte_frame_parms.Ncp;
  uint32_t bytes;
382 383 384

  last_subframe_emos=0;

Raymond Knopp's avatar
 
Raymond Knopp committed
385

Raymond Knopp's avatar
 
Raymond Knopp committed
386

Raymond Knopp's avatar
 
Raymond Knopp committed
387

388
#ifdef EMOS_CHANNEL
389

390
  //if (last_slot%2==1) // this is for all UL subframes
391
  if (subframe==3)
392
    for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) {
393 394 395 396 397 398
      memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*phy_vars_eNB->lte_frame_parms.N_RB_UL*12],
             &phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos1],
             phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int));
      memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*phy_vars_eNB->lte_frame_parms.N_RB_UL*12],
             &phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos2],
             phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int));
399
    }
400

401 402
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
403
  if (subframe==4) {
404
    emos_dump_eNB.timestamp = rt_get_time_ns();
jiangx's avatar
jiangx committed
405
    emos_dump_eNB.frame_tx = phy_vars_eNB->proc[subframe].frame_rx;
406 407 408 409 410 411 412 413
    emos_dump_eNB.rx_total_gain_dB = phy_vars_eNB->rx_total_gain_eNB_dB;
    emos_dump_eNB.mimo_mode = phy_vars_eNB->transmission_mode[0];
    memcpy(&emos_dump_eNB.PHY_measurements_eNB,
           &phy_vars_eNB->PHY_measurements_eNB[0],
           sizeof(PHY_MEASUREMENTS_eNB));
    memcpy(&emos_dump_eNB.eNB_UE_stats[0],&phy_vars_eNB->eNB_UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));

    bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_eNB, sizeof(fifo_dump_emos_eNB));
414

415 416
    //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
    if (bytes!=sizeof(fifo_dump_emos_eNB)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
417
      LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n",
jiangx's avatar
jiangx committed
418
            phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
419
    } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
420 421
      if (phy_vars_eNB->proc[(subframe+1)%10].frame_tx%100==0) {
        LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n",
jiangx's avatar
jiangx committed
422
              phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes);
423
      }
424
    }
425 426 427 428 429 430 431
  }
}
#endif


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
432 433
int QPSK[4]= {AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)};
int QPSK2[4]= {AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)};
434

Lionel Gauthier's avatar
Lionel Gauthier committed
435 436

#if defined(ENABLE_ITTI)
437
#   if ENABLE_RAL
Lionel Gauthier's avatar
Lionel Gauthier committed
438 439
extern PHY_MEASUREMENTS PHY_measurements;

440 441
void phy_eNB_lte_measurement_thresholds_test_and_report(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP, uint16_t valP)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
442
  MessageDef *message_p = NULL;
443

Raymond Knopp's avatar
 
Raymond Knopp committed
444
  if (
445 446 447 448 449 450
    (
      ((threshold_phy_pP->threshold.threshold_val <  valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_ABOVE_THRESHOLD)) ||
      ((threshold_phy_pP->threshold.threshold_val >  valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_BELOW_THRESHOLD))
    )  ||
    (threshold_phy_pP->threshold.threshold_xdir == RAL_NO_THRESHOLD)
  ) {
Raymond Knopp's avatar
 
Raymond Knopp committed
451 452 453 454
    message_p = itti_alloc_new_message(TASK_PHY_ENB , PHY_MEAS_REPORT_IND);
    memset(&PHY_MEAS_REPORT_IND(message_p), 0, sizeof(PHY_MEAS_REPORT_IND(message_p)));

    memcpy(&PHY_MEAS_REPORT_IND (message_p).threshold,
455 456
           &threshold_phy_pP->threshold,
           sizeof(PHY_MEAS_REPORT_IND (message_p).threshold));
Raymond Knopp's avatar
 
Raymond Knopp committed
457 458

    memcpy(&PHY_MEAS_REPORT_IND (message_p).link_param,
459 460 461
           &threshold_phy_pP->link_param,
           sizeof(PHY_MEAS_REPORT_IND (message_p).link_param));
    \
Raymond Knopp's avatar
 
Raymond Knopp committed
462 463 464 465 466

    switch (threshold_phy_pP->link_param.choice) {
    case RAL_LINK_PARAM_CHOICE_LINK_PARAM_VAL:
      PHY_MEAS_REPORT_IND (message_p).link_param._union.link_param_val = valP;
      break;
467

Raymond Knopp's avatar
 
Raymond Knopp committed
468 469 470 471
    case RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL:
      //PHY_MEAS_REPORT_IND (message_p).link_param._union.qos_param_val.
      AssertFatal (1 == 0, "TO DO RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL\n");
      break;
472
    }
473

Raymond Knopp's avatar
 
Raymond Knopp committed
474 475
    itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
  }
Lionel Gauthier's avatar
Lionel Gauthier committed
476 477
}

478 479
void phy_eNB_lte_check_measurement_thresholds(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
480 481 482 483 484 485 486 487 488 489 490
  unsigned int  mod_id;

  mod_id = instanceP;

  switch (threshold_phy_pP->link_param.link_param_type.choice) {

  case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
    switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) {
    case RAL_LINK_PARAM_GEN_DATA_RATE:
      phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
      break;
491

Raymond Knopp's avatar
 
Raymond Knopp committed
492 493 494
    case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH:
      phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
      break;
495

Raymond Knopp's avatar
 
Raymond Knopp committed
496 497 498
    case RAL_LINK_PARAM_GEN_SINR:
      phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
      break;
499

Raymond Knopp's avatar
 
Raymond Knopp committed
500 501
    case RAL_LINK_PARAM_GEN_THROUGHPUT:
      break;
502

Raymond Knopp's avatar
 
Raymond Knopp committed
503 504
    case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE:
      break;
505 506 507

    default:
      ;
Lionel Gauthier's avatar
Lionel Gauthier committed
508
    }
509

Raymond Knopp's avatar
 
Raymond Knopp committed
510 511 512 513 514 515
    break;

  case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
    switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) {
    case RAL_LINK_PARAM_LTE_UE_RSRP:
      break;
516

Raymond Knopp's avatar
 
Raymond Knopp committed
517 518
    case RAL_LINK_PARAM_LTE_UE_RSRQ:
      break;
519

Raymond Knopp's avatar
 
Raymond Knopp committed
520 521
    case RAL_LINK_PARAM_LTE_UE_CQI:
      break;
522

Raymond Knopp's avatar
 
Raymond Knopp committed
523 524
    case RAL_LINK_PARAM_LTE_AVAILABLE_BW:
      break;
525

Raymond Knopp's avatar
 
Raymond Knopp committed
526 527
    case RAL_LINK_PARAM_LTE_PACKET_DELAY:
      break;
528

Raymond Knopp's avatar
 
Raymond Knopp committed
529 530
    case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE:
      break;
531

Raymond Knopp's avatar
 
Raymond Knopp committed
532 533
    case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS:
      break;
534

Raymond Knopp's avatar
 
Raymond Knopp committed
535 536
    case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES:
      break;
537

Raymond Knopp's avatar
 
Raymond Knopp committed
538 539
    case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY:
      break;
540

Raymond Knopp's avatar
 
Raymond Knopp committed
541 542
    case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY:
      break;
543

Raymond Knopp's avatar
 
Raymond Knopp committed
544 545
    case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS:
      break;
546

Raymond Knopp's avatar
 
Raymond Knopp committed
547 548
    case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW:
      break;
549 550 551

    default:
      ;
Raymond Knopp's avatar
 
Raymond Knopp committed
552
    }
553

Raymond Knopp's avatar
 
Raymond Knopp committed
554 555
    break;

556 557
  default:
    ;
Raymond Knopp's avatar
 
Raymond Knopp committed
558
  }
Lionel Gauthier's avatar
Lionel Gauthier committed
559 560 561 562
}
#   endif
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
563

Cedric Roux's avatar
Cedric Roux committed
564
unsigned int taus(void);
Raymond Knopp's avatar
 
Raymond Knopp committed
565

566 567
void pmch_procedures(PHY_VARS_eNB *eNB,PHY_VARS_RN *rn, int subframe,int sched_subframe,int abstraction_flag,relaying_type_t r_type) {

568
#ifdef Rel10
569 570
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
571
  //  uint8_t sync_area=255;
572
#endif
573

Raymond Knopp's avatar
 
Raymond Knopp committed
574
  if (abstraction_flag==0) {
575 576 577 578 579
    // This is DL-Cell spec pilots in Control region
    generate_pilots_slot(eNB,
			 eNB->lte_eNB_common_vars.txdataF[0],
			 AMP,
			 subframe<<1,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
580
  }
581
  
582
#ifdef Rel10
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
  // if mcch is active, send regardless of the node type: eNB or RN
  // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing
  mch_pduP = mac_xface->get_mch_sdu(eNB->Mod_id,
				    eNB->CC_id,
				    eNB->proc[sched_subframe].frame_tx,
				    subframe);
  
  switch (r_type) {
  case no_relay:
    if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
      LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
	    eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->mcs,
	    eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3);
    else {
      LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
	    eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->sync_area,
	    (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment");
      mch_pduP = NULL;
    }
    
    break;
    
  case multicast_relay:
    if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) {
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN  sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,
	    mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);
    } else if (rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8
      mch_pduP= &mch_pdu;
      memcpy(&mch_pduP->payload, // could be a simple copy
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b,
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->Pdu_size = (uint16_t) (rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->mcs = rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs;
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,subframe%5,
	    rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size);
Raymond Knopp's avatar
 
Raymond Knopp committed
620
    } else {
621
      mch_pduP=NULL;
622
    }
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
    
    rn->mch_avtive[subframe]=0;
    break;
    
  default:
    LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
	  eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,r_type);
    mch_pduP=NULL;
    break;
  }// switch
  
  if (mch_pduP) {
    fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0, abstraction_flag);
    // Generate PMCH
    generate_mch(eNB,sched_subframe,(uint8_t*)mch_pduP->payload,abstraction_flag);
  } else {
    LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",eNB->proc[sched_subframe].frame_tx,subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
640
  }
641 642 643
  
#endif
}
644

645
void common_signal_procedures (int subframe,int sched_subframe,PHY_VARS_eNB *eNB,int abstraction_flag) {
646

647 648 649
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  int **txdataF = eNB->lte_eNB_common_vars.txdataF[0];
  uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
650

651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
  // generate Cell-Specific Reference Signals for both slots
  if (abstraction_flag==0) {
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
    generate_pilots_slot(eNB,
			 txdataF,
			 AMP,
			 subframe<<1,0);
    // check that 2nd slot is for DL
    if (subframe_select(fp,subframe) == SF_DL)
      generate_pilots_slot(eNB,
			   txdataF,
			   AMP,
			   (subframe<<1)+1,0);
    
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
  }    
Raymond Knopp's avatar
 
Raymond Knopp committed
667

668
  // First half of PSS/SSS (FDD, slot 0)
Raymond Knopp's avatar
 
Raymond Knopp committed
669
  if (subframe == 0) {
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
    if ((fp->frame_type == FDD) &&
	(abstraction_flag==0)) {
      generate_pss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   0);
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 5 : 4,
		   0);
      
    }
    
685
    // generate PBCH (Physical Broadcast CHannel) info
686
    if ((eNB->proc[sched_subframe].frame_tx&3) == 0) {
687
      pbch_pdu[2] = 0;
688
      
689
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
690
      switch (fp->N_RB_DL) {
Raymond Knopp's avatar
 
Raymond Knopp committed
691
      case 6:
692 693 694
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
695
      case 15:
696 697 698
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
699
      case 25:
700 701 702
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
703
      case 50:
704 705 706
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
707
      case 75:
708 709 710
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
711
      case 100:
712 713 714
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
715
      default:
716 717 718
	// FIXME if we get here, this should be flagged as an error, right?
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
Raymond Knopp's avatar
 
Raymond Knopp committed
719
      }
720
      
721
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
722 723 724
	((fp->phich_config_common.phich_duration << 4)&0x10);
      
      switch (fp->phich_config_common.phich_resource) {
Raymond Knopp's avatar
 
Raymond Knopp committed
725
      case oneSixth:
726 727 728
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
729
      case half:
730 731 732
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
733
      case one:
734 735 736
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
737
      case two:
738 739 740
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
	break;
	
Raymond Knopp's avatar
 
Raymond Knopp committed
741
      default:
742 743
	// unreachable
	break;
Raymond Knopp's avatar
 
Raymond Knopp committed
744
      }
745 746 747
      
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((eNB->proc[sched_subframe].frame_tx>>8)&0x3);
      pbch_pdu[1] = eNB->proc[sched_subframe].frame_tx&0xfc;
748
      pbch_pdu[0] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
749
    }
750 751 752 753 754 755 756 757 758 759 760
      
    /// First half of SSS (TDD, slot 1)
    
    if ((fp->frame_type == TDD)&&
	(abstraction_flag==0)){
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   1);
    }
761

762
    /// generate PBCH
Raymond Knopp's avatar
 
Raymond Knopp committed
763
    if (abstraction_flag==0) {
764 765 766 767 768 769 770 771 772 773 774 775
      generate_pbch(&eNB->lte_eNB_pbch,
                    txdataF,
                    AMP,
                    fp,
                    pbch_pdu,
                    eNB->proc[sched_subframe].frame_tx&3);
    }
#ifdef PHY_ABSTRACTION
    else {
      generate_pbch_emul(eNB,pbch_pdu);
    }
#endif
776

777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
  }
  else if ((subframe == 1) &&
	   (fp->frame_type == TDD)&&
	   (abstraction_flag==0)) {
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 2);
  }
  
  // Second half of PSS/SSS (FDD, slot 10)
  else if ((subframe == 5) && 
	   (fp->frame_type == FDD) &&
	   (abstraction_flag==0)) {
        generate_pss(txdataF,
793
                     AMP,
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 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 892 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
                     &eNB->lte_frame_parms,
                     (fp->Ncp==NORMAL) ? 6 : 5,
                     10);
        generate_sss(txdataF,
                     AMP,
                     &eNB->lte_frame_parms,
                     (fp->Ncp==NORMAL) ? 5 : 4,
                     10);

  }

  //  Second-half of SSS (TDD, slot 11)
  else if ((subframe == 5) &&
	   (fp->frame_type == TDD) &&
	   (abstraction_flag==0)) {
    generate_sss(txdataF,
		 AMP,
		 fp,
		 (fp->Ncp==NORMAL) ? 6 : 5,
		 11);
  }

  // Second half of PSS (TDD, slot 12)
  else if ((subframe == 6) &&
	   (fp->frame_type == TDD) &&
	   (abstraction_flag==0)) {
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 12);
  }

}

void generate_eNB_dlsch_params(const int frame,const int subframe,int sched_subframe,PHY_VARS_eNB *eNB,DCI_ALLOC_t *dci_alloc,const int UE_id) {

  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;

  // if we have SI_RNTI, configure dlsch parameters and CCE index
  if (dci_alloc->rnti == SI_RNTI) {
    LOG_D(PHY,"Generating dlsch params for SI_RNTI\n");
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
				       &eNB->dlsch_eNB_SI,
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       0,
				       P_RNTI,
				       eNB->eNB_UE_stats[0].DL_pmi_single);
    
    
    eNB->dlsch_eNB_SI->nCCE[subframe] = dci_alloc->firstCCE;
    
    LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,
	  eNB->dlsch_eNB_SI->nCCE[subframe]);
    
#if defined(SMBV) 
    
    // configure SI DCI
    if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", dci_alloc, i);
    }
    
#endif
    
    
  } else if (dci_alloc->ra_flag == 1) {  // This is format 1A allocation for RA
    // configure dlsch parameters and CCE index
    LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");    
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
				       &eNB->dlsch_eNB_ra,
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       dci_alloc->rnti,
				       P_RNTI,
				       eNB->eNB_UE_stats[0].DL_pmi_single);
    
    
    eNB->dlsch_eNB_ra->nCCE[subframe] = dci_alloc->firstCCE;
    
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,
	  eNB->dlsch_eNB_ra->nCCE[subframe]);
#if defined(SMBV) 
    
    // configure RA DCI
    if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", dci_alloc, i);
    }
    
#endif
    
  }
  
  else if ((dci_alloc->format != format0)&&
	   (dci_alloc->format != format3)&&
	   (dci_alloc->format != format3A)&&
	   (dci_alloc->format != format4)){ // this is a normal DLSCH allocation
    

    
    if (UE_id>=0) {
#if defined(SMBV) 
      // Configure this user
      if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",eNB->proc[sched_subframe].frame_tx,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
              dci_alloc->rnti,eNB->transmission_mode[(uint8_t)UE_id]);
	smbv_configure_user(smbv_fname,UE_id+1,eNB->transmission_mode[(uint8_t)UE_id],dci_alloc->rnti);
      }
      
#endif

      LOG_D(PHY,"Generating dlsch params for RNTI %x\n",dci_alloc->rnti);      
      generate_eNB_dlsch_params_from_dci(frame,
					 subframe,
					 &dci_alloc->dci_pdu[0],
					 dci_alloc->rnti,
					 dci_alloc->format,
					 eNB->dlsch_eNB[(uint8_t)UE_id],
					 fp,
					 eNB->pdsch_config_dedicated,
					 SI_RNTI,
					 0,
					 P_RNTI,
					 eNB->eNB_UE_stats[(uint8_t)UE_id].DL_pmi_single);
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid,eNB->proc[sched_subframe].frame_tx,subframe);
      
      
      eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
      
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,
	    dci_alloc->rnti,eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe]);
      
#if defined(SMBV) 
      
      // configure UE-spec DCI
      if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
	smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1,dci_alloc, i);
Raymond Knopp's avatar
 
Raymond Knopp committed
945
      }
946 947 948 949 950 951 952 953 954 955 956
      
#endif
      
      LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
	    eNB->Mod_id, dci_alloc->rnti,
	    eNB->proc[sched_subframe].frame_tx, subframe,UE_id,
	    dci_alloc->format,
	    1<<dci_alloc->L);
    } else {
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
	    eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,dci_alloc->rnti);
Raymond Knopp's avatar
 
Raymond Knopp committed
957
    }
958 959 960
  }
  
}
961

962
void generate_eNB_ulsch_params(const int frame,const int subframe,int sched_subframe,PHY_VARS_eNB *eNB,DCI_ALLOC_t *dci_alloc,const int UE_id) {
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 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
  int harq_pid;
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  
  LOG_D(PHY,
	"[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8"), aggregation %d\n",
	eNB->Mod_id,
	subframe2harq_pid(fp,
			  pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe),
			  pdcch_alloc2ul_subframe(fp,subframe)),
	eNB->proc[sched_subframe].frame_tx,
	subframe,
	pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe),
	pdcch_alloc2ul_subframe(fp,subframe),
	dci_alloc->rnti,
	dci_alloc->dci_pdu[0],
	1<<dci_alloc->L);
  
  generate_eNB_ulsch_params_from_dci(&dci_alloc->dci_pdu[0],
				     dci_alloc->rnti,
				     sched_subframe,
				     format0,
				     UE_id,
				     eNB,
				     SI_RNTI,
				     0,
				     P_RNTI,
				     CBA_RNTI,
				     0);  // do_srs
  
  LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n",
	eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,dci_alloc->rnti,
	dci_alloc->firstCCE);
  
#if defined(SMBV) 
  
  // configure UE-spec DCI for UL Grant
  if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
    LOG_D(PHY,"[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
    smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i);
  }
  
#endif
  
  
  // get the hard_pid for this subframe 
  harq_pid = subframe2harq_pid(fp,
			       pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe),
			       pdcch_alloc2ul_subframe(fp,subframe));
  
  if (harq_pid==255) { // should not happen, log an error and exit, this is a fatal error
    LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx);
    mac_xface->macphy_exit("FATAL\n"); 
  }
  
  if ((dci_alloc->rnti  >= CBA_RNTI) && (dci_alloc->rnti < P_RNTI))
    eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
  else
    eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
  
}
1024

1025
void pdsch_procedures(PHY_VARS_eNB *eNB,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int subframe,int sched_subframe,int num_pdcch_symbols,int abstraction_flag) {
1026

1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
  int harq_pid = dlsch->current_harq_pid;
  LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
  int input_buffer_length = dlsch_harq->TBS/8;
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  uint8_t *DLSCH_pdu=NULL;
  uint8_t DLSCH_pdu_tmp[768*8];
  uint8_t DLSCH_pdu_rar[256];
  int i;

  LOG_D(PHY,
	"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")\n",
	eNB->Mod_id, dlsch->rnti,harq_pid,
	eNB->proc[sched_subframe].frame_tx, subframe, input_buffer_length,
	get_G(fp,
	      dlsch_harq->nb_rb,
	      dlsch_harq->rb_alloc,
	      get_Qm(dlsch_harq->mcs),
	      dlsch_harq->Nl,
	      num_pdcch_symbols,eNB->proc[sched_subframe].frame_tx,subframe),
	dlsch_harq->nb_rb,
	dlsch_harq->mcs,
	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
	dlsch_harq->rvidx,
	dlsch_harq->round);
1051

1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 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
#if defined(MESSAGE_CHART_GENERATOR_PHY)
      MSC_LOG_TX_MESSAGE(
        MSC_PHY_ENB,MSC_PHY_UE,
        NULL,0,
        "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
        eNB->proc[sched_subframe].frame_tx, subframe,
        input_buffer_length,
        get_G(fp,
        		dlsch_harq->nb_rb,
        		dlsch_harq->rb_alloc,
        		get_Qm(dlsch_harq->mcs),
        		dlsch_harq->Nl,
        		num_pdcch_symbols,eNB->proc[sched_subframe].frame_tx,subframe),
        dlsch_harq->nb_rb,
        dlsch_harq->mcs,
        pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
        dlsch_harq->rvidx,
        dlsch_harq->round);
#endif

      if (ue_stats) ue_stats->dlsch_sliding_cnt++;

      if (dlsch_harq->round == 0) {

	if (ue_stats)
	  ue_stats->dlsch_trials[harq_pid][0]++;

	if (eNB->mac_enabled==1) {
	  if (ra_flag == 0) {
	    DLSCH_pdu = mac_xface->get_dlsch_sdu(eNB->Mod_id,
						 eNB->CC_id,
						 eNB->proc[sched_subframe].frame_tx,
						 dlsch->rnti,
						 0);
	  }
	  else {
	    int16_t crnti = mac_xface->fill_rar(eNB->Mod_id,
						eNB->CC_id,
						eNB->proc[sched_subframe].frame_tx,
						DLSCH_pdu_rar,
						fp->N_RB_UL,
						input_buffer_length);
	    DLSCH_pdu = DLSCH_pdu_rar;

	    int UE_id;

	    if (crnti!=0) 
	      UE_id = add_ue(crnti,eNB);
	    else 
	      UE_id = -1;
	    
	    if (UE_id==-1) {
	      LOG_W(PHY,"[eNB] Max user count reached.\n");
	      mac_xface->cancel_ra_proc(eNB->Mod_id,
					eNB->CC_id,
					eNB->proc[sched_subframe].frame_tx,
					crnti);
	    } else {
	      eNB->eNB_UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE;
	      // Initialize indicator for first SR (to be cleared after ConnectionSetup is acknowledged)
	      eNB->first_sr[(uint32_t)UE_id] = 1;
	      
	      generate_eNB_ulsch_params_from_rar(DLSCH_pdu,
						 eNB->proc[sched_subframe].frame_tx,
						 (subframe),
						 eNB->ulsch_eNB[(uint32_t)UE_id],
						 fp);
	      
	      eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 1;
	      
	      get_Msg3_alloc(fp,
			     subframe,
			     eNB->proc[sched_subframe].frame_tx,
			     &eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
			     &eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
	      LOG_D(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n",
		    eNB->proc[sched_subframe].frame_tx,
		    subframe,
		    UE_id,
		    eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
		    eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
	    }
	    if (ue_stats) ue_stats->total_TBS_MAC += dlsch_harq->TBS;
	  }
	}
	else {
	  DLSCH_pdu = DLSCH_pdu_tmp;
	  
	  for (i=0; i<input_buffer_length; i++)
	    DLSCH_pdu[i] = (unsigned char)(taus()&0xff);
	}
	
#if defined(SMBV) 
1145

1146 1147 1148 1149 1150
        // Configures the data source of allocation (allocation is configured by DCI)
        if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
          LOG_D(PHY,"[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
          smbv_configure_datalist_for_user(smbv_fname, find_ue(dlsch->rnti,eNB)+1, DLSCH_pdu, input_buffer_length);
        }
1151

1152
#endif
1153

1154 1155 1156 1157 1158 1159 1160 1161 1162

#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
        LOG_T(PHY,"eNB DLSCH SDU: \n");

        for (i=0; i<dlsch_harq->TBS>>3; i++)
          LOG_T(PHY,"%"PRIx8".",DLSCH_pdu[i]);

        LOG_T(PHY,"\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1163
#endif
1164 1165 1166 1167 1168 1169 1170 1171 1172
#endif
      } else {
        ue_stats->dlsch_trials[harq_pid][dlsch_harq->round]++;
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
        LOG_D(PHY,"[eNB] This DLSCH is a retransmission\n");
#endif
#endif
      }
1173

1174
      if (abstraction_flag==0) {
1175

1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
	LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag);
        // 36-212
        start_meas(&eNB->dlsch_encoding_stats);
        dlsch_encoding(DLSCH_pdu,
                       fp,
                       num_pdcch_symbols,
                       dlsch,
                       eNB->proc[sched_subframe].frame_tx,subframe,
                       &eNB->dlsch_rate_matching_stats,
                       &eNB->dlsch_turbo_encoding_stats,
                       &eNB->dlsch_interleaving_stats);
        stop_meas(&eNB->dlsch_encoding_stats);
        // 36-211
        start_meas(&eNB->dlsch_scrambling_stats);
        dlsch_scrambling(fp,
                         0,
                         dlsch,
                         get_G(fp,
                               dlsch_harq->nb_rb,
                               dlsch_harq->rb_alloc,
                               get_Qm(dlsch_harq->mcs),
                               dlsch_harq->Nl,
                               num_pdcch_symbols,eNB->proc[sched_subframe].frame_tx,subframe),
                         0,
                         subframe<<1);
        stop_meas(&eNB->dlsch_scrambling_stats);
        start_meas(&eNB->dlsch_modulation_stats);
1203 1204


1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
        dlsch_modulation(eNB->lte_eNB_common_vars.txdataF[0],
			 AMP,
			 subframe,
			 fp,
			 num_pdcch_symbols,
			 dlsch,
			 dlsch1);
	
        stop_meas(&eNB->dlsch_modulation_stats);
      }
1215

1216 1217 1218 1219 1220 1221 1222
#ifdef PHY_ABSTRACTION
      else {
        start_meas(&eNB->dlsch_encoding_stats);
        dlsch_encoding_emul(eNB,
                            DLSCH_pdu,
                            dlsch);
        stop_meas(&eNB->dlsch_encoding_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1223
      }
1224

1225 1226 1227
#endif
      dlsch->active = 0;
}
1228

1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
void phy_procedures_eNB_TX(unsigned char sched_subframe,
			   PHY_VARS_eNB *eNB,
			   uint8_t abstraction_flag,
                           relaying_type_t r_type,
			   PHY_VARS_RN *rn)
{
  UNUSED(rn);
  uint16_t input_buffer_length;
  uint32_t i,aa;
  uint8_t harq_pid;
  DCI_PDU *DCI_pdu;
  DCI_PDU DCI_pdu_tmp;
  int8_t UE_id;
  uint8_t num_pdcch_symbols=0;
  uint8_t ul_subframe;
  uint32_t ul_frame;
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  DCI_ALLOC_t *dci_alloc=(DCI_ALLOC_t *)NULL;
1247

1248 1249 1250 1251 1252 1253 1254
#if defined(SMBV) 
  // counts number of allocations in subframe
  // there is at least one allocation for PDCCH
  uint8_t smbv_alloc_cnt = 1;
#endif
  int frame = eNB->proc[sched_subframe].frame_tx;
  int subframe = eNB->proc[sched_subframe].subframe_tx;
1255

1256 1257
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,1);
  start_meas(&eNB->phy_proc_tx);
1258

1259 1260
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    // If we've dropped the UE, go back to PRACH mode for this UE
1261

1262 1263 1264 1265 1266 1267 1268 1269 1270 1271
    if (eNB->eNB_UE_stats[i].ulsch_consecutive_errors == ULSCH_max_consecutive_errors) {
      LOG_W(PHY,"[eNB %d, CC %d] frame %d, subframe %d, UE %d: ULSCH consecutive error count reached %u, triggering UL Failure\n",
            eNB->Mod_id,eNB->CC_id,frame,subframe, i, eNB->eNB_UE_stats[i].ulsch_consecutive_errors);
      eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
      mac_xface->UL_failure_indication(eNB->Mod_id,
				       eNB->CC_id,
				       frame,
				       eNB->eNB_UE_stats[i].crnti,
				       subframe);
				       
Raymond Knopp's avatar
 
Raymond Knopp committed
1272
    }
1273
	
1274

1275
  }
1276 1277


1278 1279 1280 1281 1282
// Get scheduling info for next subframe
// This is called only for the CC_id = 0 and triggers scheduling for all CC_id's
  if (eNB->mac_enabled==1) {
    if (eNB->CC_id == 0) {
      mac_xface->eNB_dlsch_ulsch_scheduler(eNB->Mod_id,0,eNB->proc[sched_subframe].frame_tx,subframe);//,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1283
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1284
  }
1285

1286 1287 1288 1289 1290 1291 1292
// clear the transmit data array for the current subframe
  if (abstraction_flag==0) {
    for (aa=0; aa<fp->nb_antennas_tx_eNB; aa++) {      
      memset(&eNB->lte_eNB_common_vars.txdataF[0][aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)],
             0,fp->ofdm_symbol_size*(fp->symbols_per_tti)*sizeof(int32_t));
    }
  }
1293

1294 1295 1296 1297 1298 1299 1300
  if (is_pmch_subframe(eNB->proc[sched_subframe].frame_tx,subframe,fp)) {
    pmch_procedures(eNB,rn,subframe,sched_subframe,abstraction_flag,r_type);
  }
  else {
    // this is not a pmch subframe, so generate PSS/SSS/PBCH
    common_signal_procedures(subframe,sched_subframe,eNB,abstraction_flag);
  }
1301

1302
#if defined(SMBV) 
1303

Raymond Knopp's avatar
 
Raymond Knopp committed
1304
  // PBCH takes one allocation
1305
  if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
1306
    if (subframe==0)
Raymond Knopp's avatar
 
Raymond Knopp committed
1307 1308
      smbv_alloc_cnt++;
  }
1309

1310
#endif
1311

1312
  if (eNB->mac_enabled==1) {
1313 1314
    // Parse DCI received from MAC
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1);
1315 1316 1317
    DCI_pdu = mac_xface->get_dci_sdu(eNB->Mod_id,
				     eNB->CC_id,
				     eNB->proc[sched_subframe].frame_tx,
1318 1319 1320 1321
				     subframe);
  }
  else {
    DCI_pdu = &DCI_pdu_tmp;
1322
#ifdef EMOS_CHANNEL
1323
    fill_dci_emos(DCI_pdu,sched_subframe,eNB);
1324
#else
1325
    fill_dci(DCI_pdu,sched_subframe,eNB);
1326
#endif
1327
  }
1328

Raymond Knopp's avatar
 
Raymond Knopp committed
1329
  // clear existing ulsch dci allocations before applying info from MAC  (this is table
1330 1331
  ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
  ul_frame = pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe);
1332

1333 1334 1335
  if ((subframe_select(fp,ul_subframe)==SF_UL) ||
      (fp->frame_type == FDD)) {
    harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
1336

1337
    // clear DCI allocation maps for new subframe
1338
    for (i=0; i<NUMBER_OF_UE_MAX; i++)
1339 1340 1341
      if (eNB->ulsch_eNB[i]) {
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc=0;
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1342 1343
      }
  }
1344

Raymond Knopp's avatar
 
Raymond Knopp committed
1345
  // clear previous allocation information for all UEs
1346
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
1347
    eNB->dlsch_eNB[i][0]->subframe_tx[subframe] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1348
  }
1349 1350


1351
  num_pdcch_symbols = DCI_pdu->num_pdcch_symbols;
Raymond Knopp's avatar
Raymond Knopp committed
1352
  LOG_D(PHY,"num_pdcch_symbols %"PRIu8",(dci common %"PRIu8", dci uespec %"PRIu8"\n",num_pdcch_symbols,
1353 1354
        DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);

1355
#if defined(SMBV) 
Raymond Knopp's avatar
 
Raymond Knopp committed
1356
  // Sets up PDCCH and DCI table
1357 1358 1359
  if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4) && ((DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci)>0)) {
    LOG_D(PHY,"[SMBV] Frame %3d, SF %d PDCCH, number of DCIs %d\n",eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
    dump_dci(fp,&DCI_pdu->dci_alloc[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1360 1361
    smbv_configure_pdcch(smbv_fname,(smbv_frame_cnt*10) + (subframe),num_pdcch_symbols,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
  }
1362 1363
#endif

1364 1365
  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->num_pdcch_symbols);

1366
  // loop over all DCIs for this subframe to generate DLSCH allocations
1367 1368 1369 1370 1371
  for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
    LOG_D(PHY,"[eNB] Subframe %d: DCI %d/%d : rnti %x, CCEind %d\n",subframe,i,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,DCI_pdu->dci_alloc[i].rnti,DCI_pdu->dci_alloc[i].firstCCE);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->dci_alloc[i].rnti);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->dci_alloc[i].format);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->dci_alloc[i].firstCCE);
1372
    dci_alloc = &DCI_pdu->dci_alloc[i];
1373

1374 1375 1376 1377
    if ((dci_alloc->rnti<= P_RNTI) && 
	(dci_alloc->ra_flag!=1)) {
      if (eNB->mac_enabled==1)
	UE_id = find_ue((int16_t)dci_alloc->rnti,eNB);
1378 1379
      else
	UE_id = i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1380
    }
1381 1382 1383
    else UE_id=0;
    
    generate_eNB_dlsch_params(frame,subframe,sched_subframe,eNB,dci_alloc,UE_id);
1384

Raymond Knopp's avatar
 
Raymond Knopp committed
1385
  }
1386

1387 1388
  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,(frame*10)+subframe);

Raymond Knopp's avatar
 
Raymond Knopp committed
1389
  // Apply physicalConfigDedicated if needed
1390 1391 1392 1393
  // This is for UEs that have received this IE, which changes these DL and UL configuration, we apply after a delay for the eNodeB UL parameters
  phy_config_dedicated_eNB_step2(eNB);
  
  // Now loop again over the DCIs for UL configuration
1394
  for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
1395 1396 1397
    if (dci_alloc->format == format0) {  // this is a ULSCH allocation
      if (eNB->mac_enabled==1)
	UE_id = find_ue((int16_t)dci_alloc->rnti,eNB);
1398 1399
      else
	UE_id = i;
1400
      
1401 1402 1403
      if (UE_id<0) { // should not happen, log an error and exit, this is a fatal error
	LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Unknown UE_id for rnti %"PRIx16"\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,dci_alloc->rnti);
	mac_xface->macphy_exit("FATAL\n"); 
1404
      }
1405
      generate_eNB_ulsch_params(frame,subframe,sched_subframe,eNB,dci_alloc,UE_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
1406
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1407
  }
1408

1409 1410


Lionel Gauthier's avatar
Lionel Gauthier committed
1411 1412


Raymond Knopp's avatar
 
Raymond Knopp committed
1413 1414
  // if we have DCI to generate do it now
  if ((DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci)>0) {
Lionel Gauthier's avatar
Lionel Gauthier committed
1415

1416 1417

  } else { // for emulation!!
1418 1419
    eNB->num_ue_spec_dci[(subframe)&1]=0;
    eNB->num_common_dci[(subframe)&1]=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1420
  }
1421

Raymond Knopp's avatar
 
Raymond Knopp committed
1422
  if (abstraction_flag == 0) {
1423

Raymond Knopp's avatar
 
Raymond Knopp committed
1424
    if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0)
1425
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx, subframe,
1426 1427 1428 1429 1430 1431 1432
            DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);

    num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci,
                                         DCI_pdu->Num_common_dci,
                                         DCI_pdu->dci_alloc,
                                         0,
                                         AMP,
1433 1434
                                         fp,
                                         eNB->lte_eNB_common_vars.txdataF[0],
1435
                                         subframe);
Raymond Knopp's avatar
Raymond Knopp committed
1436

Raymond Knopp's avatar
 
Raymond Knopp committed
1437
  }
1438

1439
#ifdef PHY_ABSTRACTION // FIXME this ifdef seems suspicious
Raymond Knopp's avatar
 
Raymond Knopp committed
1440
  else {
1441 1442
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_to_emul\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx, subframe);
    num_pdcch_symbols = generate_dci_top_emul(eNB,DCI_pdu->Num_ue_spec_dci,DCI_pdu->Num_common_dci,DCI_pdu->dci_alloc,subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1443
  }
1444

1445 1446
#endif

1447
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
1448

Raymond Knopp's avatar
 
Raymond Knopp committed
1449
  // Check for SI activity
1450

1451
  if (eNB->dlsch_eNB_SI->active == 1) {
1452

1453
    pdsch_procedures(eNB,eNB->dlsch_eNB_SI,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,0,subframe,sched_subframe,num_pdcch_symbols,abstraction_flag);
1454

1455
#if defined(SMBV) 
1456

Raymond Knopp's avatar
 
Raymond Knopp committed
1457
    // Configures the data source of allocation (allocation is configured by DCI)
1458 1459
    if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, Configuring SI payload in SF %d alloc %"PRIu8"\n",eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1460 1461
      smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), DLSCH_pdu, input_buffer_length);
    }
1462

1463
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1464
  }
Lionel Gauthier's avatar
Lionel Gauthier committed
1465

Raymond Knopp's avatar
 
Raymond Knopp committed
1466
  // Check for RA activity
1467
  if (eNB->dlsch_eNB_ra->active == 1) {
1468

1469
#if defined(SMBV) 
1470

1471 1472 1473 1474 1475 1476
    // Configures the data source of allocation (allocation is configured by DCI)
    if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, Configuring RA payload in SF %d alloc %"PRIu8"\n",eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
      smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), dlsch_input_buffer, input_buffer_length);
    }
    
1477
#endif
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
    
    
    LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d, subframe %d: Calling generate_dlsch (RA) with input size = %"PRIu16",Msg3 frame %"PRIu32", Msg3 subframe %"PRIu8"\n",
	  eNB->Mod_id,
	  eNB->proc[sched_subframe].frame_tx, subframe,input_buffer_length,
	  eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
	  eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
    
    pdsch_procedures(eNB,eNB->dlsch_eNB_ra,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,1,subframe,sched_subframe,num_pdcch_symbols,abstraction_flag);
    
    
    eNB->dlsch_eNB_ra->active = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1490
  }
1491
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1492
  // Now scan UE specific DLSCH
1493 1494
  for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
  {
1495 1496 1497
    if ((eNB->dlsch_eNB[(uint8_t)UE_id][0])&&
        (eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&&
        (eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 1)) {
1498

1499
      pdsch_procedures(eNB,eNB->dlsch_eNB[(uint8_t)UE_id][0],eNB->dlsch_eNB[(uint8_t)UE_id][1],&eNB->eNB_UE_stats[(uint32_t)UE_id],0,subframe,sched_subframe,num_pdcch_symbols,abstraction_flag);
1500 1501


Raymond Knopp's avatar
 
Raymond Knopp committed
1502
    }
Lionel Gauthier's avatar
Lionel Gauthier committed
1503

1504 1505 1506
    else if ((eNB->dlsch_eNB[(uint8_t)UE_id][0])&&
             (eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&&
             (eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 0)) {
1507

Raymond Knopp's avatar
 
Raymond Knopp committed
1508
      // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
1509
      eNB->dlsch_eNB[(uint8_t)UE_id][0]->subframe_tx[subframe]=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1510
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1511
  }
1512

1513 1514


Raymond Knopp's avatar
 
Raymond Knopp committed
1515
  // if we have PHICH to generate
1516

1517
  if (is_phich_subframe(fp,subframe))
1518
  {
1519
    generate_phich_top(eNB,
1520 1521 1522 1523
                       sched_subframe,
                       AMP,
                       0,
                       abstraction_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
1524
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1525

1526 1527


1528
#ifdef EMOS
1529
  phy_procedures_emos_eNB_TX(subframe, eNB);
1530
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1531

1532
#if !(defined(EXMIMO) || defined(OAI_USRP) || defined (CPRIGW))
1533 1534 1535

  if (abstraction_flag==0)
  {
1536 1537 1538 1539 1540 1541 1542 1543 1544 1545
    start_meas(&eNB->ofdm_mod_stats);
    do_OFDM_mod(eNB->lte_eNB_common_vars.txdataF[0],
                eNB->lte_eNB_common_vars.txdata[0],
                eNB->proc[sched_subframe].frame_tx,subframe<<1,
                fp);
    do_OFDM_mod(eNB->lte_eNB_common_vars.txdataF[0],
                eNB->lte_eNB_common_vars.txdata[0],
                eNB->proc[sched_subframe].frame_tx,1+(subframe<<1),
                fp);
    stop_meas(&eNB->ofdm_mod_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1546
  }
1547

Raymond Knopp's avatar
 
Raymond Knopp committed
1548
#endif
1549

1550
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,0);
1551
  stop_meas(&eNB->phy_proc_tx);
1552 1553


1554 1555
}

1556
void process_Msg3(PHY_VARS_eNB *eNB,uint8_t sched_subframe,uint8_t UE_id, uint8_t harq_pid)
1557
{
Raymond Knopp's avatar
 
Raymond Knopp committed
1558
  // this prepares the demodulation of the first PUSCH of a new user, containing Msg3
1559

1560 1561
  int subframe = eNB->proc[sched_subframe].subframe_rx;
  int frame = eNB->proc[sched_subframe].frame_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1562

Raymond Knopp's avatar
 
Raymond Knopp committed
1563
  LOG_D(PHY,"[eNB %d][RAPROC] frame %d : subframe %d : process_Msg3 UE_id %d (active %d, subframe %d, frame %d)\n",
1564
        eNB->Mod_id,
1565
        frame,subframe,
1566 1567 1568 1569
        UE_id,eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active,
        eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe,
        eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame);
  eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 0;
1570

1571 1572 1573
  if ((eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active == 1) &&
      (eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe == subframe) &&
      (eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame == (uint32_t)frame))   {
1574

1575
    //    harq_pid = 0;
1576

1577 1578 1579
    eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 0;
    eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 1;
    eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag=1;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1580
    LOG_D(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Setting subframe_scheduling_flag (Msg3) for UE %d\n",
1581
          eNB->Mod_id,
1582
          frame,subframe,UE_id);
1583 1584 1585 1586 1587 1588 1589 1590 1591
  }
}


// This function retrieves the harq_pid of the corresponding DLSCH process
// and updates the error statistics of the DLSCH based on the received ACK
// info from UE along with the round index.  It also performs the fine-grain
// rate-adaptation based on the error statistics derived from the ACK/NAK process

1592 1593
void process_HARQ_feedback(uint8_t UE_id,
                           uint8_t sched_subframe,
1594
                           PHY_VARS_eNB *eNB,
1595 1596 1597 1598 1599
                           uint8_t pusch_flag,
                           uint8_t *pucch_payload,
                           uint8_t pucch_sel,
                           uint8_t SR_payload)
{
1600

1601
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1602
  uint8_t dl_harq_pid[8],dlsch_ACK[8],dl_subframe;
1603 1604
  LTE_eNB_DLSCH_t *dlsch             =  eNB->dlsch_eNB[(uint32_t)UE_id][0];
  LTE_eNB_UE_stats *ue_stats         =  &eNB->eNB_UE_stats[(uint32_t)UE_id];
1605
  LTE_DL_eNB_HARQ_t *dlsch_harq_proc;
1606
  uint8_t subframe_m4,M,m;
1607 1608
  int mp;
  int all_ACKed=1,nb_alloc=0,nb_ACK=0;
1609 1610 1611
  int frame = eNB->proc[sched_subframe].frame_rx;
  int subframe = eNB->proc[sched_subframe].subframe_rx;
  int harq_pid = subframe2harq_pid( fp,frame,subframe);
1612

1613 1614

  if (fp->frame_type == FDD) { //FDD
1615
    subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
1616

1617 1618
    dl_harq_pid[0] = dlsch->harq_ids[subframe_m4];
    M=1;
1619

1620
    if (pusch_flag == 1) {
1621
      dlsch_ACK[0] = eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
1622
      if (dlsch->subframe_tx[subframe_m4]==1)
1623
      LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUSCH for subframe %d\n",eNB->Mod_id,
1624 1625 1626
	    frame,dlsch_ACK[0],subframe_m4);
    }
    else {
1627
      dlsch_ACK[0] = pucch_payload[0];
1628
      LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUCCH for subframe %d\n",eNB->Mod_id,
1629
	    frame,dlsch_ACK[0],subframe_m4);
kaltenbe's avatar
kaltenbe committed
1630
      /*
1631 1632
      if (dlsch_ACK[0]==0)
	AssertFatal(0,"Exiting on NAK on PUCCH\n");
kaltenbe's avatar
kaltenbe committed
1633
      */
1634
    }
1635

Lionel Gauthier's avatar
Lionel Gauthier committed
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649

#if defined(MESSAGE_CHART_GENERATOR_PHY)
    MSC_LOG_RX_MESSAGE(
      MSC_PHY_ENB,MSC_PHY_UE,
      NULL,0,
      "%05u:%02u %s received %s  rnti %x harq id %u  tx SF %u",
      frame,subframe,
      (pusch_flag == 1)?"PUSCH":"PUCCH",
      (dlsch_ACK[0])?"ACK":"NACK",
      dlsch->rnti,
      dl_harq_pid[0],
      subframe_m4
      );
#endif
1650 1651
  } else { // TDD Handle M=1,2 cases only

1652
    M=ul_ACK_subframe2_M(fp,
1653 1654
                         subframe);

1655 1656 1657 1658 1659 1660 1661 1662
    // Now derive ACK information for TDD
    if (pusch_flag == 1) { // Do PUSCH ACK/NAK first
      // detect missing DAI
      //FK: this code is just a guess
      //RK: not exactly, yes if scheduled from PHICH (i.e. no DCI format 0)
      //    otherwise, it depends on how many of the PDSCH in the set are scheduled, we can leave it like this,
      //    but we have to adapt the code below.  For example, if only one out of 2 are scheduled, only 1 bit o_ACK is used

1663 1664 1665
      dlsch_ACK[0] = eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
      dlsch_ACK[1] = (eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode == bundling)
                     ?eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]:eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[1];
1666
    }
1667

1668
    else {  // PUCCH ACK/NAK
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703
      if ((SR_payload == 1)&&(pucch_sel!=2)) {  // decode Table 7.3 if multiplexing and SR=1
        nb_ACK = 0;

        if (M == 2) {
          if ((pucch_payload[0] == 1) && (pucch_payload[1] == 1)) // b[0],b[1]
            nb_ACK = 1;
          else if ((pucch_payload[0] == 1) && (pucch_payload[1] == 0))
            nb_ACK = 2;
        } else if (M == 3) {
          if ((pucch_payload[0] == 1) && (pucch_payload[1] == 1))
            nb_ACK = 1;
          else if ((pucch_payload[0] == 1) && (pucch_payload[1] == 0))
            nb_ACK = 2;
          else if ((pucch_payload[0] == 0) && (pucch_payload[1] == 1))
            nb_ACK = 3;
        }
      } else if (pucch_sel == 2) { // bundling or M=1
        dlsch_ACK[0] = pucch_payload[0];
        dlsch_ACK[1] = pucch_payload[0];
      } else { // multiplexing with no SR, this is table 10.1
        if (M==1)
          dlsch_ACK[0] = pucch_payload[0];
        else if (M==2) {
          if (((pucch_sel == 1) && (pucch_payload[0] == 1) && (pucch_payload[1] == 1)) ||
              ((pucch_sel == 0) && (pucch_payload[0] == 0) && (pucch_payload[1] == 1)))
            dlsch_ACK[0] = 1;
          else
            dlsch_ACK[0] = 0;

          if (((pucch_sel == 1) && (pucch_payload[0] == 1) && (pucch_payload[1] == 1)) ||
              ((pucch_sel == 1) && (pucch_payload[0] == 0) && (pucch_payload[1] == 0)))
            dlsch_ACK[1] = 1;
          else
            dlsch_ACK[1] = 0;
        }
1704
      }
1705
    }
1706 1707 1708 1709
  }

  // handle case where positive SR was transmitted with multiplexing
  if ((SR_payload == 1)&&(pucch_sel!=2)&&(pusch_flag == 0)) {
1710
    nb_alloc = 0;
1711 1712

    for (m=0; m<M; m++) {
1713
      dl_subframe = ul_ACK_subframe2_dl_subframe(fp,
1714 1715 1716 1717 1718
                    subframe,
                    m);

      if (dlsch->subframe_tx[dl_subframe]==1)
        nb_alloc++;
1719
    }
1720

1721 1722
    if (nb_alloc == nb_ACK)
      all_ACKed = 1;
1723
    else
1724
      all_ACKed = 0;
1725 1726 1727
  }


1728
  for (m=0,mp=-1; m<M; m++) {
1729

1730
    dl_subframe = ul_ACK_subframe2_dl_subframe(fp,
1731 1732
                  subframe,
                  m);
1733

1734 1735
    if (dlsch->subframe_tx[dl_subframe]==1) {
      if (pusch_flag == 1)
1736
        mp++;
1737
      else
1738
        mp = m;
1739

1740
      dl_harq_pid[m]     = dlsch->harq_ids[dl_subframe];
1741

1742
      if ((pucch_sel != 2)&&(pusch_flag == 0)) { // multiplexing
1743 1744 1745 1746
        if ((SR_payload == 1)&&(all_ACKed == 1))
          dlsch_ACK[m] = 1;
        else
          dlsch_ACK[m] = 0;
1747
      }
1748

1749
      if (dl_harq_pid[m]<dlsch->Mdlharq) {
1750 1751
        dlsch_harq_proc = dlsch->harq_processes[dl_harq_pid[m]];
#ifdef DEBUG_PHY_PROC
1752
        LOG_D(PHY,"[eNB %d][PDSCH %x/%d] subframe %d, status %d, round %d (mcs %d, rv %d, TBS %d)\n",eNB->Mod_id,
1753 1754 1755 1756 1757 1758 1759 1760 1761
              dlsch->rnti,dl_harq_pid[m],dl_subframe,
              dlsch_harq_proc->status,dlsch_harq_proc->round,
              dlsch->harq_processes[dl_harq_pid[m]]->mcs,
              dlsch->harq_processes[dl_harq_pid[m]]->rvidx,
              dlsch->harq_processes[dl_harq_pid[m]]->TBS);

        if (dlsch_harq_proc->status==DISABLED)
          LOG_E(PHY,"dlsch_harq_proc is disabled? \n");

1762
#endif
1763 1764 1765 1766 1767 1768 1769 1770

        if ((dl_harq_pid[m]<dlsch->Mdlharq) &&
            (dlsch_harq_proc->status == ACTIVE)) {
          // dl_harq_pid of DLSCH is still active

          if ( dlsch_ACK[mp]==0) {
            // Received NAK
#ifdef DEBUG_PHY_PROC
1771
            LOG_D(PHY,"[eNB %d][PDSCH %x/%d] M = %d, m= %d, mp=%d NAK Received in round %d, requesting retransmission\n",eNB->Mod_id,
1772
                  dlsch->rnti,dl_harq_pid[m],M,m,mp,dlsch_harq_proc->round);
1773
#endif
1774 1775 1776 1777 1778 1779 1780 1781 1782 1783

            if (dlsch_harq_proc->round == 0)
              ue_stats->dlsch_NAK_round0++;

            ue_stats->dlsch_NAK[dl_harq_pid[m]][dlsch_harq_proc->round]++;


            // then Increment DLSCH round index
            dlsch_harq_proc->round++;

1784

1785
            if (dlsch_harq_proc->round == dlsch->Mlimit) {
1786 1787
              // This was the last round for DLSCH so reset round and increment l2_error counter
#ifdef DEBUG_PHY_PROC
1788
              LOG_W(PHY,"[eNB %d][PDSCH %x/%d] DLSCH retransmissions exhausted, dropping packet\n",eNB->Mod_id,
1789
                    dlsch->rnti,dl_harq_pid[m]);
1790
#endif
Lionel Gauthier's avatar
Lionel Gauthier committed
1791
#if defined(MESSAGE_CHART_GENERATOR_PHY)
1792
              MSC_LOG_EVENT(MSC_PHY_ENB, "0 HARQ DLSCH Failed RNTI %"PRIx16" round %u",
1793 1794
                            dlsch->rnti,
                            dlsch_harq_proc->round);
Lionel Gauthier's avatar
Lionel Gauthier committed
1795
#endif
Lionel Gauthier's avatar
Lionel Gauthier committed
1796

1797 1798 1799
              dlsch_harq_proc->round = 0;
              ue_stats->dlsch_l2_errors[dl_harq_pid[m]]++;
              dlsch_harq_proc->status = SCH_IDLE;
1800
              put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
1801 1802 1803 1804
              dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;
            }
          } else {
#ifdef DEBUG_PHY_PROC
1805
            LOG_D(PHY,"[eNB %d][PDSCH %x/%d] ACK Received in round %d, resetting process\n",eNB->Mod_id,
1806
                  dlsch->rnti,dl_harq_pid[m],dlsch_harq_proc->round);
1807
#endif
1808 1809 1810 1811 1812
            ue_stats->dlsch_ACK[dl_harq_pid[m]][dlsch_harq_proc->round]++;

            // Received ACK so set round to 0 and set dlsch_harq_pid IDLE
            dlsch_harq_proc->round  = 0;
            dlsch_harq_proc->status = SCH_IDLE;
1813
            put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
1814 1815 1816
            dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;

            ue_stats->total_TBS = ue_stats->total_TBS +
1817
                                  eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
1818 1819
            /*
              ue_stats->total_transmitted_bits = ue_stats->total_transmitted_bits +
1820
              eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834
            */
          }

          // Do fine-grain rate-adaptation for DLSCH
          if (ue_stats->dlsch_NAK_round0 > dlsch->error_threshold) {
            if (ue_stats->dlsch_mcs_offset == 1)
              ue_stats->dlsch_mcs_offset=0;
            else
              ue_stats->dlsch_mcs_offset=-1;
          }

#ifdef DEBUG_PHY_PROC
          LOG_D(PHY,"[process_HARQ_feedback] Frame %d Setting round to %d for pid %d (subframe %d)\n",frame,
                dlsch_harq_proc->round,dl_harq_pid[m],subframe);
1835
#endif
1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857

          // Clear NAK stats and adjust mcs offset
          // after measurement window timer expires
          if (ue_stats->dlsch_sliding_cnt == dlsch->ra_window_size) {
            if ((ue_stats->dlsch_mcs_offset == 0) && (ue_stats->dlsch_NAK_round0 < 2))
              ue_stats->dlsch_mcs_offset = 1;

            if ((ue_stats->dlsch_mcs_offset == 1) && (ue_stats->dlsch_NAK_round0 > 2))
              ue_stats->dlsch_mcs_offset = 0;

            if ((ue_stats->dlsch_mcs_offset == 0) && (ue_stats->dlsch_NAK_round0 > 2))
              ue_stats->dlsch_mcs_offset = -1;

            if ((ue_stats->dlsch_mcs_offset == -1) && (ue_stats->dlsch_NAK_round0 < 2))
              ue_stats->dlsch_mcs_offset = 0;

            ue_stats->dlsch_NAK_round0 = 0;
            ue_stats->dlsch_sliding_cnt = 0;
          }


        }
1858
      }
1859
    }
1860 1861 1862
  }
}

1863
void get_n1_pucch_eNB(PHY_VARS_eNB *eNB,
1864 1865 1866 1867 1868 1869 1870
                      uint8_t UE_id,
                      uint8_t sched_subframe,
                      int16_t *n1_pucch0,
                      int16_t *n1_pucch1,
                      int16_t *n1_pucch2,
                      int16_t *n1_pucch3)
{
1871

1872
  LTE_DL_FRAME_PARMS *frame_parms=&eNB->lte_frame_parms;
1873
  uint8_t nCCE0,nCCE1;
1874
  int sf;
1875 1876
  int frame = eNB->proc[sched_subframe].frame_rx;
  int subframe = eNB->proc[sched_subframe].subframe_rx;
1877 1878

  if (frame_parms->frame_type == FDD ) {
1879
    sf = (subframe<4) ? (subframe+6) : (subframe-4);
1880

1881 1882
    if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[sf]>0) {
      *n1_pucch0 = frame_parms->pucch_config_common.n1PUCCH_AN + eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf];
1883
      *n1_pucch1 = -1;
1884
    } else {
1885 1886 1887
      *n1_pucch0 = -1;
      *n1_pucch1 = -1;
    }
1888
  } else {
1889

1890 1891 1892
    switch (frame_parms->tdd_config) {
    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL
      if (subframe == 2) {  // ACK subframes 5 and 6
1893 1894
        /*  if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
          nCCE1 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6];
1895 1896 1897 1898 1899
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
          }
          else
          *n1_pucch1 = -1;*/

1900 1901
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5];
1902 1903 1904 1905 1906 1907 1908
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch0 = -1;

        *n1_pucch1 = -1;
      } else if (subframe == 3) { // ACK subframe 9

1909 1910
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9];
1911 1912 1913 1914 1915 1916 1917 1918 1919
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch0 = -1;

        *n1_pucch1 = -1;

      } else if (subframe == 7) { // ACK subframes 0 and 1
        //harq_ack[0].nCCE;
        //harq_ack[1].nCCE;
1920 1921
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0];
1922 1923 1924 1925 1926 1927 1928
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch0 = -1;

        *n1_pucch1 = -1;
      } else if (subframe == 8) { // ACK subframes 4
        //harq_ack[4].nCCE;
1929 1930
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[4]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[4];
1931 1932 1933 1934 1935 1936 1937
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch0 = -1;

        *n1_pucch1 = -1;
      } else {
        LOG_D(PHY,"[eNB %d] frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
1938
              eNB->Mod_id,
1939 1940 1941
              frame,
              subframe,frame_parms->tdd_config);
        return;
1942
      }
1943

1944
      break;
1945

1946 1947
    case 3:  // DL:S:UL:UL:UL:DL:DL:DL:DL:DL
      if (subframe == 2) {  // ACK subframes 5,6 and 1 (S in frame-2), forget about n-11 for the moment (S-subframe)
1948 1949
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
          nCCE1 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6];
1950 1951 1952 1953
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch1 = -1;

1954 1955
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5];
1956 1957 1958 1959 1960
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch0 = -1;
      } else if (subframe == 3) { // ACK subframes 7 and 8
        LOG_D(PHY,"get_n1_pucch_eNB : subframe 3, subframe_tx[7] %d, subframe_tx[8] %d\n",
1961
              eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7],eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]);
1962

1963 1964
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]>0) {
          nCCE1 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[8];
1965 1966 1967 1968 1969
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
          LOG_D(PHY,"nCCE1 %d, n1_pucch1 %d\n",nCCE1,*n1_pucch1);
        } else
          *n1_pucch1 = -1;

1970 1971
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[7];
1972 1973 1974 1975 1976
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
          LOG_D(PHY,"nCCE0 %d, n1_pucch0 %d\n",nCCE0,*n1_pucch0);
        } else
          *n1_pucch0 = -1;
      } else if (subframe == 4) { // ACK subframes 9 and 0
1977 1978
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
          nCCE1 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0];
1979 1980 1981 1982
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch1 = -1;

1983 1984
        if (eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
          nCCE0 = eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9];
1985 1986 1987 1988 1989
          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch0 = -1;
      } else {
        LOG_D(PHY,"[eNB %d] Frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
1990
              eNB->Mod_id,frame,subframe,frame_parms->tdd_config);
1991
        return;
1992
      }
1993

1994
      break;
1995 1996
    }  // switch tdd_config

1997 1998 1999
    // Don't handle the case M>2
    *n1_pucch2 = -1;
    *n1_pucch3 = -1;
2000 2001 2002
  }
}

2003
void prach_procedures(PHY_VARS_eNB *eNB,uint8_t sched_subframe,uint8_t abstraction_flag)
2004
{
2005

2006
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
2007 2008 2009 2010
  uint16_t preamble_energy_list[64],preamble_delay_list[64];
  uint16_t preamble_max,preamble_energy_max;
  uint16_t i;
  int8_t UE_id;
2011 2012 2013
  int subframe = eNB->proc[sched_subframe].subframe_rx;
  int frame = eNB->proc[sched_subframe].frame_rx;
  uint8_t CC_id = eNB->CC_id;
2014

2015 2016
  memset(&preamble_energy_list[0],0,64*sizeof(uint16_t));
  memset(&preamble_delay_list[0],0,64*sizeof(uint16_t));
2017

2018
  if (abstraction_flag == 0) {
2019 2020
    LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",eNB->Mod_id, 
          frame,subframe,dB_fixed(signal_energy(&eNB->lte_eNB_common_vars.rxdata[0][0][subframe*fp->samples_per_tti],512)) - eNB->rx_total_gain_eNB_dB);
2021

2022

2023
    rx_prach(eNB,
2024 2025 2026 2027 2028 2029 2030 2031
             subframe,
             preamble_energy_list,
             preamble_delay_list,
             frame,
             0);
  } else {
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {

2032
      LOG_D(PHY,"[RAPROC] UE_id %d (%p), generate_prach %d, UE RSI %d, eNB RSI %d preamble index %d\n",
2033 2034
            UE_id,PHY_vars_UE_g[UE_id][CC_id],PHY_vars_UE_g[UE_id][CC_id]->generate_prach,
            PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex,
2035
            fp->prach_config_common.rootSequenceIndex,
2036 2037
            PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex);

Raymond Knopp's avatar
 
Raymond Knopp committed
2038
      if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach==1) &&
2039
          (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex ==
2040
           fp->prach_config_common.rootSequenceIndex) ) {
2041 2042 2043
        preamble_energy_list[PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex] = 800;
        preamble_delay_list[PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex] = 5;

2044
      }
2045
    }
2046
  }
2047

2048 2049 2050
  preamble_energy_max = preamble_energy_list[0];
  preamble_max = 0;

2051
  for (i=1; i<64; i++) {
2052 2053 2054 2055
    if (preamble_energy_max < preamble_energy_list[i]) {
      preamble_energy_max = preamble_energy_list[i];
      preamble_max = i;
    }
2056 2057 2058
  }

#ifdef DEBUG_PHY_PROC
2059
  LOG_D(PHY,"[RAPROC] Most likely preamble %d, energy %d dB delay %d\n",
2060 2061 2062
        preamble_max,
        preamble_energy_list[preamble_max],
        preamble_delay_list[preamble_max]);
2063 2064
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2065
  if (preamble_energy_list[preamble_max] > 580) {
2066

2067
    UE_id = find_next_ue_index(eNB);
2068
 
2069
    if (UE_id>=0) {
2070
      eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits
2071

2072
      eNB->eNB_UE_stats[(uint32_t)UE_id].sector = 0;
2073
      LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n",
2074 2075
            eNB->Mod_id,
            eNB->CC_id,
2076 2077
            frame,
            subframe,
2078
	    UE_id,
2079 2080 2081 2082
            preamble_max,
            preamble_energy_max/10,
            preamble_energy_max%10,
            preamble_delay_list[preamble_max]);
2083

2084
      if (eNB->mac_enabled==1) {
2085 2086
        uint8_t update_TA=4;

2087
        switch (fp->N_RB_DL) {
2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
        case 6:
          update_TA = 16;
          break;

        case 25:
          update_TA = 4;
          break;

        case 50:
          update_TA = 2;
          break;

        case 100:
          update_TA = 1;
          break;
        }

2105 2106
      mac_xface->initiate_ra_proc(eNB->Mod_id,
                                  eNB->CC_id,
2107 2108
                                  frame,
                                  preamble_max,
2109
                                  preamble_delay_list[preamble_max]*update_TA,
Raymond Knopp's avatar
 
Raymond Knopp committed
2110
				  0,subframe,0);
2111 2112
      }      

2113
    } else {
2114
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 RA Failed add user, too many");
2115
      LOG_I(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Unable to add user, max user count reached\n",
2116
            eNB->Mod_id,frame, subframe);
2117
    }
2118 2119 2120
  }
}

2121
void ulsch_decoding_procedures(unsigned char subframe, unsigned int i, PHY_VARS_eNB *eNB, unsigned char abstraction_flag)
2122
{
2123 2124
  UNUSED(subframe);
  UNUSED(i);
2125
  UNUSED(eNB);
2126
  UNUSED(abstraction_flag);
2127 2128 2129 2130
  LOG_D(PHY,"ulsch_decoding_procedures not yet implemented. should not be called");
}


2131
void pucch_procedures(const unsigned char sched_subframe,PHY_VARS_eNB *eNB,int UE_id,int harq_pid,const uint8_t abstraction_flag) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2132

2133
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
2134
  uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0};
2135 2136 2137
  int16_t n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3;
  uint8_t do_SR = 0;
  uint8_t pucch_sel = 0;
2138
  int32_t metric0=0,metric1=0,metric0_SR=0;
2139 2140
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
2141

2142 2143
  const int subframe = eNB->proc[sched_subframe].subframe_rx;
  const int frame = eNB->proc[sched_subframe].frame_rx;
Lionel Gauthier's avatar
Lionel Gauthier committed
2144

2145 2146 2147
  if ((eNB->dlsch_eNB[UE_id][0]) &&
      (eNB->dlsch_eNB[UE_id][0]->rnti>0) &&
      (eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag==0)) { 
2148

2149
      // check SR availability
2150
      do_SR = is_SR_subframe(eNB,UE_id,sched_subframe);
2151
      //      do_SR = 0;
2152

2153 2154
      // Now ACK/NAK
      // First check subframe_tx flag for earlier subframes
2155
      get_n1_pucch_eNB(eNB,
2156 2157 2158 2159 2160 2161
                       UE_id,
                       sched_subframe,
                       &n1_pucch0,
                       &n1_pucch1,
                       &n1_pucch2,
                       &n1_pucch3);
2162

2163
      LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d, subframe %d Checking for PUCCH (%d,%d,%d,%d) SR %d\n",
2164
            eNB->Mod_id,eNB->dlsch_eNB[UE_id][0]->rnti,
2165 2166
            frame,subframe,
            n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,do_SR);
2167

2168 2169 2170
      if ((n1_pucch0==-1) && (n1_pucch1==-1) && (do_SR==0)) {  // no TX PDSCH that have to be checked and no SR for this UE_id
      } else {
        // otherwise we have some PUCCH detection to do
2171

2172
	// Null out PUCCH PRBs for noise measurement
2173
	switch(fp->N_RB_UL) {
2174
	case 6:
2175
	  eNB->rb_mask_ul[0] |= (0x1 | (1<<5)); //position 5
2176 2177
	  break;
	case 15:
2178
	  eNB->rb_mask_ul[0] |= (0x1 | (1<<14)); // position 14
2179 2180
	  break;
	case 25:
2181
	  eNB->rb_mask_ul[0] |= (0x1 | (1<<24)); // position 24
2182 2183
	  break;
	case 50:
2184 2185
	  eNB->rb_mask_ul[0] |= 0x1;
	  eNB->rb_mask_ul[1] |= (1<<17); // position 49 (49-32)
2186 2187
	  break;
	case 75:
2188 2189
	  eNB->rb_mask_ul[0] |= 0x1;
	  eNB->rb_mask_ul[2] |= (1<<10); // position 74 (74-64)
2190 2191
	  break;
	case 100:
2192 2193
	  eNB->rb_mask_ul[0] |= 0x1;
	  eNB->rb_mask_ul[3] |= (1<<3); // position 99 (99-96)
2194 2195
	  break;
	default:
2196
	  LOG_E(PHY,"Unknown number for N_RB_UL %d\n",fp->N_RB_UL);
2197 2198
	  break;
	}
2199

2200
        if (do_SR == 1) {
2201
          eNB->eNB_UE_stats[UE_id].sr_total++;
2202

2203
          if (abstraction_flag == 0)
2204
            metric0_SR = rx_pucch(eNB,
2205 2206
				  pucch_format1,
				  UE_id,
2207
				  eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,
2208 2209 2210 2211 2212
				  0, // n2_pucch
				  0, // shortened format, should be use_srs flag, later
				  &SR_payload,
				  subframe,
				  PUCCH1_THRES);
2213

2214 2215
#ifdef PHY_ABSTRACTION
          else {
2216
            metric0_SR = rx_pucch_emul(eNB,
2217 2218 2219 2220 2221
				       UE_id,
				       pucch_format1,
				       0,
				       &SR_payload,
				       sched_subframe);
2222 2223
            LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR (UE SR %d/%d)\n",eNB->Mod_id,
                  eNB->ulsch_eNB[UE_id]->rnti,frame,subframe,SR_payload,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex);
2224
          }
2225

2226
#endif
2227

2228
          if (SR_payload == 1) {
2229 2230 2231
            LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id,
                  eNB->ulsch_eNB[UE_id]->rnti,frame,subframe);
            eNB->eNB_UE_stats[UE_id].sr_received++;
2232

2233
            if (eNB->first_sr[UE_id] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
2234
              /* is this test necessary? */
2235 2236 2237 2238 2239
              if (eNB->dlsch_eNB[UE_id][0]->harq_processes[0]->status != SCH_IDLE)
                put_harq_pid_in_freelist(eNB->dlsch_eNB[UE_id][0], 0);
              eNB->first_sr[UE_id] = 0;
              eNB->dlsch_eNB[UE_id][0]->harq_processes[0]->round=0;
              eNB->dlsch_eNB[UE_id][0]->harq_processes[0]->status=SCH_IDLE;
2240
              LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
2241 2242
                    eNB->Mod_id,
                    eNB->ulsch_eNB[UE_id]->rnti,frame,subframe);
2243
            }
2244

2245 2246 2247
	    if (eNB->mac_enabled==1) {
	      mac_xface->SR_indication(eNB->Mod_id,
				       eNB->CC_id,
2248
				       frame,
2249
				       eNB->dlsch_eNB[UE_id][0]->rnti,subframe);
2250 2251 2252
	    }
          }
        }// do_SR==1
2253

2254
        if ((n1_pucch0==-1) && (n1_pucch1==-1)) { // just check for SR
2255
        } else if (fp->frame_type==FDD) { // FDD
2256
          // if SR was detected, use the n1_pucch from SR, else use n1_pucch0
2257
	  //          n1_pucch0 = (SR_payload==1) ? eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex:n1_pucch0;
2258

2259
	  LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload);
Raymond Knopp's avatar
 
Raymond Knopp committed
2260

2261
          if (abstraction_flag == 0) {
2262

2263

2264

2265
            metric0 = rx_pucch(eNB,
2266 2267 2268 2269 2270 2271 2272 2273
                               pucch_format1a,
                               UE_id,
                               (uint16_t)n1_pucch0,
                               0, //n2_pucch
                               0, // shortened format
                               pucch_payload0,
                               subframe,
                               PUCCH1a_THRES);
2274

2275
            if (metric0 < metric0_SR)
2276
	      metric0=rx_pucch(eNB,
2277 2278
			       pucch_format1a,
			       UE_id,
2279
			       eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,
2280 2281 2282 2283 2284 2285 2286 2287
			       0, //n2_pucch
			       0, // shortened format
			       pucch_payload0,
			       subframe,
			       PUCCH1a_THRES);
	  }
          else {
#ifdef PHY_ABSTRACTION
2288
            metric0 = rx_pucch_emul(eNB,UE_id,
2289 2290 2291 2292 2293 2294
                                    pucch_format1a,
                                    0,
                                    pucch_payload0,
                                    subframe);
#endif
          }
2295

2296 2297
#ifdef DEBUG_PHY_PROC
          LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
2298 2299
                eNB->Mod_id,
                eNB->dlsch_eNB[UE_id][0]->rnti,
2300 2301
                frame,subframe,
                pucch_payload0[0],metric0);
2302 2303
#endif

2304
          process_HARQ_feedback(UE_id,sched_subframe,eNB,
2305 2306 2307 2308
                                0,// pusch_flag
                                pucch_payload0,
                                2,
                                SR_payload);
2309

2310 2311
        } // FDD
        else {  //TDD
2312

2313
          bundling_flag = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode;
2314

2315
          // fix later for 2 TB case and format1b
Raymond Knopp's avatar
Raymond Knopp committed
2316

2317
          if ((fp->frame_type==FDD) ||
2318
              (bundling_flag==bundling)    ||
2319
              ((fp->frame_type==TDD)&&(fp->tdd_config==1)&&((subframe!=2)||(subframe!=7)))) {
2320
            format = pucch_format1a;
2321
	  } else {
2322
            format = pucch_format1b;
2323
	  }
2324

2325 2326 2327
          // if SR was detected, use the n1_pucch from SR
          if (SR_payload==1) {
#ifdef DEBUG_PHY_PROC
2328 2329
            LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id,
                  eNB->dlsch_eNB[UE_id][0]->rnti,
2330 2331 2332
                  frame,subframe,
                  n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
#endif
2333

2334
            if (abstraction_flag == 0)
2335
              metric0_SR = rx_pucch(eNB,
2336 2337
				    format,
				    UE_id,
2338
				    eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,
2339 2340 2341 2342 2343 2344
				    0, //n2_pucch
				    0, // shortened format
				    pucch_payload0,
				    subframe,
				    PUCCH1a_THRES);
            else {
2345
#ifdef PHY_ABSTRACTION
2346
              metric0 = rx_pucch_emul(eNB,UE_id,
2347 2348 2349 2350
                                      format,
                                      0,
                                      pucch_payload0,
                                      subframe);
2351
#endif
2352 2353 2354
            }
          } else { //using n1_pucch0/n1_pucch1 resources
#ifdef DEBUG_PHY_PROC
2355 2356
            LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",eNB->Mod_id,
                  eNB->dlsch_eNB[UE_id][0]->rnti,
2357 2358 2359 2360 2361
                  frame,subframe,
                  n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
#endif
            metric0=0;
            metric1=0;
2362

2363 2364 2365
            // Check n1_pucch0 metric
            if (n1_pucch0 != -1) {
              if (abstraction_flag == 0)
2366
                metric0 = rx_pucch(eNB,
2367 2368 2369 2370 2371 2372 2373 2374 2375
                                   format,
                                   UE_id,
                                   (uint16_t)n1_pucch0,
                                   0, // n2_pucch
                                   0, // shortened format
                                   pucch_payload0,
                                   subframe,
                                   PUCCH1a_THRES);
              else {
2376
#ifdef PHY_ABSTRACTION
2377
                metric0 = rx_pucch_emul(eNB,UE_id,
2378 2379 2380 2381
                                        format,
                                        0,
                                        pucch_payload0,
                                        subframe);
2382
#endif
2383 2384
              }
            }
2385

2386 2387 2388
            // Check n1_pucch1 metric
            if (n1_pucch1 != -1) {
              if (abstraction_flag == 0)
2389
                metric1 = rx_pucch(eNB,
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399
                                   format,
                                   UE_id,
                                   (uint16_t)n1_pucch1,
                                   0, //n2_pucch
                                   0, // shortened format
                                   pucch_payload1,
                                   subframe,
                                   PUCCH1a_THRES);
              else {
#ifdef PHY_ABSTRACTION
2400
                metric1 = rx_pucch_emul(eNB,UE_id,
2401 2402 2403 2404
                                        format,
                                        1,
                                        pucch_payload1,
                                        subframe);
2405

2406

2407 2408 2409 2410
#endif
              }
            }
          }
2411

2412 2413
          if (SR_payload == 1) {
            pucch_payload = pucch_payload0;
2414

2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427
            if (bundling_flag == bundling)
              pucch_sel = 2;
          } else if (bundling_flag == multiplexing) { // multiplexing + no SR
            pucch_payload = (metric1>metric0) ? pucch_payload1 : pucch_payload0;
            pucch_sel     = (metric1>metric0) ? 1 : 0;
          } else { // bundling + no SR
            if (n1_pucch1 != -1)
              pucch_payload = pucch_payload1;
            else if (n1_pucch0 != -1)
              pucch_payload = pucch_payload0;

            pucch_sel = 2;  // indicate that this is a bundled ACK/NAK
          }
2428 2429

#ifdef DEBUG_PHY_PROC
2430 2431
          LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id,
                eNB->dlsch_eNB[UE_id][0]->rnti,
2432 2433
                frame,subframe,
                metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]);
2434
#endif
2435
          process_HARQ_feedback(UE_id,sched_subframe,eNB,
2436 2437 2438 2439 2440
                                0,// pusch_flag
                                pucch_payload,
                                pucch_sel,
                                SR_payload);
        }
2441
      }
2442

2443 2444
    }
}
2445

2446
void cba_procedures(const unsigned char sched_subframe,PHY_VARS_eNB *eNB,int UE_id,int harq_pid,const uint8_t abstraction_flag) {
2447

2448 2449
  uint8_t access_mode;
  int num_active_cba_groups;
2450 2451
  const int subframe = eNB->proc[sched_subframe].subframe_rx;
  const int frame = eNB->proc[sched_subframe].frame_rx;
2452 2453
  uint16_t rnti=0;
  int ret=0;
2454
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
2455

2456
  num_active_cba_groups = eNB->ulsch_eNB[UE_id]->num_active_cba_groups;
2457
  
2458
  if ((eNB->ulsch_eNB[UE_id]) &&
2459
      (num_active_cba_groups > 0) &&
2460 2461
      (eNB->ulsch_eNB[UE_id]->cba_rnti[UE_id%num_active_cba_groups]>0) &&
      (eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag==1)) {
2462 2463 2464 2465
    rnti=0;
    
#ifdef DEBUG_PHY_PROC
    LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Checking PUSCH/ULSCH CBA Reception for UE %d with cba rnti %x mode %s\n",
2466
	  eNB->Mod_id,harq_pid,
2467
	  frame,subframe,
2468
	  UE_id, (uint16_t)eNB->ulsch_eNB[UE_id]->cba_rnti[UE_id%num_active_cba_groups],mode_string[eNB->eNB_UE_stats[UE_id].mode]);
2469 2470 2471
#endif
    
    if (abstraction_flag==0) {
2472
      rx_ulsch(eNB,
2473
	       sched_subframe,
2474
	       eNB->eNB_UE_stats[UE_id].sector,  // this is the effective sector id
2475
	       UE_id,
2476
	       eNB->ulsch_eNB,
2477 2478 2479 2480 2481
	       0);
    }
    
#ifdef PHY_ABSTRACTION
    else {
2482
      rx_ulsch_emul(eNB,
2483
		    subframe,
2484
		    eNB->eNB_UE_stats[UE_id].sector,  // this is the effective sector id
2485
		    UE_id);
2486 2487 2488 2489 2490
    }
    
#endif
    
    if (abstraction_flag == 0) {
2491
      ret = ulsch_decoding(eNB,
2492 2493 2494
			   UE_id,
			   sched_subframe,
			   0, // control_only_flag
2495 2496
			   eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->V_UL_DAI,
			   eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb>20 ? 1 : 0);
2497 2498 2499 2500
    }
    
#ifdef PHY_ABSTRACTION
    else {
2501
      ret = ulsch_decoding_emul(eNB,
2502 2503 2504 2505 2506 2507 2508
				sched_subframe,
				UE_id,
				&rnti);
    }
    
#endif
    
2509
    if (eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->cqi_crc_status == 1) {
2510 2511
#ifdef DEBUG_PHY_PROC
      
2512
      print_CQI(eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->o,eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->uci_format,0,fp->N_RB_DL);
2513 2514
#endif
      access_mode = UNKNOWN_ACCESS;
2515 2516 2517 2518
      extract_CQI(eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->o,
		  eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->uci_format,
		  &eNB->eNB_UE_stats[UE_id],
		  fp->N_RB_DL,
2519
		  &rnti, &access_mode);
2520
      eNB->eNB_UE_stats[UE_id].rank = eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->o_RI[0];
2521 2522
    }
    
2523 2524
      eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=0;
      eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->status= SCH_IDLE;
2525 2526 2527
      
      if ((num_active_cba_groups > 0) &&
          (UE_id + num_active_cba_groups < NUMBER_OF_UE_MAX) &&
2528 2529
          (eNB->ulsch_eNB[UE_id+num_active_cba_groups]->cba_rnti[UE_id%num_active_cba_groups] > 0 ) &&
          (eNB->ulsch_eNB[UE_id+num_active_cba_groups]->num_active_cba_groups> 0)) {
2530 2531
#ifdef DEBUG_PHY_PROC
        LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d resetting the subframe_scheduling_flag for Ue %d cba groups %d members\n",
2532 2533
              eNB->Mod_id,harq_pid,frame,subframe,UE_id,harq_pid,
              UE_id+num_active_cba_groups, UE_id%eNB->ulsch_eNB[UE_id]->num_active_cba_groups);
2534
#endif
2535 2536 2537
        eNB->ulsch_eNB[UE_id+num_active_cba_groups]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=1;
        eNB->ulsch_eNB[UE_id+num_active_cba_groups]->harq_processes[harq_pid]->status= CBA_ACTIVE;
        eNB->ulsch_eNB[UE_id+num_active_cba_groups]->harq_processes[harq_pid]->TBS=eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->TBS;
2538
      }
2539

2540
      if (ret == (1+MAX_TURBO_ITERATIONS)) {
2541 2542 2543 2544
        eNB->eNB_UE_stats[UE_id].ulsch_round_errors[harq_pid][eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->round]++;
        eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->phich_active = 1;
        eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->phich_ACK = 0;
        eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->round++;
2545 2546 2547
      } // ulsch in error
      else {
        LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
2548
              eNB->Mod_id,harq_pid,
2549
              frame,subframe);
2550

2551 2552 2553 2554
        eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->phich_active = 1;
        eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->phich_ACK = 1;
        eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->round = 0;
        eNB->eNB_UE_stats[UE_id].ulsch_consecutive_errors = 0;
2555 2556 2557 2558
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
        LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",
              frame,subframe,
2559
              harq_pid,eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->TBS>>3);
2560

2561 2562
        for (j=0; j<eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->TBS>>3; j++)
          LOG_T(PHY,"%x.",eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->b[j]);
2563 2564 2565 2566 2567 2568 2569

        LOG_T(PHY,"\n");
#endif
#endif

        if (access_mode > UNKNOWN_ACCESS) {
          LOG_D(PHY,"[eNB %d] Frame %d, Subframe %d : received ULSCH SDU from CBA transmission, UE (%d,%x), CBA (group %d, rnti %x)\n",
2570 2571 2572
                eNB->Mod_id, frame,subframe,
                UE_id, eNB->ulsch_eNB[UE_id]->rnti,
                UE_id % eNB->ulsch_eNB[UE_id]->num_active_cba_groups, eNB->ulsch_eNB[UE_id]->cba_rnti[UE_id%num_active_cba_groups]);
2573

2574
          // detect if there is a CBA collision
2575 2576 2577
          if (eNB->cba_last_reception[UE_id%num_active_cba_groups] == 0 ) {
            mac_xface->rx_sdu(eNB->Mod_id,
                              eNB->CC_id,
2578
                              frame,subframe,
2579 2580 2581
                              eNB->ulsch_eNB[UE_id]->rnti,
                              eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->b,
                              eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->TBS>>3,
2582 2583 2584
                              harq_pid,
                              NULL);

2585
            eNB->cba_last_reception[UE_id%num_active_cba_groups]+=1;//(subframe);
2586
          } else {
2587
            if (eNB->cba_last_reception[UE_id%num_active_cba_groups] == 1 )
2588
              LOG_N(PHY,"[eNB%d] Frame %d subframe %d : first CBA collision detected \n ",
2589
                    eNB->Mod_id,frame,subframe);
2590

2591
            LOG_N(PHY,"[eNB%d] Frame %d subframe %d : CBA collision set SR for UE %d in group %d \n ",
2592 2593
                  eNB->Mod_id,frame,subframe,
                  eNB->cba_last_reception[UE_id%num_active_cba_groups],UE_id%num_active_cba_groups );
2594

2595
            eNB->cba_last_reception[UE_id%num_active_cba_groups]+=1;
2596

2597 2598
            mac_xface->SR_indication(eNB->Mod_id,
                                     eNB->CC_id,
2599
                                     frame,
2600
                                     eNB->dlsch_eNB[UE_id][0]->rnti,subframe);
2601
          }
2602 2603 2604
        } // UNKNOWN_ACCESS
      } // ULSCH CBA not in error
  }
2605

2606
}
2607

2608
void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *eNB,const uint8_t abstraction_flag,const relaying_type_t r_type)
2609 2610 2611 2612 2613 2614 2615 2616 2617
{
  //RX processing
  UNUSED(r_type);
  uint32_t l, ret=0,i,j,k;
  uint32_t harq_pid, harq_idx, round;
  uint8_t nPRS;
  int sync_pos;
  uint16_t rnti=0;
  uint8_t access_mode;
2618
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
2619

2620 2621
  const int subframe = eNB->proc[sched_subframe].subframe_rx;
  const int frame = eNB->proc[sched_subframe].frame_rx;
2622

2623 2624 2625
  AssertFatal(sched_subframe < NUM_ENB_THREADS, "Bad sched_subframe %d", sched_subframe);

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1);
2626
  start_meas(&eNB->phy_proc_rx);
2627
#ifdef DEBUG_PHY_PROC
2628
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe);
Lionel Gauthier's avatar
Lionel Gauthier committed
2629
#endif
2630 2631


2632 2633 2634 2635
  eNB->rb_mask_ul[0]=0;
  eNB->rb_mask_ul[1]=0;
  eNB->rb_mask_ul[2]=0;
  eNB->rb_mask_ul[3]=0;
2636

2637
  if (abstraction_flag == 0) {
2638 2639
    remove_7_5_kHz(eNB,subframe<<1);
    remove_7_5_kHz(eNB,(subframe<<1)+1);
2640
  }
2641

2642
  // check if we have to detect PRACH first
2643
  if (is_prach_subframe(fp,frame,subframe)>0) {
2644
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
2645
    prach_procedures(eNB,sched_subframe,abstraction_flag);
2646 2647
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
  }
2648

2649
  if (abstraction_flag == 0) {
2650
    start_meas(&eNB->ofdm_demod_stats);
2651

2652
    for (l=0; l<fp->symbols_per_tti/2; l++) {
2653

2654 2655
      slot_fep_ul(fp,
                  &eNB->lte_eNB_common_vars,
2656 2657 2658 2659 2660
                  l,
                  subframe<<1,
                  0,
                  0
                 );
2661 2662
      slot_fep_ul(fp,
                  &eNB->lte_eNB_common_vars,
2663 2664 2665 2666 2667 2668 2669
                  l,
                  (subframe<<1)+1,
                  0,
                  0
                 );
    }

2670
    stop_meas(&eNB->ofdm_demod_stats);
2671 2672 2673
  }

  // Check for active processes in current subframe
2674
  harq_pid = subframe2harq_pid(fp,
2675 2676 2677 2678
                               frame,subframe);

  // reset the cba flag used for collision detection
  for (i=0; i < NUM_MAX_CBA_GROUP; i++) {
2679
    eNB->cba_last_reception[i]=0;
2680 2681 2682 2683 2684
  }

  // Do PUCCH processing first

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
2685
    pucch_procedures(sched_subframe,eNB,i,harq_pid,abstraction_flag);
2686
  }
2687

2688
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
2689

2690
    // check for Msg3
2691 2692 2693
    if (eNB->mac_enabled==1) {
      if (eNB->eNB_UE_stats[i].mode == RA_RESPONSE) {
	process_Msg3(eNB,sched_subframe,i,harq_pid);
2694 2695
      }
    }
2696 2697


2698 2699 2700
    eNB->pusch_stats_rb[i][(frame*10)+subframe] = -63;
    eNB->pusch_stats_round[i][(frame*10)+subframe] = 0;
    eNB->pusch_stats_mcs[i][(frame*10)+subframe] = -63;
2701

2702 2703 2704
    if ((eNB->ulsch_eNB[i]) &&
        (eNB->ulsch_eNB[i]->rnti>0) &&
        (eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag==1)) {
2705
      // UE is has ULSCH scheduling
2706
      round = eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round;
2707 2708

      for (int rb=0;
2709
           rb<=eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb;
2710
	   rb++) {
2711 2712
	int rb2 = rb+eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb;
	eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
2713
      }
2714
#ifdef DEBUG_PHY_PROC
2715
      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Scheduling PUSCH/ULSCH Reception for rnti %x (UE_id %d)\n",
2716 2717
            eNB->Mod_id,harq_pid,
            frame,subframe,eNB->ulsch_eNB[i]->rnti,i);
2718
#endif
2719

2720
      if (eNB->ulsch_eNB[i]->Msg3_flag == 1) {
2721
        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for Msg3 in Sector %d\n",
2722
              eNB->Mod_id,
2723 2724
              frame,
              subframe,
2725
              eNB->eNB_UE_stats[i].sector);
2726 2727 2728
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_MSG3,1);
      } else {
        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d Mode %s\n",
2729
              eNB->Mod_id,
2730 2731 2732
              frame,
              subframe,
              i,
2733
              mode_string[eNB->eNB_UE_stats[i].mode]);
2734
      }
2735 2736


2737
      nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
2738

2739
      eNB->ulsch_eNB[i]->cyclicShift = (eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2 + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
2740
          nPRS)%12;
2741

2742
      if (fp->frame_type == FDD ) {
2743
        int sf = (subframe<4) ? (subframe+6) : (subframe-4);
2744

2745 2746
        if (eNB->dlsch_eNB[i][0]->subframe_tx[sf]>0) { // we have downlink transmission
          eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 1;
2747
        } else {
2748
          eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 0;
2749
        }
2750
      }
2751

2752 2753
      LOG_D(PHY,
            "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, mcs %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n",
2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765
            eNB->Mod_id,harq_pid,frame,subframe,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->mcs,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rvidx,
            eNB->ulsch_eNB[i]->cyclicShift,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2,
            fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
2766
            nPRS,
2767 2768 2769 2770 2771
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK);
      eNB->pusch_stats_rb[i][(frame*10)+subframe] = eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb;
      eNB->pusch_stats_round[i][(frame*10)+subframe] = eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round;
      eNB->pusch_stats_mcs[i][(frame*10)+subframe] = eNB->ulsch_eNB[i]->harq_processes[harq_pid]->mcs;
      start_meas(&eNB->ulsch_demodulation_stats);
2772

2773
      if (abstraction_flag==0) {
2774
        rx_ulsch(eNB,
2775
                 sched_subframe,
2776
                 eNB->eNB_UE_stats[i].sector,  // this is the effective sector id
2777
                 i,
2778
                 eNB->ulsch_eNB,
2779 2780
                 0);
      }
2781

2782 2783
#ifdef PHY_ABSTRACTION
      else {
2784
        rx_ulsch_emul(eNB,
2785
                      subframe,
2786
                      eNB->eNB_UE_stats[i].sector,  // this is the effective sector id
2787 2788
                      i);
      }
2789

2790
#endif
2791
      stop_meas(&eNB->ulsch_demodulation_stats);
2792

2793

2794
      start_meas(&eNB->ulsch_decoding_stats);
2795

2796
      if (abstraction_flag == 0) {
2797
        ret = ulsch_decoding(eNB,
2798 2799 2800
                             i,
                             sched_subframe,
                             0, // control_only_flag
2801 2802
                             eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI,
			     eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb>20 ? 1 : 0);
2803
      }
2804

2805 2806
#ifdef PHY_ABSTRACTION
      else {
2807
        ret = ulsch_decoding_emul(eNB,
2808 2809 2810 2811
                                  sched_subframe,
                                  i,
                                  &rnti);
      }
2812

2813
#endif
2814
      stop_meas(&eNB->ulsch_decoding_stats);
2815

2816
      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
2817
            eNB->Mod_id,harq_pid,
2818
            frame,subframe,
2819 2820 2821 2822 2823 2824 2825 2826 2827
            eNB->ulsch_eNB[i]->rnti,
            dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
            dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
            eNB->eNB_UE_stats[i].UL_rssi[0],
            eNB->eNB_UE_stats[i].UL_rssi[1],
            eNB->PHY_measurements_eNB->n0_power_dB[0],
            eNB->PHY_measurements_eNB->n0_power_dB[1],
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
2828
            ret);
2829

2830

2831
      //compute the expected ULSCH RX power (for the stats)
2832 2833
      eNB->ulsch_eNB[(uint32_t)i]->harq_processes[harq_pid]->delta_TF =
        get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
2834

2835
      //dump_ulsch(eNB, sched_subframe, i);
2836

2837
      eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
2838 2839
#ifdef DEBUG_PHY_PROC
      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d Clearing subframe_scheduling_flag\n",
2840
            eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid);
2841
#endif
2842
      eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag=0;
2843

2844
      if (eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) {
2845
#ifdef DEBUG_PHY_PROC
2846 2847
        //if (((eNB->proc[sched_subframe].frame_tx%10) == 0) || (eNB->proc[sched_subframe].frame_tx < 50))
        print_CQI(eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,fp->N_RB_DL);
2848
#endif
2849 2850 2851 2852
        extract_CQI(eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,
                    eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,
                    &eNB->eNB_UE_stats[i],
                    fp->N_RB_DL,
2853
                    &rnti, &access_mode);
2854
        eNB->eNB_UE_stats[i].rank = eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0];
2855

2856
      }
2857

2858
      if (eNB->ulsch_eNB[i]->Msg3_flag == 1)
2859
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_MSG3,0);
2860

2861
      if (ret == (1+MAX_TURBO_ITERATIONS)) {
2862

2863 2864 2865 2866
        eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0;
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++;
2867

2868
        LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round);
2869

2870
        if (eNB->ulsch_eNB[i]->Msg3_flag == 1) {
2871
          LOG_D(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d/%d\n",
2872 2873
                eNB->Mod_id,
                eNB->CC_id,
2874
                frame,subframe, i,
2875 2876
                eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
                fp->maxHARQ_Msg3Tx-1);
2877 2878

	  LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
2879
		eNB->Mod_id,harq_pid,
2880
		frame,subframe,
2881 2882 2883 2884 2885 2886 2887 2888 2889
		eNB->ulsch_eNB[i]->rnti,
		dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
		dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
		eNB->eNB_UE_stats[i].UL_rssi[0],
		eNB->eNB_UE_stats[i].UL_rssi[1],
		eNB->PHY_measurements_eNB->n0_power_dB[0],
		eNB->PHY_measurements_eNB->n0_power_dB[1],
		eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
		eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
2890 2891
		ret);

2892 2893
          if (eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round ==
              fp->maxHARQ_Msg3Tx) {
2894
            LOG_D(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n",
2895 2896 2897 2898 2899
                  eNB->Mod_id, i);
            eNB->eNB_UE_stats[i].mode = PRACH;
	    if (eNB->mac_enabled==1) {
	      mac_xface->cancel_ra_proc(eNB->Mod_id,
					eNB->CC_id,
2900
					frame,
2901
					eNB->eNB_UE_stats[i].crnti);
2902
	    }
2903
            mac_phy_remove_ue(eNB->Mod_id,eNB->eNB_UE_stats[i].crnti);
2904

2905 2906
            eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
            //eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 0;
2907

2908 2909
          } else {
            // activate retransmission for Msg3 (signalled to UE PHY by PHICH (not MAC/DCI)
2910
            eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 1;
2911

2912
            get_Msg3_alloc_ret(fp,
2913
                               subframe,
2914
                               frame,
2915 2916
                               &eNB->ulsch_eNB[i]->Msg3_frame,
                               &eNB->ulsch_eNB[i]->Msg3_subframe);
2917 2918 2919
          }
          LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i);
        } // This is Msg3 error
2920

2921 2922
        else { //normal ULSCH
          LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
2923
                eNB->Mod_id,harq_pid,
2924
                frame,subframe, i,
2925 2926 2927 2928
                eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
                eNB->ulsch_eNB[i]->Mlimit,
                eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
                eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1]);
2929 2930 2931 2932 2933 2934 2935

#if defined(MESSAGE_CHART_GENERATOR_PHY)
          MSC_LOG_RX_DISCARDED_MESSAGE(
            MSC_PHY_ENB,MSC_PHY_UE,
            NULL,0,
            "%05u:%02u ULSCH received rnti %x harq id %u round %d",
            frame,subframe,
2936 2937
            eNB->ulsch_eNB[i]->rnti,harq_pid,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1
2938
            );
2939
#endif
2940

2941
          if (eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round== eNB->ulsch_eNB[i]->Mlimit) {
2942
            LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d ULSCH Mlimit %d reached\n",
2943
                  eNB->Mod_id,harq_pid,
2944
                  frame,subframe, i,
2945
                  eNB->ulsch_eNB[i]->Mlimit);
2946

2947 2948 2949 2950
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round=0;
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active=0;
            eNB->eNB_UE_stats[i].ulsch_errors[harq_pid]++;
            eNB->eNB_UE_stats[i].ulsch_consecutive_errors++;
2951 2952

	    // indicate error to MAC
2953 2954
	    mac_xface->rx_sdu(eNB->Mod_id,
			      eNB->CC_id,
2955
			      frame,subframe,
2956
			      eNB->ulsch_eNB[i]->rnti,
2957 2958 2959
			      NULL,
			      0,
			      harq_pid,
2960
			      &eNB->ulsch_eNB[i]->Msg3_flag);
2961 2962 2963 2964
          }
        }
      }  // ulsch in error
      else {
2965
        if (eNB->ulsch_eNB[i]->Msg3_flag == 1) {
2966
	  LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
2967
		eNB->Mod_id,harq_pid,
2968 2969
		frame,subframe);
	  LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
2970
		eNB->Mod_id,harq_pid,
2971
		frame,subframe,
2972 2973 2974 2975 2976 2977 2978 2979 2980
		eNB->ulsch_eNB[i]->rnti,
		dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
		dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
		eNB->eNB_UE_stats[i].UL_rssi[0],
		eNB->eNB_UE_stats[i].UL_rssi[1],
		eNB->PHY_measurements_eNB->n0_power_dB[0],
		eNB->PHY_measurements_eNB->n0_power_dB[1],
		eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
		eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
2981 2982 2983 2984 2985 2986 2987 2988
		ret);
	}
#if defined(MESSAGE_CHART_GENERATOR_PHY)
        MSC_LOG_RX_MESSAGE(
          MSC_PHY_ENB,MSC_PHY_UE,
          NULL,0,
          "%05u:%02u ULSCH received rnti %x harq id %u",
          frame,subframe,
2989
          eNB->ulsch_eNB[i]->rnti,harq_pid
2990
          );
2991
#endif
2992
        for (j=0; j<fp->nb_antennas_rx; j++)
2993
          //this is the RSSI per RB
2994
          eNB->eNB_UE_stats[i].UL_rssi[j] =
2995
	    
2996 2997 2998 2999 3000 3001
            dB_fixed(eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]*
                     (eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb*12)/
                     fp->ofdm_symbol_size) -
            eNB->rx_total_gain_eNB_dB -
            hundred_times_log10_NPRB[eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
            get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0)/100;
3002
	    
3003 3004 3005 3006
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1;
        eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0;
        eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0;
3007

3008 3009
        if (eNB->ulsch_eNB[i]->Msg3_flag == 1) {
	  if (eNB->mac_enabled==1) {
3010

3011
	    LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n",
3012
		  eNB->Mod_id,
3013 3014
		  frame,harq_pid,i);
	    
3015 3016
	    mac_xface->rx_sdu(eNB->Mod_id,
			      eNB->CC_id,
3017
			      frame,subframe,
3018 3019 3020
			      eNB->ulsch_eNB[i]->rnti,
			      eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
			      eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
3021
			      harq_pid,
3022
			      &eNB->ulsch_eNB[i]->Msg3_flag);
3023 3024
	    
	    // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
3025 3026 3027 3028
	    if (eNB->ulsch_eNB[i]->Msg3_flag == 0 ) {
	      eNB->eNB_UE_stats[i].mode = PRACH;
	      mac_xface->cancel_ra_proc(eNB->Mod_id,
					eNB->CC_id,
3029
					frame,
3030 3031 3032
					eNB->eNB_UE_stats[i].crnti);
	      mac_phy_remove_ue(eNB->Mod_id,eNB->eNB_UE_stats[i].crnti);
	      eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
3033 3034 3035
	    } // Msg3_flag == 0
	    
	  } // mac_enabled==1
3036

3037 3038
          eNB->eNB_UE_stats[i].mode = PUSCH;
          eNB->ulsch_eNB[i]->Msg3_flag = 0;
3039

3040
	  LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",eNB->Mod_id,frame,subframe,i);
3041

3042
          for (k=0; k<8; k++) { //harq_processes
3043 3044 3045 3046
            for (j=0; j<eNB->dlsch_eNB[i][0]->Mlimit; j++) {
              eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0;
              eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0;
              eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0;
3047
            }
3048

3049 3050 3051
            eNB->eNB_UE_stats[i].dlsch_l2_errors[k]=0;
            eNB->eNB_UE_stats[i].ulsch_errors[k]=0;
            eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
3052

3053 3054 3055 3056 3057
            for (j=0; j<eNB->ulsch_eNB[i]->Mlimit; j++) {
              eNB->eNB_UE_stats[i].ulsch_decoding_attempts[k][j]=0;
              eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
              eNB->eNB_UE_stats[i].ulsch_round_errors[k][j]=0;
              eNB->eNB_UE_stats[i].ulsch_round_fer[k][j]=0;
3058
            }
3059 3060
          }

3061 3062 3063
          eNB->eNB_UE_stats[i].dlsch_sliding_cnt=0;
          eNB->eNB_UE_stats[i].dlsch_NAK_round0=0;
          eNB->eNB_UE_stats[i].dlsch_mcs_offset=0;
3064 3065 3066
        } // Msg3_flag==1
	else {  // Msg3_flag == 0

3067
#ifdef DEBUG_PHY_PROC
3068 3069
#ifdef DEBUG_ULSCH
          LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
3070
                harq_pid,eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
3071

3072 3073
          for (j=0; j<eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++)
            LOG_T(PHY,"%x.",eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]);
3074 3075 3076

          LOG_T(PHY,"\n");
#endif
3077
#endif
3078

3079
	  if (eNB->mac_enabled==1) {
3080

3081 3082
	    mac_xface->rx_sdu(eNB->Mod_id,
			      eNB->CC_id,
3083
			      frame,subframe,
3084 3085 3086
			      eNB->ulsch_eNB[i]->rnti,
			      eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
			      eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
3087 3088
			      harq_pid,
			      NULL);
3089

3090
#ifdef LOCALIZATION
3091 3092
	    start_meas(&eNB->localization_stats);
	    aggregate_eNB_UE_localization_stats(eNB,
3093 3094 3095
						i,
						frame,
						subframe,
3096 3097
						get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 1)/100);
	    stop_meas(&eNB->localization_stats);
3098
#endif
3099 3100 3101
	    
	  } // mac_enabled==1
        } // Msg3_flag == 0
3102

3103 3104
        // estimate timing advance for MAC
        if (abstraction_flag == 0) {
3105 3106
          sync_pos = lte_est_timing_advance_pusch(eNB,i,sched_subframe);
          eNB->eNB_UE_stats[i].timing_advance_update = sync_pos - fp->nb_prefix_samples/4; //to check
3107
        }
3108

3109 3110
#ifdef DEBUG_PHY_PROC
        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: user %d: timing advance = %d\n",
3111
              eNB->Mod_id,
3112 3113
              frame, subframe,
              i,
3114
              eNB->eNB_UE_stats[i].timing_advance_update);
3115
#endif
3116 3117


3118 3119 3120
      }  // ulsch not in error

      // process HARQ feedback
3121
#ifdef DEBUG_PHY_PROC
3122 3123
      LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d, Processing HARQ feedback for UE %d (after PUSCH)\n",eNB->Mod_id,
            eNB->dlsch_eNB[i][0]->rnti,
3124 3125
            frame,subframe,
            i);
3126
#endif
3127 3128
      process_HARQ_feedback(i,
                            sched_subframe,
3129
                            eNB,
3130 3131 3132 3133 3134 3135 3136
                            1, // pusch_flag
                            0,
                            0,
                            0);

#ifdef DEBUG_PHY_PROC
      LOG_D(PHY,"[eNB %d] Frame %d subframe %d, sect %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n",
3137 3138
            eNB->Mod_id,frame,subframe,
            eNB->eNB_UE_stats[i].sector,
3139 3140 3141
            harq_pid,
            i,
            ret,
3142 3143 3144 3145 3146
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status,
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
            eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
            eNB->eNB_UE_stats[i].ulsch_errors[harq_pid],
            eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
3147 3148 3149 3150
#endif
      
      // dump stats to VCD
      if (i==0) {
3151 3152 3153 3154
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_MCS0+harq_pid,eNB->pusch_stats_mcs[0][(frame*10)+subframe]);
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RB0+harq_pid,eNB->pusch_stats_rb[0][(frame*10)+subframe]);
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_ROUND0+harq_pid,eNB->pusch_stats_round[0][(frame*10)+subframe]);
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RSSI0+harq_pid,dB_fixed(eNB->lte_eNB_pusch_vars[0]->ulsch_power[0]));
3155 3156
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RES0+harq_pid,ret);
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN0+harq_pid,(frame*10)+subframe);
Lionel Gauthier's avatar
Lionel Gauthier committed
3157
      }
3158
    } // ulsch_eNB[0] && ulsch_eNB[0]->rnti>0 && ulsch_eNB[0]->subframe_scheduling_flag == 1
3159

3160

3161
    // update ULSCH statistics for tracing
3162
    if ((frame % 100 == 0) && (subframe == 4)) {
3163
      for (harq_idx=0; harq_idx<8; harq_idx++) {
3164 3165 3166 3167 3168 3169 3170 3171
        for (round=0; round<eNB->ulsch_eNB[i]->Mlimit; round++) {
          if ((eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
               eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]) != 0) {
            eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] =
              (100*(eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round] -
                    eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round]))/
              (eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
               eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]);
3172
          } else {
3173
            eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] = 0;
3174 3175
          }

3176 3177 3178 3179
          eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round] =
            eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round];
          eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round] =
            eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round];
3180
        }
3181 3182
      }
    }
3183

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3184
    if ((frame % 100 == 0) && (subframe==4)) {
3185 3186
      eNB->eNB_UE_stats[i].dlsch_bitrate = (eNB->eNB_UE_stats[i].total_TBS -
          eNB->eNB_UE_stats[i].total_TBS_last);
3187

3188
      eNB->eNB_UE_stats[i].total_TBS_last = eNB->eNB_UE_stats[i].total_TBS;
3189
    }
3190

3191
    // CBA (non-LTE)
3192
    cba_procedures(sched_subframe,eNB,i,harq_pid,abstraction_flag);
3193 3194
  } // loop i=0 ... NUMBER_OF_UE_MAX-1

3195
  if (abstraction_flag == 0) {
3196
    lte_eNB_I0_measurements(eNB,
3197 3198
			    subframe,
			    0,
3199 3200
			    eNB->first_run_I0_measurements);
    eNB->first_run_I0_measurements = 0;
3201
  }
3202

3203
#ifdef PHY_ABSTRACTION
3204
    else {
3205
      lte_eNB_I0_measurements_emul(eNB,
3206
                                   0);
3207
    }
3208

3209
#endif
3210 3211


3212
    //}
3213 3214

#ifdef EMOS
3215
  phy_procedures_emos_eNB_RX(subframe,eNB);
3216 3217
#endif

3218
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,0);
3219
  stop_meas(&eNB->phy_proc_rx);
3220

3221 3222 3223 3224
}

#undef DEBUG_PHY_PROC

3225 3226 3227 3228
#ifdef Rel10
int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type)
{

3229
  int do_proc=0;// do nothing
3230 3231

  switch(r_type) {
3232
  case no_relay:
3233
    do_proc= no_relay; // perform the normal eNB operation
3234
    break;
3235

3236
  case multicast_relay:
3237
    if (((next_slot >>1) < 6) || ((next_slot >>1) > 8))
3238
      do_proc = 0; // do nothing
3239 3240 3241
    else // SF#6, SF#7 and SF#8
      do_proc = multicast_relay; // do PHY procedures eNB TX

3242
    break;
3243

3244 3245
  default: // should'not be here
    LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type);
3246
    do_proc=0;
3247 3248
    break;
  }
3249

3250 3251
  return do_proc;
}
3252
#endif
3253 3254
void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **eNB,uint8_t abstraction_flag,
                            relaying_type_t r_type, PHY_VARS_RN *rn)
3255
{
3256
#if defined(ENABLE_ITTI)
3257 3258 3259 3260 3261
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  unsigned int  Mod_id;
  int           result;
3262
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3263

Raymond Knopp's avatar
 
Raymond Knopp committed
3264 3265 3266

  int CC_id=0;

3267
  /*
3268
    if (eNB->proc[sched_subframe].frame_tx >= 1000)
3269
    mac_xface->macphy_exit("Exiting after 1000 Frames\n");
3270
  */
3271
  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, eNB[0]->proc[subframe].frame_tx);
3272
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1);
3273
  start_meas(&eNB[0]->phy_proc);
Lionel Gauthier's avatar
Lionel Gauthier committed
3274

3275
#if defined(ENABLE_ITTI)
3276

3277
  do {
3278 3279
    // Checks if a message has been sent to PHY sub-task
    itti_poll_msg (TASK_PHY_ENB, &msg_p);
3280

3281 3282 3283 3284
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance;
3285

3286
      switch (ITTI_MSG_ID(msg_p)) {
3287
#   if ENABLE_RAL
3288

Raymond Knopp's avatar
 
Raymond Knopp committed
3289
      case TIMER_HAS_EXPIRED:
3290 3291 3292 3293 3294
        // check if it is a measurement timer
      {
        hashtable_rc_t       hashtable_rc;

        hashtable_rc = hashtable_is_key_exists(PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_timed, (uint64_t)(TIMER_HAS_EXPIRED(msg_p).timer_id));
Raymond Knopp's avatar
 
Raymond Knopp committed
3295

3296 3297 3298 3299 3300
        if (hashtable_rc == HASH_TABLE_OK) {
          phy_eNB_lte_check_measurement_thresholds(instance, (ral_threshold_phy_t*)TIMER_HAS_EXPIRED(msg_p).arg);
        }
      }
      break;
Lionel Gauthier's avatar
Lionel Gauthier committed
3301 3302


Raymond Knopp's avatar
 
Raymond Knopp committed
3303
      case PHY_MEAS_THRESHOLD_REQ:
Lionel Gauthier's avatar
Lionel Gauthier committed
3304
#warning "TO DO LIST OF THRESHOLDS"
3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396
        LOG_D(PHY, "[ENB %d] Received %s\n", Mod_id, msg_name);
        {
          ral_threshold_phy_t* threshold_phy_p  = NULL;
          int                  index, res;
          long                 timer_id;
          hashtable_rc_t       hashtable_rc;

          switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action) {

          case RAL_TH_ACTION_CANCEL_THRESHOLD:
            break;

          case RAL_TH_ACTION_SET_NORMAL_THRESHOLD:
          case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD:
            for (index = 0; index < PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.num_thresholds; index++) {
              threshold_phy_p                  = calloc(1, sizeof(ral_threshold_phy_t));
              threshold_phy_p->th_action       = PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action;
              memcpy(&threshold_phy_p->link_param.link_param_type,
                     &PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type,
                     sizeof(ral_link_param_type_t));

              memcpy(&threshold_phy_p->threshold,
                     &PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.thresholds[index],
                     sizeof(ral_threshold_t));

              switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice) {

              case RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL:
                switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice) {
                case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
                  SLIST_INSERT_HEAD(
                    &PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_gen_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_gen],
                    threshold_phy_p,
                    ral_thresholds);
                  break;

                case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
                  SLIST_INSERT_HEAD(
                    &PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_lte_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_lte],
                    threshold_phy_p,
                    ral_thresholds);
                  break;

                default:
                  LOG_E(PHY, "[ENB %d] BAD PARAMETER cfg_param.link_param_type.choice %d in %s\n",
                        Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice, msg_name);
                }

                break;

              case RAL_LINK_CFG_PARAM_CHOICE_TIMER:
                res = timer_setup(
                        (uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval/1000),//uint32_t      interval_sec,
                        (uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval%1000),//uint32_t      interval_us,
                        TASK_PHY_ENB,
                        instance,
                        TIMER_PERIODIC,
                        threshold_phy_p,
                        &timer_id);

                if (res == 0) {
                  hashtable_rc = hashtable_insert(PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_timed, (uint64_t )timer_id, (void*)threshold_phy_p);

                  if (hashtable_rc == HASH_TABLE_OK) {
                    threshold_phy_p->timer_id = timer_id;
                  } else {
                    LOG_E(PHY, "[ENB %d]  %s: Error in hashtable. Could not configure threshold index %d \n",
                          Mod_id, msg_name, index);
                  }

                } else {
                  LOG_E(PHY, "[ENB %d]  %s: Could not configure threshold index %d because of timer initialization failure\n",
                        Mod_id, msg_name, index);
                }

                break;

              default: // already checked in RRC, should not happen here
                LOG_E(PHY, "[ENB %d] BAD PARAMETER cfg_param.union_choice %d in %s\n",
                      Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice, msg_name);
              }
            }

            break;

          default:
            LOG_E(PHY, "[ENB %d] BAD PARAMETER th_action value %d in %s\n",
                  Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action, msg_name);
          }

        }
        break;
Lionel Gauthier's avatar
Lionel Gauthier committed
3397
#   endif
3398

3399
        /* Messages from eNB app */
Raymond Knopp's avatar
 
Raymond Knopp committed
3400
      case PHY_CONFIGURATION_REQ:
3401 3402
        LOG_I(PHY, "[eNB %d] Received %s\n", instance, msg_name);
        /* TODO */
3403

3404
        break;
3405

Raymond Knopp's avatar
 
Raymond Knopp committed
3406
      default:
3407 3408
        LOG_E(PHY, "[ENB %d] Received unexpected message %s\n", Mod_id, msg_name);
        break;
Lionel Gauthier's avatar
Lionel Gauthier committed
3409
      }
3410 3411 3412 3413

      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    }
3414
  } while(msg_p != NULL);
3415

3416 3417
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3418

3419
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
3420 3421 3422
    if ((((eNB[CC_id]->lte_frame_parms.frame_type == TDD)&&
          (subframe_select(&eNB[CC_id]->lte_frame_parms,eNB[CC_id]->proc[subframe].subframe_tx)==SF_DL))||
         (eNB[CC_id]->lte_frame_parms.frame_type == FDD))) {
3423 3424
#ifdef Rel10

3425
      if (phy_procedures_RN_eNB_TX(eNB[CC_id]->proc[subframe].subframe_rx, eNB[CC_id]->proc[subframe].subframe_tx, r_type) != 0 )
3426
#endif
3427
        phy_procedures_eNB_TX(subframe,eNB[CC_id],abstraction_flag,r_type,rn);
Raymond Knopp's avatar
 
Raymond Knopp committed
3428
    }
3429

3430 3431 3432 3433
    if ((((eNB[CC_id]->lte_frame_parms.frame_type == TDD )&&
          (subframe_select(&eNB[CC_id]->lte_frame_parms,eNB[CC_id]->proc[subframe].subframe_rx)==SF_UL)) ||
         (eNB[CC_id]->lte_frame_parms.frame_type == FDD))) {
      phy_procedures_eNB_RX(subframe,eNB[CC_id],abstraction_flag,r_type);
Raymond Knopp's avatar
 
Raymond Knopp committed
3434
    }
3435

3436
    if (subframe_select(&eNB[CC_id]->lte_frame_parms,eNB[CC_id]->proc[subframe].subframe_tx)==SF_S) {
3437 3438
#ifdef Rel10

Raymond Knopp's avatar
 
Raymond Knopp committed
3439
      if (phy_procedures_RN_eNB_TX(subframe, subframe, r_type) != 0 )
3440
#endif
3441
        phy_procedures_eNB_TX(subframe,eNB[CC_id],abstraction_flag,r_type,rn);
Raymond Knopp's avatar
 
Raymond Knopp committed
3442
    }
3443

3444 3445
    if ((subframe_select(&eNB[CC_id]->lte_frame_parms,eNB[CC_id]->proc[subframe].subframe_rx)==SF_S)) {
      phy_procedures_eNB_S_RX(subframe,eNB[CC_id],abstraction_flag,r_type);
Raymond Knopp's avatar
 
Raymond Knopp committed
3446
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3447

3448 3449
    eNB[CC_id]->proc[subframe].frame_tx++;
    eNB[CC_id]->proc[subframe].frame_rx++;
3450

3451 3452
    if (eNB[CC_id]->proc[subframe].frame_tx>=MAX_FRAME_NUMBER) // defined in impl_defs_top.h
      eNB[CC_id]->proc[subframe].frame_tx-=MAX_FRAME_NUMBER;
3453

3454 3455
    if (eNB[CC_id]->proc[subframe].frame_rx>=MAX_FRAME_NUMBER)
      eNB[CC_id]->proc[subframe].frame_rx-=MAX_FRAME_NUMBER;
Raymond Knopp's avatar
 
Raymond Knopp committed
3456
  }
3457

3458
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0);
3459
  stop_meas(&eNB[0]->phy_proc);
3460 3461
}