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

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


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

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

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

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

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

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

#include "PHY/defs.h"
#include "PHY/extern.h"
#include "MAC_INTERFACE/defs.h"
#include "MAC_INTERFACE/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"

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

52
//#define DEBUG_PHY_PROC (Already defined in cmake)
53 54 55 56 57 58 59
//#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"

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

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

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

#define NS_PER_SLOT 500000

#define PUCCH 1

extern int exit_openair;
77
//extern void do_OFDM_mod(mod_sym_t **txdataF, int32_t **txdata, uint32_t frame, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
78 79 80 81 82 83 84


unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(16)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(16)));
int eNB_sync_buffer1[640*6] __attribute__ ((aligned(16)));
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

85
extern uint16_t hundred_times_log10_NPRB[100];
86

87
unsigned int max_peak_val;
88
int max_sync_pos;
89 90 91 92 93 94 95 96 97 98

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

#if defined(SMBV) && !defined(EXMIMO)
extern const char smbv_fname[];
extern unsigned short config_frames[4];
99
extern uint8_t smbv_frame_cnt;
100 101 102 103 104 105
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

106 107
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
108

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

112
  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
113 114 115
        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);

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

  return(0);
}
135

136 137 138 139 140 141
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
142
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
143 144 145 146 147
{
  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
148 149 150 151 152 153 154 155 156
  /* 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();
  }
157 158 159
  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}

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

Raymond Knopp's avatar
 
Raymond Knopp committed
164
#ifdef DEBUG_PHY_PROC
165 166 167 168
  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
169
#endif
170 171

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

	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));
187
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
188 189 190 191
	      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);
  
192
        return(i);
193
      }
194
    }
195 196 197 198
  }
  return(-1);
}

199
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
200
  uint8_t i;
201 202 203 204 205 206 207 208 209 210 211 212 213
  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);
214
#ifdef DEBUG_PHY_PROC
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
	  LOG_I(PHY,"eNB %d removing UE %d with rnti %x\n",phy_vars_eNB->Mod_id,i,rnti);
#endif
	  //msg("[PHY] UE_id %d\n",i);
	  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);
	}
232
      }
233
    }
234
  }
235
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
236 237 238
  return(-1);
}

239 240
int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB)
{
241
  uint8_t i;
242

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

253 254 255
  return(-1);
}

Lionel Gauthier's avatar
Lionel Gauthier committed
256
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)
257 258 259 260
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
261
  uint8_t i;
Raymond Knopp's avatar
 
Raymond Knopp committed
262
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
263
  int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
264 265

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

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

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

    for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
      if (DLSCH_ptr->harq_processes[i]!=NULL) {
279
	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
	  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);
296
      }
297
    }
298 299 300 301 302 303 304 305

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

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

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

321 322 323
  return(0);
}

324
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
325
{
326 327
  //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;
328 329
}

330 331 332 333 334 335
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;
}

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

}
#endif



345 346 347
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);
348

349
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
350

351
#ifdef DEBUG_PHY_PROC
352
  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);
353
#endif
354

355

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
369 370
#endif

371

372 373
}

Raymond Knopp's avatar
 
Raymond Knopp committed
374 375


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

380 381 382 383
  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;
384 385 386

  last_subframe_emos=0;

Raymond Knopp's avatar
 
Raymond Knopp committed
387

Raymond Knopp's avatar
 
Raymond Knopp committed
388

Raymond Knopp's avatar
 
Raymond Knopp committed
389

390
#ifdef EMOS_CHANNEL
391

392
  //if (last_slot%2==1) // this is for all UL subframes
393
  if (subframe==3)
394
    for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) {
395 396 397 398 399 400
      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));
401
    }
402

403 404
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
405
  if (subframe==4) {
406
    emos_dump_eNB.timestamp = rt_get_time_ns();
jiangx's avatar
jiangx committed
407
    emos_dump_eNB.frame_tx = phy_vars_eNB->proc[subframe].frame_rx;
408 409 410 411 412 413 414 415
    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));
416

417 418
    //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
    if (bytes!=sizeof(fifo_dump_emos_eNB)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
419
      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
420
            phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
421
    } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
422 423
      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
424
              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);
425
      }
426
    }
427 428 429 430 431 432 433
  }
}
#endif


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
434 435
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)};
436

Lionel Gauthier's avatar
Lionel Gauthier committed
437 438

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

442 443
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
444
  MessageDef *message_p = NULL;
445

Raymond Knopp's avatar
 
Raymond Knopp committed
446
  if (
447 448 449 450 451 452
    (
      ((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
453 454 455 456
    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,
457 458
           &threshold_phy_pP->threshold,
           sizeof(PHY_MEAS_REPORT_IND (message_p).threshold));
Raymond Knopp's avatar
 
Raymond Knopp committed
459 460

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

    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;
469

Raymond Knopp's avatar
 
Raymond Knopp committed
470 471 472 473
    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;
474
    }
475

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

480 481
void phy_eNB_lte_check_measurement_thresholds(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
482 483 484 485 486 487 488 489 490 491 492
  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;
493

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
502 503
    case RAL_LINK_PARAM_GEN_THROUGHPUT:
      break;
504

Raymond Knopp's avatar
 
Raymond Knopp committed
505 506
    case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE:
      break;
507 508 509

    default:
      ;
Lionel Gauthier's avatar
Lionel Gauthier committed
510
    }
511

Raymond Knopp's avatar
 
Raymond Knopp committed
512 513 514 515 516 517
    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;
518

Raymond Knopp's avatar
 
Raymond Knopp committed
519 520
    case RAL_LINK_PARAM_LTE_UE_RSRQ:
      break;
521

Raymond Knopp's avatar
 
Raymond Knopp committed
522 523
    case RAL_LINK_PARAM_LTE_UE_CQI:
      break;
524

Raymond Knopp's avatar
 
Raymond Knopp committed
525 526
    case RAL_LINK_PARAM_LTE_AVAILABLE_BW:
      break;
527

Raymond Knopp's avatar
 
Raymond Knopp committed
528 529
    case RAL_LINK_PARAM_LTE_PACKET_DELAY:
      break;
530

Raymond Knopp's avatar
 
Raymond Knopp committed
531 532
    case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE:
      break;
533

Raymond Knopp's avatar
 
Raymond Knopp committed
534 535
    case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS:
      break;
536

Raymond Knopp's avatar
 
Raymond Knopp committed
537 538
    case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES:
      break;
539

Raymond Knopp's avatar
 
Raymond Knopp committed
540 541
    case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY:
      break;
542

Raymond Knopp's avatar
 
Raymond Knopp committed
543 544
    case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY:
      break;
545

Raymond Knopp's avatar
 
Raymond Knopp committed
546 547
    case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS:
      break;
548

Raymond Knopp's avatar
 
Raymond Knopp committed
549 550
    case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW:
      break;
551 552 553

    default:
      ;
Raymond Knopp's avatar
 
Raymond Knopp committed
554
    }
555

Raymond Knopp's avatar
 
Raymond Knopp committed
556 557
    break;

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

Raymond Knopp's avatar
 
Raymond Knopp committed
565 566


Raymond Knopp's avatar
 
Raymond Knopp committed
567
void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,
568 569
                           relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn)
{
570
  UNUSED(phy_vars_rn);
571 572
  uint8_t *pbch_pdu=&phy_vars_eNB->pbch_pdu[0];
  uint16_t input_buffer_length, re_allocated=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
573
  uint32_t i,aa;
574
  uint8_t harq_pid;
575
  DCI_PDU *DCI_pdu;
576
  uint8_t *DLSCH_pdu=NULL;
577
  DCI_PDU DCI_pdu_tmp;
578 579 580 581 582
  uint8_t DLSCH_pdu_tmp[768*8];
  int8_t UE_id;
  uint8_t num_pdcch_symbols=0;
  uint8_t ul_subframe;
  uint32_t ul_frame;
583
#ifdef Rel10
584 585
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
586
  //  uint8_t sync_area=255;
587 588 589 590
#endif
#if defined(SMBV) && !defined(EXMIMO)
  // counts number of allocations in subframe
  // there is at least one allocation for PDCCH
591
  uint8_t smbv_alloc_cnt = 1;
592
#endif
593
  int frame = phy_vars_eNB->proc[sched_subframe].frame_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
594
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_tx;
595

596
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,1);
597
  start_meas(&phy_vars_eNB->phy_proc_tx);
598

599
#ifdef DEBUG_PHY_PROC
600
  LOG_D(PHY,"[%s %"PRIu8"] Frame %d subframe %d : Doing phy_procedures_eNB_TX\n",
601 602
        (r_type == multicast_relay) ? "RN/eNB" : "eNB",
        phy_vars_eNB->Mod_id, frame, subframe);
603
#endif
604

605
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
606 607 608
    // If we've dropped the UE, go back to PRACH mode for this UE
    //#if !defined(EXMIMO_IOT)
    if (phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors == ULSCH_max_consecutive_errors) {
609
      LOG_W(PHY,"[eNB %d, CC %d] frame %d, subframe %d, UE %d: ULSCH consecutive error count reached %u, triggering UL Failure\n",
610
            phy_vars_eNB->Mod_id,phy_vars_eNB->CC_id,frame,subframe, i, phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors);
611
      /*
612 613
      phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
      remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag);
614
      */
615
      phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
616 617 618 619 620 621
      mac_xface->UL_failure_indication(phy_vars_eNB->Mod_id,
				       phy_vars_eNB->CC_id,
				       frame,
				       phy_vars_eNB->eNB_UE_stats[i].crnti,
				       subframe);
				       
622
    }
623
	
624 625 626 627
    //#endif
  }


628
  // Get scheduling info for next subframe
629 630 631 632 633
  if (phy_vars_eNB->mac_enabled==1) {
    if (phy_vars_eNB->CC_id == 0) {
      mac_xface->eNB_dlsch_ulsch_scheduler(phy_vars_eNB->Mod_id,0,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);//,1);
    }
  }
634

Raymond Knopp's avatar
 
Raymond Knopp committed
635
  if (abstraction_flag==0) {
636
    // clear the transmit data array for the current subframe
637 638
    for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_tx_eNB; aa++) {

Raymond Knopp's avatar
 
Raymond Knopp committed
639
      memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][subframe*phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti)],
640
             0,phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti)*sizeof(mod_sym_t));
Raymond Knopp's avatar
 
Raymond Knopp committed
641 642
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
643 644


Raymond Knopp's avatar
 
Raymond Knopp committed
645
  if (is_pmch_subframe(phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,&phy_vars_eNB->lte_frame_parms)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
646

647
    if (abstraction_flag==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
648 649
      // This is DL-Cell spec pilots in Control region
      generate_pilots_slot(phy_vars_eNB,
650 651 652
                           phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                           AMP,
                           subframe<<1,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
653
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
654

655
#ifdef Rel10
Raymond Knopp's avatar
 
Raymond Knopp committed
656
    // if mcch is active, send regardless of the node type: eNB or RN
657
    // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing
Raymond Knopp's avatar
 
Raymond Knopp committed
658
    mch_pduP = mac_xface->get_mch_sdu(phy_vars_eNB->Mod_id,
659 660 661 662 663
                                      phy_vars_eNB->CC_id,
                                      phy_vars_eNB->proc[sched_subframe].frame_tx,
                                      subframe);

    switch (r_type) {
Raymond Knopp's avatar
 
Raymond Knopp committed
664
    case no_relay:
665
      if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
666
        LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
667 668
              phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->mcs,
              phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3);
Raymond Knopp's avatar
 
Raymond Knopp committed
669
      else {
670
        LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
671 672 673
              phy_vars_eNB->Mod_id,phy_vars_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;
Raymond Knopp's avatar
 
Raymond Knopp committed
674
      }
675

Raymond Knopp's avatar
 
Raymond Knopp committed
676
      break;
677

Raymond Knopp's avatar
 
Raymond Knopp committed
678
    case multicast_relay:
679
      if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) {
680
        LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN  sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
681 682 683 684 685 686 687 688 689
              phy_vars_rn->Mod_id,phy_vars_rn->frame, subframe,
              mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);
      } else if (phy_vars_rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8
        mch_pduP= &mch_pdu;
        memcpy(&mch_pduP->payload, // could be a simple copy
               phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b,
               phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
        mch_pduP->Pdu_size = (uint16_t) (phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
        mch_pduP->mcs = phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs;
690
        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",
691 692
              phy_vars_rn->Mod_id,phy_vars_rn->frame, subframe,subframe%5,
              phy_vars_rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size);
Raymond Knopp's avatar
 
Raymond Knopp committed
693
      } else {
694 695 696 697
        /* LOG_I(PHY,"[RN %d] Frame %d subframe %d: do not forward MCH pdu for MBSFN  sync area %d (MCS %d, TBS %d)\n",
           phy_vars_rn->Mod_id,phy_vars_rn->frame, next_slot>>1,
           mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);*/
        mch_pduP=NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
698
      }
699

Raymond Knopp's avatar
 
Raymond Knopp committed
700 701
      phy_vars_rn->mch_avtive[subframe]=0;
      break;
702

Raymond Knopp's avatar
 
Raymond Knopp committed
703
    default:
704
      LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
705
            phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,r_type);
Raymond Knopp's avatar
 
Raymond Knopp committed
706 707
      mch_pduP=NULL;
      break;
708 709 710
    }// switch

    if (mch_pduP) {
Raymond Knopp's avatar
 
Raymond Knopp committed
711 712
      fill_eNB_dlsch_MCH(phy_vars_eNB,mch_pduP->mcs,1,0, abstraction_flag);
      // Generate PMCH
Raymond Knopp's avatar
 
Raymond Knopp committed
713
      generate_mch(phy_vars_eNB,sched_subframe,(uint8_t*)mch_pduP->payload,abstraction_flag);
714
#ifdef DEBUG_PHY
715 716

      for (i=0; i<mch_pduP->Pdu_size; i++)
717
        msg("%2"PRIx8".",(uint8_t)mch_pduP->payload[i]);
718

Raymond Knopp's avatar
 
Raymond Knopp committed
719
      msg("\n");
720
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
721 722
    } else {
      LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
723
    }
724

Raymond Knopp's avatar
 
Raymond Knopp committed
725 726
#endif
  }
727

Raymond Knopp's avatar
 
Raymond Knopp committed
728
  else {
729
    // this is not a pmch subframe
730 731

    if (abstraction_flag==0) {
732
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
733
      generate_pilots_slot(phy_vars_eNB,
734 735 736
                           phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                           AMP,
                           subframe<<1,0);
737 738 739 740 741 742
      if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_DL)
	generate_pilots_slot(phy_vars_eNB,
			     phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
			     AMP,
			     (subframe<<1)+1,0);

743
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
744

Raymond Knopp's avatar
 
Raymond Knopp committed
745 746
      // First half of PSS/SSS (FDD)
      if (subframe == 0) {
747 748
        if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
          generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
749
                       AMP,
750
                       &phy_vars_eNB->lte_frame_parms,
751
                       (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
752 753
                       0);
          generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
754
                       AMP,
755
                       &phy_vars_eNB->lte_frame_parms,
756
                       (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4,
757 758 759 760
                       0);

        }
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
761
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
762
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
763

Raymond Knopp's avatar
 
Raymond Knopp committed
764
  if (subframe == 0) {
765
    // generate PBCH (Physical Broadcast CHannel) info
Raymond Knopp's avatar
 
Raymond Knopp committed
766
    if ((phy_vars_eNB->proc[sched_subframe].frame_tx&3) == 0) {
767
      pbch_pdu[2] = 0;
768

769
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
Raymond Knopp's avatar
 
Raymond Knopp committed
770 771
      switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
      case 6:
772
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
773 774
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
775
      case 15:
776
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
777 778
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
779
      case 25:
780
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
781 782
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
783
      case 50:
784
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
785 786
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
787
      case 75:
788
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
789 790
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
791
      case 100:
792
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
793 794
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
795
      default:
796 797
        // FIXME if we get here, this should be flagged as an error, right?
        pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
798
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
799
      }
800

801
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
802 803
                    ((phy_vars_eNB->lte_frame_parms.phich_config_common.phich_duration << 4)&0x10);

Raymond Knopp's avatar
 
Raymond Knopp committed
804 805
      switch (phy_vars_eNB->lte_frame_parms.phich_config_common.phich_resource) {
      case oneSixth:
806
        pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
807 808
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
809
      case half:
810
        pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
811 812
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
813
      case one:
814
        pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
815 816
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
817
      case two:
818
        pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
819 820
        break;

Raymond Knopp's avatar
 
Raymond Knopp committed
821
      default:
822
        // unreachable
823
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
824
      }
825

826 827 828
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((phy_vars_eNB->proc[sched_subframe].frame_tx>>8)&0x3);
      pbch_pdu[1] = phy_vars_eNB->proc[sched_subframe].frame_tx&0xfc;
      pbch_pdu[0] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
829
    }
830

Raymond Knopp's avatar
 
Raymond Knopp committed
831 832
    /// First half of SSS (TDD)
    if (abstraction_flag==0) {
833

Raymond Knopp's avatar
 
Raymond Knopp committed
834
      if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
835 836 837
        generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                     AMP,
                     &phy_vars_eNB->lte_frame_parms,
838
                     (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
839
                     1);
Raymond Knopp's avatar
 
Raymond Knopp committed
840
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
841
    }
842 843


844 845


846
#ifdef DEBUG_PHY_PROC
847 848 849
    uint16_t frame_tx = (((int) (pbch_pdu[2]&0x3))<<8) + ((int) (pbch_pdu[1]&0xfc)) + phy_vars_eNB->proc[sched_subframe].frame_tx%4;

    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Generating PBCH, mode1_flag=%"PRIu8", frame_tx=%"PRIu16", pdu=%02"PRIx8"%02"PRIx8"%02"PRIx8"\n",
850 851 852 853 854
          phy_vars_eNB->Mod_id,
          phy_vars_eNB->proc[sched_subframe].frame_tx,
          subframe,
          phy_vars_eNB->lte_frame_parms.mode1_flag,
          frame_tx,
855 856 857
          pbch_pdu[2],
          pbch_pdu[1],
          pbch_pdu[0]);
858
#endif
859

Raymond Knopp's avatar
 
Raymond Knopp committed
860
    if (abstraction_flag==0) {
861

Raymond Knopp's avatar
 
Raymond Knopp committed
862
      generate_pbch(&phy_vars_eNB->lte_eNB_pbch,
863 864 865 866 867 868
                    phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                    AMP,
                    &phy_vars_eNB->lte_frame_parms,
                    pbch_pdu,
                    phy_vars_eNB->proc[sched_subframe].frame_tx&3);

Raymond Knopp's avatar
 
Raymond Knopp committed
869
    }
870

871
#ifdef PHY_ABSTRACTION
Raymond Knopp's avatar
 
Raymond Knopp committed
872
    else {
873
      generate_pbch_emul(phy_vars_eNB,pbch_pdu);
Raymond Knopp's avatar
 
Raymond Knopp committed
874
    }
875

Raymond Knopp's avatar
 
Raymond Knopp committed
876
#endif
877 878


Raymond Knopp's avatar
 
Raymond Knopp committed
879
  }
880

Raymond Knopp's avatar
 
Raymond Knopp committed
881
  if (subframe == 1) {
882

Raymond Knopp's avatar
 
Raymond Knopp committed
883
    if (abstraction_flag==0) {
884

Raymond Knopp's avatar
 
Raymond Knopp committed
885
      if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
886 887
        //    printf("Generating PSS (frame %d, subframe %d)\n",phy_vars_eNB->proc[sched_subframe].frame_tx,next_slot>>1);
        generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
888
                     AMP,
889 890 891
                     &phy_vars_eNB->lte_frame_parms,
                     2,
                     2);
Raymond Knopp's avatar
 
Raymond Knopp committed
892
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
893
    }
894 895
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
896 897
  // Second half of PSS/SSS (FDD)
  if (subframe == 5) {
898

Raymond Knopp's avatar
 
Raymond Knopp committed
899
    if (abstraction_flag==0) {
900

Raymond Knopp's avatar
 
Raymond Knopp committed
901
      if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
902
        generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
903
                     AMP,
904
                     &phy_vars_eNB->lte_frame_parms,
905
                     (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
906 907
                     10);
        generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
908
                     AMP,
909
                     &phy_vars_eNB->lte_frame_parms,
910
                     (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4,
911 912
                     10);

913
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
914
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
915
  }
916

Raymond Knopp's avatar
 
Raymond Knopp committed
917 918 919
  //  Second-half of SSS (TDD)
  if (subframe == 5) {
    if (abstraction_flag==0) {
920

Raymond Knopp's avatar
 
Raymond Knopp committed
921
      if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
922 923 924
        generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                     AMP,
                     &phy_vars_eNB->lte_frame_parms,
925
                     (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
926
                     11);
927
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
928
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
929
  }
930

Raymond Knopp's avatar
 
Raymond Knopp committed
931 932
  // Second half of PSS (TDD)
  if (subframe == 6) {
933

Raymond Knopp's avatar
 
Raymond Knopp committed
934
    if (abstraction_flag==0) {
935

Raymond Knopp's avatar
 
Raymond Knopp committed
936
      if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
937 938
        //      printf("Generating PSS (frame %d, subframe %d)\n",phy_vars_eNB->proc[sched_subframe].frame_tx,next_slot>>1);
        generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
939
                     AMP,
940 941 942
                     &phy_vars_eNB->lte_frame_parms,
                     2,
                     12);
943
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
944
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
945
  }
946 947 948



949
#if defined(SMBV) && !defined(EXMIMO)
950

Raymond Knopp's avatar
 
Raymond Knopp committed
951 952
  // PBCH takes one allocation
  if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
953
    if (subframe==0)
Raymond Knopp's avatar
 
Raymond Knopp committed
954 955
      smbv_alloc_cnt++;
  }
956

957
#endif
958

959 960 961 962 963 964 965 966 967 968
  if (phy_vars_eNB->mac_enabled==1) {
    // Parse DCI received from MAC
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1);
    DCI_pdu = mac_xface->get_dci_sdu(phy_vars_eNB->Mod_id,
				     phy_vars_eNB->CC_id,
				     phy_vars_eNB->proc[sched_subframe].frame_tx,
				     subframe);
  }
  else {
    DCI_pdu = &DCI_pdu_tmp;
969
#ifdef EMOS_CHANNEL
970
    fill_dci_emos(DCI_pdu,sched_subframe,phy_vars_eNB);
971
#else
972
    fill_dci(DCI_pdu,sched_subframe,phy_vars_eNB);
973
#endif
974
  }
975

Raymond Knopp's avatar
 
Raymond Knopp committed
976 977
  // clear existing ulsch dci allocations before applying info from MAC  (this is table
  ul_subframe = pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe);
978
  ul_frame = pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
979

Raymond Knopp's avatar
 
Raymond Knopp committed
980 981 982
  if ((subframe_select(&phy_vars_eNB->lte_frame_parms,ul_subframe)==SF_UL) ||
      (phy_vars_eNB->lte_frame_parms.frame_type == FDD)) {
    harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,ul_frame,ul_subframe);
983 984

    for (i=0; i<NUMBER_OF_UE_MAX; i++)
Raymond Knopp's avatar
 
Raymond Knopp committed
985
      if (phy_vars_eNB->ulsch_eNB[i]) {
986 987
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc=0;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
988 989
      }
  }
990

991
#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
992
  //emos_dump_eNB.dci_cnt[next_slot>>1] = DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci; //nb_dci_common+nb_dci_ue_spec;
993
#endif
994

Raymond Knopp's avatar
 
Raymond Knopp committed
995
  // clear previous allocation information for all UEs
996
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
997 998
    phy_vars_eNB->dlsch_eNB[i][0]->subframe_tx[subframe] = 0;
  }
999 1000


1001 1002
  num_pdcch_symbols = DCI_pdu->num_pdcch_symbols;

1003
  LOG_D(PHY,"num_pdcch_symbols %"PRIu8", nCCE %u (dci commond %"PRIu8", dci uespec %"PRIu8"\n",num_pdcch_symbols,DCI_pdu->nCCE,
1004 1005
        DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);

1006
#if defined(SMBV) && !defined(EXMIMO)
1007

Raymond Knopp's avatar
 
Raymond Knopp committed
1008 1009 1010 1011 1012 1013
  // Sets up PDCCH and DCI table
  if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4) && ((DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci)>0)) {
    msg("[SMBV] Frame %3d, SF %d PDCCH, number of DCIs %d\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
    dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[0]);
    smbv_configure_pdcch(smbv_fname,(smbv_frame_cnt*10) + (subframe),num_pdcch_symbols,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
  }
1014 1015 1016 1017

#endif

  for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
1018
    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);
1019
#ifdef DEBUG_PHY_PROC
1020

Raymond Knopp's avatar
 
Raymond Knopp committed
1021
    if (DCI_pdu->dci_alloc[i].rnti != SI_RNTI) {
1022
      LOG_D(PHY,"[eNB] Subframe %d : Doing DCI index %"PRIu32"/%d\n",subframe,i,DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci);
Raymond Knopp's avatar
 
Raymond Knopp committed
1023 1024
      dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]);
    }
1025

1026
#endif
1027

Raymond Knopp's avatar
 
Raymond Knopp committed
1028
    if (DCI_pdu->dci_alloc[i].rnti == SI_RNTI) {
1029
#ifdef DEBUG_PHY_PROC
1030
      LOG_D(PHY,"[eNB %"PRIu8"] SI generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
1031
#endif
1032

1033 1034
      generate_eNB_dlsch_params_from_dci(frame,
					 subframe,
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
                                         &DCI_pdu->dci_alloc[i].dci_pdu[0],
                                         DCI_pdu->dci_alloc[i].rnti,
                                         DCI_pdu->dci_alloc[i].format,
                                         &phy_vars_eNB->dlsch_eNB_SI,
                                         &phy_vars_eNB->lte_frame_parms,
                                         phy_vars_eNB->pdsch_config_dedicated,
                                         SI_RNTI,
                                         0,
                                         P_RNTI,
                                         phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single);

1046

1047
      phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
1048

1049 1050 1051
      LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
	    phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe],DCI_pdu->nCCE);
      
1052
#if defined(SMBV) && !defined(EXMIMO)
1053

1054 1055 1056 1057
      // configure SI DCI
      if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	msg("[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i);
	smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", &DCI_pdu->dci_alloc[i], i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1058
      }
1059 1060 1061
      
#endif
      
1062 1063

    } else if (DCI_pdu->dci_alloc[i].ra_flag == 1) {
1064
#ifdef DEBUG_PHY_PROC
1065
      LOG_D(PHY,"[eNB %"PRIu8"] RA generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
1066
#endif
1067

1068 1069
      generate_eNB_dlsch_params_from_dci(frame,
					 subframe,
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
                                         &DCI_pdu->dci_alloc[i].dci_pdu[0],
                                         DCI_pdu->dci_alloc[i].rnti,
                                         DCI_pdu->dci_alloc[i].format,
                                         &phy_vars_eNB->dlsch_eNB_ra,
                                         &phy_vars_eNB->lte_frame_parms,
                                         phy_vars_eNB->pdsch_config_dedicated,
                                         SI_RNTI,
                                         DCI_pdu->dci_alloc[i].rnti,
                                         P_RNTI,
                                         phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single);

      //    mac_xface->macphy_exit("Transmitted RAR, exiting\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1082

1083

1084
      phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
1085

1086 1087 1088
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
	    phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe],DCI_pdu->nCCE);
#if defined(SMBV) && !defined(EXMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
1089

1090 1091 1092 1093
      // configure RA DCI
      if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	msg("[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i);
	smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", &DCI_pdu->dci_alloc[i], i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1094
      }
1095

1096
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1097 1098

    }
1099

1100
    else if (DCI_pdu->dci_alloc[i].format != format0) { // this is a normal DLSCH allocation
1101 1102

#ifdef DEBUG_PHY_PROC
1103
      LOG_D(PHY,"[eNB] Searching for RNTI %"PRIx16"\n",DCI_pdu->dci_alloc[i].rnti);
1104
#endif
1105 1106 1107 1108 1109

      if (phy_vars_eNB->mac_enabled==1)
	UE_id = find_ue((int16_t)DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB);
      else
	UE_id = i;
1110

Raymond Knopp's avatar
 
Raymond Knopp committed
1111
      if (UE_id>=0) {
1112 1113 1114 1115
	if ((frame%100)==0) {
	  LOG_D(PHY,"Frame %3d, SF %d \n",frame,subframe); 
	  dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]);
	}
1116
#if defined(SMBV) && !defined(EXMIMO)
1117 1118 1119 1120 1121 1122 1123
        // Configure this user
        if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
          msg("[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
              DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->transmission_mode[(uint8_t)UE_id]);
          smbv_configure_user(smbv_fname,UE_id+1,phy_vars_eNB->transmission_mode[(uint8_t)UE_id],DCI_pdu->dci_alloc[i].rnti);
        }

Raymond Knopp's avatar
 
Raymond Knopp committed
1124
#endif
1125

1126 1127
        generate_eNB_dlsch_params_from_dci(frame,
					   subframe,
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
                                           &DCI_pdu->dci_alloc[i].dci_pdu[0],
                                           DCI_pdu->dci_alloc[i].rnti,
                                           DCI_pdu->dci_alloc[i].format,
                                           phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id],
                                           &phy_vars_eNB->lte_frame_parms,
                                           phy_vars_eNB->pdsch_config_dedicated,
                                           SI_RNTI,
                                           0,
                                           P_RNTI,
                                           phy_vars_eNB->eNB_UE_stats[(uint8_t)UE_id].DL_pmi_single);
1138 1139 1140
        LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
              phy_vars_eNB->Mod_id,DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);

1141

1142
        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
1143

1144 1145
	LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
	      DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe],DCI_pdu->nCCE);
1146

1147 1148 1149 1150 1151 1152 1153
#if defined(SMBV) && !defined(EXMIMO)
	
	// configure UE-spec DCI
	if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	  msg("[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",phy_vars_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);
	}
1154

Raymond Knopp's avatar
 
Raymond Knopp committed
1155
#endif
1156 1157 1158

#ifdef DEBUG_PHY_PROC
        //if (phy_vars_eNB->proc[sched_subframe].frame_tx%100 == 0)
1159
        LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
1160 1161 1162 1163
              phy_vars_eNB->Mod_id, DCI_pdu->dci_alloc[i].rnti,
              phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,UE_id,
              DCI_pdu->dci_alloc[i].format,
              1<<DCI_pdu->dci_alloc[i].L);
Raymond Knopp's avatar
 
Raymond Knopp committed
1164
#endif
1165
      } else {
1166 1167
        LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
              phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti);
1168
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1169
    }
1170

Raymond Knopp's avatar
 
Raymond Knopp committed
1171
  }
1172

Raymond Knopp's avatar
 
Raymond Knopp committed
1173 1174
  // Apply physicalConfigDedicated if needed
  phy_config_dedicated_eNB_step2(phy_vars_eNB);
Raymond Knopp's avatar
 
Raymond Knopp committed
1175

1176
  for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1177 1178 1179
    if (DCI_pdu->dci_alloc[i].format == format0) {  // this is a ULSCH allocation

      harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,
1180 1181 1182
                                   pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
                                   pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe));

Raymond Knopp's avatar
 
Raymond Knopp committed
1183
      if (harq_pid==255) {
1184
        LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx);
kaltenbe's avatar
kaltenbe committed
1185
        //mac_exit_wrapper("Invalid harq_pid (255) detected");
1186
        return; 
Raymond Knopp's avatar
 
Raymond Knopp committed
1187
      }
1188

1189 1190 1191 1192
      if (phy_vars_eNB->mac_enabled==1)
	UE_id = find_ue((int16_t)DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB);
      else
	UE_id = i;
1193

Raymond Knopp's avatar
 
Raymond Knopp committed
1194
      if (UE_id<0) {
1195
        LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Unknown UE_id for rnti %"PRIx16"\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti);
1196 1197
        mac_exit_wrapper("Invalid UE id (< 0) detected");
        return; // not reached
Raymond Knopp's avatar
 
Raymond Knopp committed
1198
      }
1199

1200
      //#ifdef DEBUG_PHY_PROC
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1201
      //if (phy_vars_eNB->proc[sched_subframe].frame_tx%100 == 0)
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
      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") (DCI pos %"PRIu32"/%d), aggregation %d\n",
            phy_vars_eNB->Mod_id,
            subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,
                              pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
                              pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe)),
            phy_vars_eNB->proc[sched_subframe].frame_tx,
            subframe,
            pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
            pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe),
            DCI_pdu->dci_alloc[i].rnti,
            DCI_pdu->dci_alloc[i].dci_pdu[0],
            i,
            DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci,
            1<<DCI_pdu->dci_alloc[i].L);
1217
      //#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1218 1219 1220

      //dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]);
      //LOG_D(PHY,"[eNB] cba generate_eNB_ulsch_params_from_dci for ue %d for dci rnti %x\n", UE_id, DCI_pdu->dci_alloc[i].rnti);
1221

Raymond Knopp's avatar
 
Raymond Knopp committed
1222
      generate_eNB_ulsch_params_from_dci(&DCI_pdu->dci_alloc[i].dci_pdu[0],
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
                                         DCI_pdu->dci_alloc[i].rnti,
                                         sched_subframe,
                                         format0,
                                         UE_id,
                                         phy_vars_eNB,
                                         SI_RNTI,
                                         0,
                                         P_RNTI,
                                         CBA_RNTI,
                                         0);  // do_srs
Raymond Knopp's avatar
 
Raymond Knopp committed
1233

1234 1235 1236 1237
      LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d/%u\n",
	    phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->dci_alloc[i].rnti,
	    DCI_pdu->dci_alloc[i].firstCCE,DCI_pdu->nCCE);
      
1238
#if defined(SMBV) && !defined(EXMIMO)
1239 1240

        // configure UE-spec DCI for UL Grant
1241 1242 1243 1244 1245
      if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	msg("[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",phy_vars_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);
      }
      
1246 1247
#endif

1248
      
1249

Lionel Gauthier's avatar
 
Lionel Gauthier committed
1250
#ifdef DEBUG_PHY_PROC
1251
      LOG_D(PHY,"[eNB %"PRIu8"][PUSCH %"PRIu8"] frame %d subframe %d Setting subframe_scheduling_flag for UE %"PRIu32" harq_pid %"PRIu8" (ul subframe %"PRIu8")\n",
1252 1253 1254
            phy_vars_eNB->Mod_id,harq_pid,
            phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i,harq_pid,
            pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe));
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1255
#endif
1256

Raymond Knopp's avatar
 
Raymond Knopp committed
1257
      if ((DCI_pdu->dci_alloc[i].rnti  >= CBA_RNTI) && (DCI_pdu->dci_alloc[i].rnti < P_RNTI))
1258 1259 1260
        phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
      else
        phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
1261

Raymond Knopp's avatar
 
Raymond Knopp committed
1262
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1263
  }
1264

1265 1266


Lionel Gauthier's avatar
Lionel Gauthier committed
1267 1268


Raymond Knopp's avatar
 
Raymond Knopp committed
1269 1270
  // 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
1271

1272 1273

  } else { // for emulation!!
Raymond Knopp's avatar
 
Raymond Knopp committed
1274 1275 1276
    phy_vars_eNB->num_ue_spec_dci[(subframe)&1]=0;
    phy_vars_eNB->num_common_dci[(subframe)&1]=0;
  }
1277

Raymond Knopp's avatar
 
Raymond Knopp committed
1278
  if (abstraction_flag == 0) {
1279
    //#ifdef DEBUG_PHY_PROC
1280

Raymond Knopp's avatar
 
Raymond Knopp committed
1281
    if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0)
1282 1283 1284
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,
            DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);

1285
    //#endif
1286

1287 1288 1289 1290 1291 1292 1293 1294
    num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci,
                                         DCI_pdu->Num_common_dci,
                                         DCI_pdu->dci_alloc,
                                         0,
                                         AMP,
                                         &phy_vars_eNB->lte_frame_parms,
                                         phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                                         subframe);
Raymond Knopp's avatar
Raymond Knopp committed
1295 1296

#ifdef DEBUG_PHY_PROC
1297
    //  LOG_I(PHY,"[eNB %d] Frame %d, subframe %d: num_pdcch_symbols %d)\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot>>1,num_pdcch_symbols);
Raymond Knopp's avatar
Raymond Knopp committed
1298 1299

#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1300
  }
1301

1302
#ifdef PHY_ABSTRACTION // FIXME this ifdef seems suspicious
Raymond Knopp's avatar
 
Raymond Knopp committed
1303
  else {
1304
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top_emul\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1305 1306
    num_pdcch_symbols = generate_dci_top_emul(phy_vars_eNB,DCI_pdu->Num_ue_spec_dci,DCI_pdu->Num_common_dci,DCI_pdu->dci_alloc,subframe);
  }
1307

1308 1309
#endif

1310
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
1311 1312

#ifdef DEBUG_PHY_PROC
Raymond Knopp's avatar
 
Raymond Knopp committed
1313
  //LOG_D(PHY,"[eNB %d] Frame %d, slot %d: num_pdcch_symbols=%d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot,num_pdcch_symbols);
1314 1315
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1316
  // Check for SI activity
1317

Raymond Knopp's avatar
 
Raymond Knopp committed
1318 1319
  if (phy_vars_eNB->dlsch_eNB_SI->active == 1) {
    input_buffer_length = phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->TBS/8;
1320 1321


1322 1323 1324 1325 1326 1327 1328 1329 1330
    if (phy_vars_eNB->mac_enabled==1) {
      DLSCH_pdu = mac_xface->get_dlsch_sdu(phy_vars_eNB->Mod_id,
					   phy_vars_eNB->CC_id,
					   phy_vars_eNB->proc[sched_subframe].frame_tx,
					   SI_RNTI,
					   0);
    }
    else {
      DLSCH_pdu = DLSCH_pdu_tmp;
1331

1332 1333 1334
      for (i=0; i<input_buffer_length; i++)
	DLSCH_pdu[i] = (unsigned char)(taus()&0xff);
    }
1335

1336
#if defined(SMBV) && !defined(EXMIMO)
1337

Raymond Knopp's avatar
 
Raymond Knopp committed
1338 1339
    // Configures the data source of allocation (allocation is configured by DCI)
    if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
1340
      msg("[SMBV] Frame %3d, Configuring SI payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1341 1342
      smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), DLSCH_pdu, input_buffer_length);
    }
1343 1344

#endif
1345 1346 1347

#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
1348 1349
   //FIXME: The code below is commented as next_slot is not defined which results in failed compilation
   /*
1350 1351
    LOG_D(PHY,"[eNB %"PRIu8"][SI] Frame %d, slot %d: Calling generate_dlsch (SI) with input size = %"PRIu16", num_pdcch_symbols %"PRIu8"\n",
          phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot, input_buffer_length,num_pdcch_symbols); // FIXME this code is broken (next_slot?)
1352 1353

    for (i=0; i<input_buffer_length; i++)
1354
      LOG_T(PHY,"%x.",i,DLSCH_pdu[i]);// FIXME this code is broken (number of arguments)
1355

Raymond Knopp's avatar
 
Raymond Knopp committed
1356
    LOG_T(PHY,"\n");
1357
    */
1358 1359 1360
#endif
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1361
    if (abstraction_flag == 0) {
1362

1363
      start_meas(&phy_vars_eNB->dlsch_encoding_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1364
      dlsch_encoding(DLSCH_pdu,
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374
                     &phy_vars_eNB->lte_frame_parms,
                     num_pdcch_symbols,
                     phy_vars_eNB->dlsch_eNB_SI,
                     phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
                     &phy_vars_eNB->dlsch_rate_matching_stats,
                     &phy_vars_eNB->dlsch_turbo_encoding_stats,
                     &phy_vars_eNB->dlsch_interleaving_stats);
      stop_meas(&phy_vars_eNB->dlsch_encoding_stats);

      start_meas(&phy_vars_eNB->dlsch_scrambling_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1375
      dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
                       0,
                       phy_vars_eNB->dlsch_eNB_SI,
                       get_G(&phy_vars_eNB->lte_frame_parms,
                             phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->nb_rb,
                             phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->rb_alloc,
                             get_Qm(phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->mcs),
                             1,
                             num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
                       0,
                       subframe<<1);

      stop_meas(&phy_vars_eNB->dlsch_scrambling_stats);

      start_meas(&phy_vars_eNB->dlsch_modulation_stats);
1390

Raymond Knopp's avatar
 
Raymond Knopp committed
1391
      re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
1392 1393 1394 1395 1396 1397 1398 1399 1400
                                      AMP,
                                      subframe,
                                      &phy_vars_eNB->lte_frame_parms,
                                      num_pdcch_symbols,
                                      phy_vars_eNB->dlsch_eNB_SI,
                                      (LTE_eNB_DLSCH_t *)NULL);
      stop_meas(&phy_vars_eNB->dlsch_modulation_stats);
    }

1401
#ifdef PHY_ABSTRACTION
Raymond Knopp's avatar
 
Raymond Knopp committed
1402
    else {
1403
      start_meas(&phy_vars_eNB->dlsch_encoding_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1404
      dlsch_encoding_emul(phy_vars_eNB,
1405 1406 1407
                          DLSCH_pdu,
                          phy_vars_eNB->dlsch_eNB_SI);
      stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1408
    }
1409

1410
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1411
    phy_vars_eNB->dlsch_eNB_SI->active = 0;
1412

Raymond Knopp's avatar
 
Raymond Knopp committed
1413
  }
Lionel Gauthier's avatar
Lionel Gauthier committed
1414

Raymond Knopp's avatar
 
Raymond Knopp committed
1415 1416
  // Check for RA activity
  if (phy_vars_eNB->dlsch_eNB_ra->active == 1) {
1417
#ifdef DEBUG_PHY_PROC
1418
    LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d, subframe %d, RA active, filling RAR:\n",
1419
          phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe);
1420 1421
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1422
    input_buffer_length = phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->TBS/8;
1423

1424
    int16_t crnti = mac_xface->fill_rar(phy_vars_eNB->Mod_id,
1425 1426 1427 1428 1429
                                        phy_vars_eNB->CC_id,
                                        phy_vars_eNB->proc[sched_subframe].frame_tx,
                                        dlsch_input_buffer,
                                        phy_vars_eNB->lte_frame_parms.N_RB_UL,
                                        input_buffer_length);
Raymond Knopp's avatar
 
Raymond Knopp committed
1430 1431 1432 1433 1434
    /*
      for (i=0;i<input_buffer_length;i++)
      LOG_T(PHY,"%x.",dlsch_input_buffer[i]);
      LOG_T(PHY,"\n");
    */
kaltenbe's avatar
kaltenbe committed
1435 1436 1437 1438
    if (crnti!=0) 
      UE_id = add_ue(crnti,phy_vars_eNB);
    else 
      UE_id = -1;
1439

Raymond Knopp's avatar
 
Raymond Knopp committed
1440 1441 1442 1443
    if (UE_id==-1) {
      LOG_W(PHY,"[eNB] Max user count reached.\n");
      //mac_xface->macphy_exit("[PHY][eNB] Max user count reached.\n");
      mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
1444 1445 1446 1447
                                phy_vars_eNB->CC_id,
                                phy_vars_eNB->proc[sched_subframe].frame_tx,
                                crnti);
    } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1448 1449 1450 1451 1452
      phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE;
      // Initialize indicator for first SR (to be cleared after ConnectionSetup is acknowledged)
      phy_vars_eNB->first_sr[(uint32_t)UE_id] = 1;

      generate_eNB_ulsch_params_from_rar(dlsch_input_buffer,
1453 1454 1455 1456
                                         phy_vars_eNB->proc[sched_subframe].frame_tx,
                                         (subframe),
                                         phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id],
                                         &phy_vars_eNB->lte_frame_parms);
Raymond Knopp's avatar
 
Raymond Knopp committed
1457 1458 1459 1460

      phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 1;

      get_Msg3_alloc(&phy_vars_eNB->lte_frame_parms,
1461 1462 1463 1464
                     subframe,
                     phy_vars_eNB->proc[sched_subframe].frame_tx,
                     &phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
                     &phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
1465
      LOG_D(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n",
1466 1467 1468 1469 1470 1471
            phy_vars_eNB->proc[sched_subframe].frame_tx,
            subframe,
            UE_id,
            phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
            phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);

1472 1473 1474 1475 1476 1477 1478 1479
    /*
      for (i=0; i<input_buffer_length; i++)
	dlsch_input_buffer[i]= (unsigned char) i; //(taus()&0xff);
      
      dlsch_input_buffer[1] = (phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset)>>(2+4); // 7 MSBs of timing advance + divide by 4
      dlsch_input_buffer[2] = ((phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset)<<(4-2))&0xf0;  // 4 LSBs of timing advance + divide by 4
      //LOG_I(PHY,"UE %d: timing_offset = %d\n",UE_id,phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset);
    */
1480 1481

#if defined(SMBV) && !defined(EXMIMO)
1482

Raymond Knopp's avatar
 
Raymond Knopp committed
1483 1484
      // Configures the data source of allocation (allocation is configured by DCI)
      if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
1485
        msg("[SMBV] Frame %3d, Configuring RA payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
1486
        smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), dlsch_input_buffer, input_buffer_length);
Raymond Knopp's avatar
 
Raymond Knopp committed
1487
      }
1488 1489

#endif
1490 1491

#ifdef DEBUG_PHY_PROC
1492
      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",
1493 1494 1495 1496
            phy_vars_eNB->Mod_id,
            phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,input_buffer_length,
            phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
            phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
1497 1498
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1499 1500
      if (abstraction_flag == 0) {

1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
        dlsch_encoding(dlsch_input_buffer,
                       &phy_vars_eNB->lte_frame_parms,
                       num_pdcch_symbols,
                       phy_vars_eNB->dlsch_eNB_ra,
                       phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
                       &phy_vars_eNB->dlsch_rate_matching_stats,
                       &phy_vars_eNB->dlsch_turbo_encoding_stats,
                       &phy_vars_eNB->dlsch_interleaving_stats);

        //  phy_vars_eNB->dlsch_eNB_ra->rnti = RA_RNTI;
        dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,
                         0,
                         phy_vars_eNB->dlsch_eNB_ra,
                         get_G(&phy_vars_eNB->lte_frame_parms,
                               phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->nb_rb,
                               phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->rb_alloc,
                               get_Qm(phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->mcs),
                               1,
                               num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
                         0,
                         subframe<<1);
1522

1523 1524 1525 1526 1527 1528 1529
        re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                                        AMP,
                                        subframe,
                                        &phy_vars_eNB->lte_frame_parms,
                                        num_pdcch_symbols,
                                        phy_vars_eNB->dlsch_eNB_ra,
                                        (LTE_eNB_DLSCH_t *)NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
1530
      }
1531

1532
#ifdef PHY_ABSTRACTION
Raymond Knopp's avatar
 
Raymond Knopp committed
1533
      else {
1534 1535 1536
        dlsch_encoding_emul(phy_vars_eNB,
                            dlsch_input_buffer,
                            phy_vars_eNB->dlsch_eNB_ra);
Raymond Knopp's avatar
 
Raymond Knopp committed
1537
      }
1538

1539
#endif
1540
      LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d subframe %d Deactivating DLSCH RA\n",phy_vars_eNB->Mod_id,
1541 1542 1543
            phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);

#ifdef DEBUG_PHY_PROC
1544
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d, DLSCH (RA) re_allocated = %"PRIu16"\n",phy_vars_eNB->Mod_id,
1545
            phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, re_allocated);
1546 1547
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1548
    } //max user count
1549

Raymond Knopp's avatar
 
Raymond Knopp committed
1550 1551
    phy_vars_eNB->dlsch_eNB_ra->active = 0;
  }
1552

Raymond Knopp's avatar
 
Raymond Knopp committed
1553
  // Now scan UE specific DLSCH
1554 1555
  for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
  {
Raymond Knopp's avatar
 
Raymond Knopp committed
1556
    if ((phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0])&&
1557 1558
        (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&&
        (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 1)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1559 1560
      harq_pid = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid;
      input_buffer_length = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS/8;
1561

1562

1563
      //#ifdef DEBUG_PHY_PROC
1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578
      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",
            phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti,harq_pid,
            phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, input_buffer_length,
            get_G(&phy_vars_eNB->lte_frame_parms,
                  phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
                  phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
                  get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
                  phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
                  num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
            phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
            phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs,
            pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc),
            phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rvidx,
            phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round);
1579
      //#endif
Lionel Gauthier's avatar
Lionel Gauthier committed
1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598
#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")",
        phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,
        input_buffer_length,
        get_G(&phy_vars_eNB->lte_frame_parms,
        		phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
        		phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
        		get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
        		phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
        		num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs,
        pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc),
        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rvidx,
        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1599 1600

      phy_vars_eNB->eNB_UE_stats[(uint8_t)UE_id].dlsch_sliding_cnt++;
1601

Raymond Knopp's avatar
 
Raymond Knopp committed
1602 1603
      if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->harq_processes[harq_pid]->round == 0) {

1604 1605
        phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].dlsch_trials[harq_pid][0]++;

1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620
	if (phy_vars_eNB->mac_enabled==1) {
	  DLSCH_pdu = mac_xface->get_dlsch_sdu(phy_vars_eNB->Mod_id,
					       phy_vars_eNB->CC_id,
					       phy_vars_eNB->proc[sched_subframe].frame_tx,
					       phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti,
					       0);
	  phy_vars_eNB->eNB_UE_stats[UE_id].total_TBS_MAC += phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS;
	}
	else {
	  DLSCH_pdu = DLSCH_pdu_tmp;
	  
	  for (i=0; i<input_buffer_length; i++)
	    DLSCH_pdu[i] = (unsigned char)(taus()&0xff);
	}
	
1621
#if defined(SMBV) && !defined(EXMIMO)
1622 1623 1624

        // Configures the data source of allocation (allocation is configured by DCI)
        if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
1625
          msg("[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
1626 1627 1628 1629
          smbv_configure_datalist_for_user(smbv_fname, UE_id+1, DLSCH_pdu, input_buffer_length);
        }

#endif
1630 1631 1632 1633


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

        for (i=0; i<phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS>>3; i++)
1637
          LOG_T(PHY,"%"PRIx8".",DLSCH_pdu[i]);
1638 1639

        LOG_T(PHY,"\n");
1640 1641
#endif
#endif
1642 1643
      } else {
        phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].dlsch_trials[harq_pid][phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round]++;
1644
#ifdef DEBUG_PHY_PROC
1645 1646
#ifdef DEBUG_DLSCH
        LOG_D(PHY,"[eNB] This DLSCH is a retransmission\n");
1647 1648
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1649
      }
1650

Raymond Knopp's avatar
 
Raymond Knopp committed
1651
      if (abstraction_flag==0) {
1652

1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689
        // 36-212
        start_meas(&phy_vars_eNB->dlsch_encoding_stats);
        dlsch_encoding(DLSCH_pdu,
                       &phy_vars_eNB->lte_frame_parms,
                       num_pdcch_symbols,
                       phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
                       phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
                       &phy_vars_eNB->dlsch_rate_matching_stats,
                       &phy_vars_eNB->dlsch_turbo_encoding_stats,
                       &phy_vars_eNB->dlsch_interleaving_stats);
        stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
        // 36-211
        start_meas(&phy_vars_eNB->dlsch_scrambling_stats);
        dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,
                         0,
                         phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
                         get_G(&phy_vars_eNB->lte_frame_parms,
                               phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
                               phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
                               get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
                               phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
                               num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
                         0,
                         subframe<<1);
        stop_meas(&phy_vars_eNB->dlsch_scrambling_stats);
        start_meas(&phy_vars_eNB->dlsch_modulation_stats);


        re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                                        AMP,
                                        subframe,
                                        &phy_vars_eNB->lte_frame_parms,
                                        num_pdcch_symbols,
                                        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
                                        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][1]);

        stop_meas(&phy_vars_eNB->dlsch_modulation_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1690
      }
1691

1692
#ifdef PHY_ABSTRACTION
Raymond Knopp's avatar
 
Raymond Knopp committed
1693
      else {
1694 1695 1696 1697 1698
        start_meas(&phy_vars_eNB->dlsch_encoding_stats);
        dlsch_encoding_emul(phy_vars_eNB,
                            DLSCH_pdu,
                            phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]);
        stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
Raymond Knopp's avatar
 
Raymond Knopp committed
1699
      }
1700

1701
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1702
      phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active = 0;
1703

Raymond Knopp's avatar
 
Raymond Knopp committed
1704 1705
      //mac_xface->macphy_exit("first dlsch transmitted\n");
    }
Lionel Gauthier's avatar
Lionel Gauthier committed
1706

Raymond Knopp's avatar
 
Raymond Knopp committed
1707
    else if ((phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0])&&
1708 1709 1710
             (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&&
             (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 0)) {

Raymond Knopp's avatar
 
Raymond Knopp committed
1711 1712
      // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
      phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->subframe_tx[subframe]=0;
1713
#ifdef DEBUG_PHY_PROC
Raymond Knopp's avatar
 
Raymond Knopp committed
1714
      //LOG_D(PHY,"[eNB %d] DCI: Clearing subframe_tx for subframe %d, UE %d\n",phy_vars_eNB->Mod_id,subframe,UE_id);
1715
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1716
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1717
  }
1718

1719 1720


Raymond Knopp's avatar
 
Raymond Knopp committed
1721
  // if we have PHICH to generate
1722 1723 1724
  //    printf("[PHY][eNB] Frame %d subframe %d Checking for phich\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
  if (is_phich_subframe(&phy_vars_eNB->lte_frame_parms,subframe))
  {
Raymond Knopp's avatar
 
Raymond Knopp committed
1725
    generate_phich_top(phy_vars_eNB,
1726 1727 1728 1729
                       sched_subframe,
                       AMP,
                       0,
                       abstraction_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
1730
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1731

1732 1733


1734
#ifdef EMOS
jiangx's avatar
jiangx committed
1735
  phy_procedures_emos_eNB_TX(subframe, phy_vars_eNB);
1736
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1737

1738
#if !(defined(EXMIMO) || defined(OAI_USRP) || defined (CPRIGW))
1739 1740 1741

  if (abstraction_flag==0)
  {
Raymond Knopp's avatar
 
Raymond Knopp committed
1742 1743
    start_meas(&phy_vars_eNB->ofdm_mod_stats);
    do_OFDM_mod(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
1744 1745 1746
                phy_vars_eNB->lte_eNB_common_vars.txdata[0],
                phy_vars_eNB->proc[sched_subframe].frame_tx,subframe<<1,
                &phy_vars_eNB->lte_frame_parms);
Raymond Knopp's avatar
 
Raymond Knopp committed
1747
    do_OFDM_mod(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
1748 1749 1750
                phy_vars_eNB->lte_eNB_common_vars.txdata[0],
                phy_vars_eNB->proc[sched_subframe].frame_tx,1+(subframe<<1),
                &phy_vars_eNB->lte_frame_parms);
Raymond Knopp's avatar
 
Raymond Knopp committed
1751 1752
    stop_meas(&phy_vars_eNB->ofdm_mod_stats);
  }
1753

Raymond Knopp's avatar
 
Raymond Knopp committed
1754
#endif
1755

1756
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,0);
1757
  stop_meas(&phy_vars_eNB->phy_proc_tx);
1758 1759


1760 1761
}

1762 1763
void process_Msg3(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t UE_id, uint8_t harq_pid)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
1764
  // this prepares the demodulation of the first PUSCH of a new user, containing Msg3
1765

Raymond Knopp's avatar
 
Raymond Knopp committed
1766
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1767
  int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1768

Raymond Knopp's avatar
 
Raymond Knopp committed
1769
  LOG_D(PHY,"[eNB %d][RAPROC] frame %d : subframe %d : process_Msg3 UE_id %d (active %d, subframe %d, frame %d)\n",
1770 1771 1772 1773 1774
        phy_vars_eNB->Mod_id,
        frame,subframe,
        UE_id,phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active,
        phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe,
        phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame);
1775
  phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 0;
1776 1777

  if ((phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active == 1) &&
Raymond Knopp's avatar
 
Raymond Knopp committed
1778
      (phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe == subframe) &&
1779
      (phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame == (uint32_t)frame))   {
1780

1781
    //    harq_pid = 0;
1782

1783 1784 1785
    phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 0;
    phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 1;
    phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag=1;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1786
    LOG_D(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Setting subframe_scheduling_flag (Msg3) for UE %d\n",
1787 1788
          phy_vars_eNB->Mod_id,
          frame,subframe,UE_id);
1789 1790 1791 1792 1793 1794 1795 1796 1797
  }
}


// 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

1798 1799 1800 1801 1802 1803 1804 1805
void process_HARQ_feedback(uint8_t UE_id,
                           uint8_t sched_subframe,
                           PHY_VARS_eNB *phy_vars_eNB,
                           uint8_t pusch_flag,
                           uint8_t *pucch_payload,
                           uint8_t pucch_sel,
                           uint8_t SR_payload)
{
1806

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1807
  uint8_t dl_harq_pid[8],dlsch_ACK[8],dl_subframe;
1808 1809
  LTE_eNB_DLSCH_t *dlsch             =  phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0];
  LTE_eNB_UE_stats *ue_stats         =  &phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id];
1810
  LTE_DL_eNB_HARQ_t *dlsch_harq_proc;
1811
  uint8_t subframe_m4,M,m;
1812 1813
  int mp;
  int all_ACKed=1,nb_alloc=0,nb_ACK=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1814 1815
  int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1816
  int harq_pid = subframe2harq_pid( &phy_vars_eNB->lte_frame_parms,frame,subframe);
1817

1818
  if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { //FDD
1819
    subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
1820

1821 1822
    dl_harq_pid[0] = dlsch->harq_ids[subframe_m4];
    M=1;
1823

1824
    if (pusch_flag == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1825
      dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
1826 1827 1828 1829 1830
      if (dlsch->subframe_tx[subframe_m4]==1)
      LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUSCH for subframe %d\n",phy_vars_eNB->Mod_id,
	    frame,dlsch_ACK[0],subframe_m4);
    }
    else {
1831
      dlsch_ACK[0] = pucch_payload[0];
kaltenbe's avatar
kaltenbe committed
1832
      LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUCCH for subframe %d\n",phy_vars_eNB->Mod_id,
1833
	    frame,dlsch_ACK[0],subframe_m4);
kaltenbe's avatar
kaltenbe committed
1834
      /*
1835 1836
      if (dlsch_ACK[0]==0)
	AssertFatal(0,"Exiting on NAK on PUCCH\n");
kaltenbe's avatar
kaltenbe committed
1837
      */
1838
    }
1839

Lionel Gauthier's avatar
Lionel Gauthier committed
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853

#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
1854 1855
  } else { // TDD Handle M=1,2 cases only

1856
    M=ul_ACK_subframe2_M(&phy_vars_eNB->lte_frame_parms,
1857 1858
                         subframe);

1859 1860 1861 1862 1863 1864 1865 1866
    // 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

Raymond Knopp's avatar
 
Raymond Knopp committed
1867
      dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
1868 1869
      dlsch_ACK[1] = (phy_vars_eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode == bundling)
                     ?phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]:phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[1];
1870 1871
      //      printf("UE %d: ACK %d,%d\n",UE_id,dlsch_ACK[0],dlsch_ACK[1]);
    }
1872

1873
    else {  // PUCCH ACK/NAK
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
      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
        //  printf("*** (%d,%d)\n",pucch_payload[0],pucch_payload[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;
        }
1910
      }
1911
    }
1912 1913 1914 1915
  }

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

    for (m=0; m<M; m++) {
1919
      dl_subframe = ul_ACK_subframe2_dl_subframe(&phy_vars_eNB->lte_frame_parms,
1920 1921 1922 1923 1924
                    subframe,
                    m);

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

1927 1928
    if (nb_alloc == nb_ACK)
      all_ACKed = 1;
1929
    else
1930
      all_ACKed = 0;
1931

1932
    //    printf("nb_alloc %d, all_ACKed %d\n",nb_alloc,all_ACKed);
1933 1934 1935
  }


1936
  for (m=0,mp=-1; m<M; m++) {
1937

1938
    dl_subframe = ul_ACK_subframe2_dl_subframe(&phy_vars_eNB->lte_frame_parms,
1939 1940
                  subframe,
                  m);
1941

1942 1943
    if (dlsch->subframe_tx[dl_subframe]==1) {
      if (pusch_flag == 1)
1944
        mp++;
1945
      else
1946
        mp = m;
1947

1948
      dl_harq_pid[m]     = dlsch->harq_ids[dl_subframe];
1949

1950
      if ((pucch_sel != 2)&&(pusch_flag == 0)) { // multiplexing
1951 1952 1953 1954
        if ((SR_payload == 1)&&(all_ACKed == 1))
          dlsch_ACK[m] = 1;
        else
          dlsch_ACK[m] = 0;
1955
      }
1956

1957
      if (dl_harq_pid[m]<dlsch->Mdlharq) {
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
        dlsch_harq_proc = dlsch->harq_processes[dl_harq_pid[m]];
#ifdef DEBUG_PHY_PROC
        LOG_D(PHY,"[eNB %d][PDSCH %x/%d] subframe %d, status %d, round %d (mcs %d, rv %d, TBS %d)\n",phy_vars_eNB->Mod_id,
              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");

1970
#endif
1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981

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

          //    msg("[PHY] eNB %d Process %d is active (%d)\n",phy_vars_eNB->Mod_id,dl_harq_pid[m],dlsch_ACK[m]);
          if ( dlsch_ACK[mp]==0) {
            // Received NAK
#ifdef DEBUG_PHY_PROC
            LOG_D(PHY,"[eNB %d][PDSCH %x/%d] M = %d, m= %d, mp=%d NAK Received in round %d, requesting retransmission\n",phy_vars_eNB->Mod_id,
                  dlsch->rnti,dl_harq_pid[m],M,m,mp,dlsch_harq_proc->round);
1982
#endif
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992

            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++;

1993
            if (dlsch_harq_proc->round == 1/*dlsch->Mdlharq*/) {
1994 1995 1996 1997
              // This was the last round for DLSCH so reset round and increment l2_error counter
#ifdef DEBUG_PHY_PROC
              LOG_W(PHY,"[eNB %d][PDSCH %x/%d] DLSCH retransmissions exhausted, dropping packet\n",phy_vars_eNB->Mod_id,
                    dlsch->rnti,dl_harq_pid[m]);
1998
#endif
Lionel Gauthier's avatar
Lionel Gauthier committed
1999
#if defined(MESSAGE_CHART_GENERATOR_PHY)
2000
              MSC_LOG_EVENT(MSC_PHY_ENB, "0 HARQ DLSCH Failed RNTI %"PRIx16" round %u",
2001 2002
                            dlsch->rnti,
                            dlsch_harq_proc->round);
Lionel Gauthier's avatar
Lionel Gauthier committed
2003
#endif
Lionel Gauthier's avatar
Lionel Gauthier committed
2004

2005 2006 2007
              dlsch_harq_proc->round = 0;
              ue_stats->dlsch_l2_errors[dl_harq_pid[m]]++;
              dlsch_harq_proc->status = SCH_IDLE;
2008
              put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
2009 2010 2011 2012 2013 2014
              dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;
            }
          } else {
#ifdef DEBUG_PHY_PROC
            LOG_D(PHY,"[eNB %d][PDSCH %x/%d] ACK Received in round %d, resetting process\n",phy_vars_eNB->Mod_id,
                  dlsch->rnti,dl_harq_pid[m],dlsch_harq_proc->round);
2015
#endif
2016 2017 2018 2019 2020
            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;
2021
            put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
            dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;

            ue_stats->total_TBS = ue_stats->total_TBS +
                                  phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
            /*
              ue_stats->total_transmitted_bits = ue_stats->total_transmitted_bits +
              phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
            */
          }

          // 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);
2043
#endif
2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065

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


        }
2066
      }
2067
    }
2068 2069 2070 2071
  }
}

void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB,
2072 2073 2074 2075 2076 2077 2078
                      uint8_t UE_id,
                      uint8_t sched_subframe,
                      int16_t *n1_pucch0,
                      int16_t *n1_pucch1,
                      int16_t *n1_pucch2,
                      int16_t *n1_pucch3)
{
2079 2080

  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms;
2081
  uint8_t nCCE0,nCCE1;
2082
  int sf;
Raymond Knopp's avatar
 
Raymond Knopp committed
2083 2084
  int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
2085 2086

  if (frame_parms->frame_type == FDD ) {
2087
    sf = (subframe<4) ? (subframe+6) : (subframe-4);
2088
    //    printf("n1_pucch_eNB: subframe %d, nCCE %d\n",sf,phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf]);
2089

2090 2091
    if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[sf]>0) {
      *n1_pucch0 = frame_parms->pucch_config_common.n1PUCCH_AN + phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf];
2092
      *n1_pucch1 = -1;
2093
    } else {
2094 2095 2096
      *n1_pucch0 = -1;
      *n1_pucch1 = -1;
    }
2097
  } else {
2098

2099 2100 2101
    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
2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150
        /*  if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
          nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6];
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
          }
          else
          *n1_pucch1 = -1;*/

        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5];
          *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

        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9];
          *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;
        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0];
          *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;
        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[4]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[4];
          *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",
              phy_vars_eNB->Mod_id,
              frame,
              subframe,frame_parms->tdd_config);
        return;
2151
      }
2152

2153
      break;
2154

2155 2156
    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)
2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200
        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
          nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6];
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch1 = -1;

        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5];
          *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",
              phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7],phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]);

        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]>0) {
          nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[8];
          *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;

        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[7];
          *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
        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
          nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0];
          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
        } else
          *n1_pucch1 = -1;

        if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
          nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9];
          *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",
              phy_vars_eNB->Mod_id,frame,subframe,frame_parms->tdd_config);
        return;
2201
      }
2202

2203
      break;
2204 2205
    }  // switch tdd_config

2206 2207 2208
    // Don't handle the case M>2
    *n1_pucch2 = -1;
    *n1_pucch3 = -1;
2209 2210 2211
  }
}

2212 2213
void prach_procedures(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t abstraction_flag)
{
2214

2215 2216 2217 2218
  uint16_t preamble_energy_list[64],preamble_delay_list[64];
  uint16_t preamble_max,preamble_energy_max;
  uint16_t i;
  int8_t UE_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2219
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
2220
  int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
2221
  uint8_t CC_id = phy_vars_eNB->CC_id;
2222

2223 2224
  memset(&preamble_energy_list[0],0,64*sizeof(uint16_t));
  memset(&preamble_delay_list[0],0,64*sizeof(uint16_t));
2225

2226
  if (abstraction_flag == 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2227
    LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",phy_vars_eNB->Mod_id, 
2228 2229
          frame,subframe,dB_fixed(signal_energy(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],512)) - phy_vars_eNB->rx_total_gain_eNB_dB);

2230
    //    LOG_I(PHY,"[eNB %d][RAPROC] PRACH: rootSequenceIndex %d, prach_ConfigIndex %d, zeroCorrelationZoneConfig %d, highSpeedFlag %d, prach_FreqOffset %d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset);
2231

2232
    rx_prach(phy_vars_eNB,
2233 2234 2235 2236 2237 2238 2239 2240
             subframe,
             preamble_energy_list,
             preamble_delay_list,
             frame,
             0);
  } else {
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {

2241
      LOG_D(PHY,"[RAPROC] UE_id %d (%p), generate_prach %d, UE RSI %d, eNB RSI %d preamble index %d\n",
2242 2243 2244 2245 2246
            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,
            phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex,
            PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex);

Raymond Knopp's avatar
 
Raymond Knopp committed
2247
      if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach==1) &&
2248 2249 2250 2251 2252
          (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex ==
           phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex) ) {
        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;

2253
      }
2254
    }
2255
  }
2256

2257 2258 2259
  preamble_energy_max = preamble_energy_list[0];
  preamble_max = 0;

2260
  for (i=1; i<64; i++) {
2261 2262 2263 2264
    if (preamble_energy_max < preamble_energy_list[i]) {
      preamble_energy_max = preamble_energy_list[i];
      preamble_max = i;
    }
2265 2266 2267
  }

#ifdef DEBUG_PHY_PROC
2268
  LOG_D(PHY,"[RAPROC] Most likely preamble %d, energy %d dB delay %d\n",
2269 2270 2271
        preamble_max,
        preamble_energy_list[preamble_max],
        preamble_delay_list[preamble_max]);
2272 2273
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2274
  if (preamble_energy_list[preamble_max] > 580) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2275 2276 2277 2278 2279 2280 2281 2282
    /*
    write_output("prach_ifft0.m","prach_t0",prach_ifft[0],2048,1,1);
    write_output("prach_rx0.m","prach_rx0",&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],6144+792,1,1);
    write_output("prach_rxF0.m","prach_rxF0",phy_vars_eNB->lte_eNB_prach_vars.rxsigF[0],24576,1,1);

    mac_xface->macphy_exit("Exiting for PRACH debug\n");
    */

2283
    UE_id = find_next_ue_index(phy_vars_eNB);
2284

2285
    if (UE_id>=0) {
2286 2287 2288
      phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits
      //phy_vars_eNb->eNB_UE_stats[(uint32_t)UE_id].mode = PRACH;
      phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].sector = 0;
2289
      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",
2290
            phy_vars_eNB->Mod_id,
2291
            phy_vars_eNB->CC_id,
2292 2293
            frame,
            subframe,
2294
	    UE_id,
2295 2296 2297 2298
            preamble_max,
            preamble_energy_max/10,
            preamble_energy_max%10,
            preamble_delay_list[preamble_max]);
2299 2300

      if (phy_vars_eNB->mac_enabled==1) {
2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320
        uint8_t update_TA=4;

        switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
        case 6:
          update_TA = 16;
          break;

        case 25:
          update_TA = 4;
          break;

        case 50:
          update_TA = 2;
          break;

        case 100:
          update_TA = 1;
          break;
        }

2321
      mac_xface->initiate_ra_proc(phy_vars_eNB->Mod_id,
2322 2323 2324
                                  phy_vars_eNB->CC_id,
                                  frame,
                                  preamble_max,
2325
                                  preamble_delay_list[preamble_max]*update_TA,
Raymond Knopp's avatar
 
Raymond Knopp committed
2326
				  0,subframe,0);
2327 2328
      }      

2329
    } else {
2330
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 RA Failed add user, too many");
2331 2332
      LOG_I(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Unable to add user, max user count reached\n",
            phy_vars_eNB->Mod_id,frame, subframe);
2333
    }
2334 2335 2336
  }
}

Raymond Knopp's avatar
 
Raymond Knopp committed
2337
void ulsch_decoding_procedures(unsigned char subframe, unsigned int i, PHY_VARS_eNB *phy_vars_eNB, unsigned char abstraction_flag)
2338
{
2339 2340 2341 2342
  UNUSED(subframe);
  UNUSED(i);
  UNUSED(phy_vars_eNB);
  UNUSED(abstraction_flag);
2343 2344 2345 2346
  LOG_D(PHY,"ulsch_decoding_procedures not yet implemented. should not be called");
}


Raymond Knopp's avatar
 
Raymond Knopp committed
2347

Lionel Gauthier's avatar
Lionel Gauthier committed
2348
void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,const uint8_t abstraction_flag,const relaying_type_t r_type)
2349
{
2350
  //RX processing
2351
  UNUSED(r_type);
2352
  uint32_t l, ret=0,i,j,k;
2353
  uint32_t harq_pid, harq_idx, round;
2354
  uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0};
2355 2356 2357
  int16_t n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3;
  uint8_t do_SR = 0;
  uint8_t pucch_sel = 0;
2358
  int32_t metric0=0,metric1=0,metric0_SR=0;
2359 2360
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
2361
  uint8_t nPRS;
2362 2363
  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms;
  int sync_pos;
2364 2365
  uint16_t rnti=0;
  uint8_t access_mode;
2366
  int num_active_cba_groups;
Lionel Gauthier's avatar
Lionel Gauthier committed
2367 2368 2369 2370
  const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
  const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;

  AssertFatal(sched_subframe < NUM_ENB_THREADS, "Bad sched_subframe %d", sched_subframe);
2371

2372
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1);
2373
  start_meas(&phy_vars_eNB->phy_proc_rx);
2374
#ifdef DEBUG_PHY_PROC
Raymond Knopp's avatar
 
Raymond Knopp committed
2375
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,frame, subframe);
2376
#endif
2377

2378

2379 2380 2381 2382 2383
  phy_vars_eNB->rb_mask_ul[0]=0;
  phy_vars_eNB->rb_mask_ul[1]=0;
  phy_vars_eNB->rb_mask_ul[2]=0;
  phy_vars_eNB->rb_mask_ul[3]=0;

2384
  if (abstraction_flag == 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2385 2386
    remove_7_5_kHz(phy_vars_eNB,subframe<<1);
    remove_7_5_kHz(phy_vars_eNB,(subframe<<1)+1);
2387
  }
2388

2389
  // check if we have to detect PRACH first
Raymond Knopp's avatar
 
Raymond Knopp committed
2390
  if (is_prach_subframe(&phy_vars_eNB->lte_frame_parms,frame,subframe)>0) {
2391
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2392
    prach_procedures(phy_vars_eNB,sched_subframe,abstraction_flag);
2393
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
2394
  }
2395

2396
  if (abstraction_flag == 0) {
2397 2398 2399 2400
    start_meas(&phy_vars_eNB->ofdm_demod_stats);

    for (l=0; l<phy_vars_eNB->lte_frame_parms.symbols_per_tti/2; l++) {

Raymond Knopp's avatar
 
Raymond Knopp committed
2401
      slot_fep_ul(&phy_vars_eNB->lte_frame_parms,
2402 2403 2404 2405 2406 2407
                  &phy_vars_eNB->lte_eNB_common_vars,
                  l,
                  subframe<<1,
                  0,
                  0
                 );
Raymond Knopp's avatar
 
Raymond Knopp committed
2408
      slot_fep_ul(&phy_vars_eNB->lte_frame_parms,
2409 2410 2411 2412 2413 2414
                  &phy_vars_eNB->lte_eNB_common_vars,
                  l,
                  (subframe<<1)+1,
                  0,
                  0
                 );
2415
    }
2416 2417

    stop_meas(&phy_vars_eNB->ofdm_demod_stats);
2418
  }
2419

2420 2421
  // Check for active processes in current subframe
  harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,
2422 2423 2424
                               frame,subframe);
  // reset the cba flag used for collision detection
  for (i=0; i < NUM_MAX_CBA_GROUP; i++) {
2425
    phy_vars_eNB->cba_last_reception[i]=0;
2426
  }
2427 2428 2429

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

2430 2431 2432 2433 2434
    if (phy_vars_eNB->mac_enabled==1) {
      if (phy_vars_eNB->eNB_UE_stats[i].mode == RA_RESPONSE) {
	process_Msg3(phy_vars_eNB,sched_subframe,i,harq_pid);
      }
    }
2435

2436

2437
    phy_vars_eNB->pusch_stats_rb[i][(frame*10)+subframe] = -63;
2438
    phy_vars_eNB->pusch_stats_round[i][(frame*10)+subframe] = 0;
2439
    phy_vars_eNB->pusch_stats_mcs[i][(frame*10)+subframe] = -63;
Raymond Knopp's avatar
 
Raymond Knopp committed
2440

2441
    if ((phy_vars_eNB->ulsch_eNB[i]) &&
2442 2443 2444
        (phy_vars_eNB->ulsch_eNB[i]->rnti>0) &&
        (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag==1)) {

2445
      round = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round;
2446

2447 2448 2449 2450 2451 2452
      for (int rb=0;
           rb<=phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb;
	   rb++) {
	int rb2 = rb+phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb;
	phy_vars_eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
      }
2453
#ifdef DEBUG_PHY_PROC
2454
      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Scheduling PUSCH/ULSCH Reception for rnti %x (UE_id %d)\n",
2455
            phy_vars_eNB->Mod_id,harq_pid,
2456
            frame,subframe,phy_vars_eNB->ulsch_eNB[i]->rnti,i);
2457
#endif
2458

2459
#ifdef DEBUG_PHY_PROC
2460 2461 2462 2463 2464 2465 2466

      if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for Msg3 in Sector %d\n",
              phy_vars_eNB->Mod_id,
              frame,
              subframe,
              phy_vars_eNB->eNB_UE_stats[i].sector);
2467
      } else {
2468
        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d Mode %s\n",
2469 2470 2471 2472
              phy_vars_eNB->Mod_id,
              frame,
              subframe,
              i,
2473
              mode_string[phy_vars_eNB->eNB_UE_stats[i].mode]);
2474
      }
2475

2476 2477
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2478
      nPRS = phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
2479

2480 2481
      phy_vars_eNB->ulsch_eNB[i]->cyclicShift = (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2 + phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
          nPRS)%12;
2482

Raymond Knopp's avatar
 
Raymond Knopp committed
2483
      if (frame_parms->frame_type == FDD ) {
2484 2485 2486 2487 2488 2489 2490
        int sf = (subframe<4) ? (subframe+6) : (subframe-4);

        if (phy_vars_eNB->dlsch_eNB[i][0]->subframe_tx[sf]>0) { // we have downlink transmission
          phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 1;
        } else {
          phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 0;
        }
2491
      }
Raymond Knopp's avatar
Raymond Knopp committed
2492

2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508
      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",
            phy_vars_eNB->Mod_id,harq_pid,frame,subframe,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->mcs,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rvidx,
            phy_vars_eNB->ulsch_eNB[i]->cyclicShift,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2,
            phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
            nPRS,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK);
2509 2510 2511
      phy_vars_eNB->pusch_stats_rb[i][(frame*10)+subframe] = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb;
      phy_vars_eNB->pusch_stats_round[i][(frame*10)+subframe] = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round;
      phy_vars_eNB->pusch_stats_mcs[i][(frame*10)+subframe] = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->mcs;
2512 2513
      start_meas(&phy_vars_eNB->ulsch_demodulation_stats);

2514
      if (abstraction_flag==0) {
2515 2516 2517 2518 2519 2520
        rx_ulsch(phy_vars_eNB,
                 sched_subframe,
                 phy_vars_eNB->eNB_UE_stats[i].sector,  // this is the effective sector id
                 i,
                 phy_vars_eNB->ulsch_eNB,
                 0);
2521
      }
2522

2523
#ifdef PHY_ABSTRACTION
2524
      else {
2525 2526 2527 2528
        rx_ulsch_emul(phy_vars_eNB,
                      subframe,
                      phy_vars_eNB->eNB_UE_stats[i].sector,  // this is the effective sector id
                      i);
2529
      }
2530

2531
#endif
2532
      stop_meas(&phy_vars_eNB->ulsch_demodulation_stats);
2533 2534


2535
      start_meas(&phy_vars_eNB->ulsch_decoding_stats);
2536

2537
      if (abstraction_flag == 0) {
2538 2539 2540 2541 2542
        ret = ulsch_decoding(phy_vars_eNB,
                             i,
                             sched_subframe,
                             0, // control_only_flag
                             phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI,
2543
			     0);//phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb>20 ? 1 : 0);
2544
      }
2545

2546
#ifdef PHY_ABSTRACTION
2547
      else {
2548 2549 2550 2551
        ret = ulsch_decoding_emul(phy_vars_eNB,
                                  sched_subframe,
                                  i,
                                  &rnti);
2552
      }
2553

2554
#endif
2555
      stop_meas(&phy_vars_eNB->ulsch_decoding_stats);
2556

2557
      //#ifdef DEBUG_PHY_PROC
Raymond Knopp's avatar
 
Raymond Knopp committed
2558
      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",
2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570
            phy_vars_eNB->Mod_id,harq_pid,
            frame,subframe,
            phy_vars_eNB->ulsch_eNB[i]->rnti,
            dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
            dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
            phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
            phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
            phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
            phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
            ret);
2571

2572

2573 2574
      //compute the expected ULSCH RX power (for the stats)
      phy_vars_eNB->ulsch_eNB[(uint32_t)i]->harq_processes[harq_pid]->delta_TF =
2575
        get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
2576

2577
      //dump_ulsch(phy_vars_eNB, sched_subframe, i);
2578

2579
      phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
2580
#ifdef DEBUG_PHY_PROC
Raymond Knopp's avatar
 
Raymond Knopp committed
2581
      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d Clearing subframe_scheduling_flag\n",
2582
            phy_vars_eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid);
2583
#endif
2584
      phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag=0;
2585

Raymond Knopp's avatar
 
Raymond Knopp committed
2586
      if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) {
2587
#ifdef DEBUG_PHY_PROC
2588 2589
        //if (((phy_vars_eNB->proc[sched_subframe].frame_tx%10) == 0) || (phy_vars_eNB->proc[sched_subframe].frame_tx < 50))
        print_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,phy_vars_eNB->lte_frame_parms.N_RB_DL);
2590
#endif
2591 2592 2593 2594 2595 2596
        extract_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,
                    phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,
                    &phy_vars_eNB->eNB_UE_stats[i],
                    phy_vars_eNB->lte_frame_parms.N_RB_DL,
                    &rnti, &access_mode);
        phy_vars_eNB->eNB_UE_stats[i].rank = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0];
2597
      }
2598

2599
      if (ret == (1+MAX_TURBO_ITERATIONS)) {
2600

2601 2602 2603 2604 2605 2606 2607 2608
        phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++;

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

        if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
2609
          LOG_D(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d/%d\n",
2610
                phy_vars_eNB->Mod_id,
2611
                phy_vars_eNB->CC_id,
2612 2613 2614 2615
                frame,subframe, i,
                phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
                phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx-1);

2616
	  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",
2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629
		phy_vars_eNB->Mod_id,harq_pid,
		frame,subframe,
		phy_vars_eNB->ulsch_eNB[i]->rnti,
		dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
		dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
		phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
		phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
		phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
		phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
		phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
		phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
		ret);

2630 2631
          if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round ==
              phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx) {
2632
            LOG_D(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n",
2633 2634
                  phy_vars_eNB->Mod_id, i);
            phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
2635 2636 2637 2638 2639 2640
	    if (phy_vars_eNB->mac_enabled==1) {
	      mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
					phy_vars_eNB->CC_id,
					frame,
					phy_vars_eNB->eNB_UE_stats[i].crnti);
	    }
2641
            mac_phy_remove_ue(phy_vars_eNB->Mod_id,phy_vars_eNB->eNB_UE_stats[i].crnti);
2642

2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664
            phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
            //phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 0;

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

            get_Msg3_alloc_ret(&phy_vars_eNB->lte_frame_parms,
                               subframe,
                               frame,
                               &phy_vars_eNB->ulsch_eNB[i]->Msg3_frame,
                               &phy_vars_eNB->ulsch_eNB[i]->Msg3_subframe);
          }/*

    LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
    harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
    for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++)
      printf("%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]);
    printf("\n");
     */
          //    dump_ulsch(phy_vars_eNB,sched_subframe,i);
          //#ifndef EXMIMO_IOT
2665
          LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i);
2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678
          //#else
          //mac_exit_wrapper("Msg3 error");
          //#endif
        } // This is Msg3 error
        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",
                phy_vars_eNB->Mod_id,harq_pid,
                frame,subframe, i,
                phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
                phy_vars_eNB->ulsch_eNB[i]->Mdlharq,
                phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
                phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1]);

Lionel Gauthier's avatar
Lionel Gauthier committed
2679 2680 2681 2682 2683 2684 2685 2686 2687 2688
#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,
            phy_vars_eNB->ulsch_eNB[i]->rnti,harq_pid,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1
            );
#endif
2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713
          /*
          LOG_T(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:\n",frame,subframe,
          harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
          if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0]!=NULL){
            for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++)
              LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]);
            LOG_T(PHY,"\n");
          }
          */


          //    dump_ulsch(phy_vars_eNB,sched_subframe,i);
          //mac_exit_wrapper("ULSCH error");

          if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round== phy_vars_eNB->ulsch_eNB[i]->Mdlharq) {
            LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d ULSCH Mdlharq %d reached\n",
                  phy_vars_eNB->Mod_id,harq_pid,
                  frame,subframe, i,
                  phy_vars_eNB->ulsch_eNB[i]->Mdlharq);

            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round=0;
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active=0;
            phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[harq_pid]++;
            phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors++;
            //dump_ulsch(phy_vars_eNB, sched_subframe, i);
gauthier's avatar
gauthier committed
2714 2715 2716 2717 2718 2719 2720 2721 2722
	    // indicate error to MAC
	    mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
			      phy_vars_eNB->CC_id,
			      frame,subframe,
			      phy_vars_eNB->ulsch_eNB[i]->rnti,
			      NULL,
			      0,
			      harq_pid,
			      &phy_vars_eNB->ulsch_eNB[i]->Msg3_flag);
2723 2724
          }
        }
2725 2726
      }  // ulsch in error
      else {
2727
        if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
2728
	  LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
2729 2730
		phy_vars_eNB->Mod_id,harq_pid,
		frame,subframe);
2731
	  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",
2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744
		phy_vars_eNB->Mod_id,harq_pid,
		frame,subframe,
		phy_vars_eNB->ulsch_eNB[i]->rnti,
		dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
		dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
		phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
		phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
		phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
		phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
		phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
		phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
		ret);
	}
Lionel Gauthier's avatar
Lionel Gauthier committed
2745 2746 2747 2748 2749 2750 2751 2752 2753
#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,
          phy_vars_eNB->ulsch_eNB[i]->rnti,harq_pid
          );
#endif
2754 2755 2756
        for (j=0; j<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; j++)
          //this is the RSSI per RB
          phy_vars_eNB->eNB_UE_stats[i].UL_rssi[j] =
2757
	    
2758 2759 2760 2761 2762 2763
            dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]*
                     (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb*12)/
                     phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) -
            phy_vars_eNB->rx_total_gain_eNB_dB -
            hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
            get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100;
2764 2765 2766 2767 2768 2769
	    
	    /*
            dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]*phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb) -
            phy_vars_eNB->rx_total_gain_eNB_dB -
            hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
            get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100;*/
2770 2771 2772 2773 2774 2775
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0;
        phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0;

        if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
2776
	  if (phy_vars_eNB->mac_enabled==1) {
2777
	  //#ifdef DEBUG_PHY_PROC
2778 2779 2780
          LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n",
                phy_vars_eNB->Mod_id,
                frame,harq_pid,i);
2781
	  //#endif
2782 2783
          mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
                            phy_vars_eNB->CC_id,
2784
                            frame,subframe,
2785 2786 2787 2788 2789 2790
                            phy_vars_eNB->ulsch_eNB[i]->rnti,
                            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
                            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
                            harq_pid,
                            &phy_vars_eNB->ulsch_eNB[i]->Msg3_flag);

2791
          // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
2792 2793 2794 2795 2796 2797
          if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 0 ) {
            phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
            mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
                                      phy_vars_eNB->CC_id,
                                      frame,
                                      phy_vars_eNB->eNB_UE_stats[i].crnti);
2798
            mac_phy_remove_ue(phy_vars_eNB->Mod_id,phy_vars_eNB->eNB_UE_stats[i].crnti);
2799 2800 2801 2802 2803 2804 2805 2806 2807 2808
            phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
          }

          /*
            mac_xface->terminate_ra_proc(phy_vars_eNB->Mod_id,
            frame,
            phy_vars_eNB->ulsch_eNB[i]->rnti,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
          */
2809
	  }
2810

2811 2812
          phy_vars_eNB->eNB_UE_stats[i].mode = PUSCH;
          phy_vars_eNB->ulsch_eNB[i]->Msg3_flag = 0;
2813

2814 2815 2816
	  //#ifdef DEBUG_PHY_PROC
	    LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",phy_vars_eNB->Mod_id,frame,subframe,i);
	    //#endif //DEBUG_PHY_PROC
2817

2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843
          for (k=0; k<8; k++) { //harq_processes
            for (j=0; j<phy_vars_eNB->dlsch_eNB[i][0]->Mdlharq; j++) {
              phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0;
              phy_vars_eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0;
              phy_vars_eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0;
            }

            phy_vars_eNB->eNB_UE_stats[i].dlsch_l2_errors[k]=0;
            phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[k]=0;
            phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;

            for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->Mdlharq; j++) {
              phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[k][j]=0;
              phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
              phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[k][j]=0;
              phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[k][j]=0;
            }
          }

          phy_vars_eNB->eNB_UE_stats[i].dlsch_sliding_cnt=0;
          phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK_round0=0;
          phy_vars_eNB->eNB_UE_stats[i].dlsch_mcs_offset=0;

          //mac_xface->macphy_exit("Mode PUSCH. Exiting.\n");
        } else {

2844 2845
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
2846 2847 2848 2849 2850 2851 2852
          LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
                harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);

          for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++)
            LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]);

          LOG_T(PHY,"\n");
2853 2854
#endif
#endif
2855 2856
          //dump_ulsch(phy_vars_eNB,sched_subframe,i);

2857

2858
	  if (phy_vars_eNB->mac_enabled==1) {
2859 2860 2861
          //    if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->calibration_flag == 0) {
          mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
                            phy_vars_eNB->CC_id,
2862
                            frame,subframe,
2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874
                            phy_vars_eNB->ulsch_eNB[i]->rnti,
                            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
                            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
                            harq_pid,
                            NULL);
          //}
          /*
            else {
            // Retrieve calibration information and do whatever
            LOG_D(PHY,"[eNB][Auto-Calibration] Frame %d, Subframe %d : ULSCH PDU (RX) %d bytes\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
            }
          */
2875 2876
#ifdef LOCALIZATION
          start_meas(&phy_vars_eNB->localization_stats);
2877 2878 2879 2880
          aggregate_eNB_UE_localization_stats(phy_vars_eNB,
                                              i,
                                              frame,
                                              subframe,
2881 2882
                                              get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 1)/100);
          stop_meas(&phy_vars_eNB->localization_stats);
2883
#endif
2884

2885
	  }
2886 2887 2888 2889 2890 2891 2892 2893 2894
        }

        // estimate timing advance for MAC
        if (abstraction_flag == 0) {
          sync_pos = lte_est_timing_advance_pusch(phy_vars_eNB,i,sched_subframe);
          phy_vars_eNB->eNB_UE_stats[i].timing_advance_update = sync_pos - phy_vars_eNB->lte_frame_parms.nb_prefix_samples/4; //to check
        }

#ifdef DEBUG_PHY_PROC
2895
        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: user %d: timing advance = %d\n",
2896 2897
              phy_vars_eNB->Mod_id,
              frame, subframe,
2898
              i,
2899
              phy_vars_eNB->eNB_UE_stats[i].timing_advance_update);
2900
#endif
2901

2902

2903
      }  // ulsch not in error
2904

2905
      // process HARQ feedback
2906
#ifdef DEBUG_PHY_PROC
2907
      LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d, Processing HARQ feedback for UE %d (after PUSCH)\n",phy_vars_eNB->Mod_id,
2908 2909 2910
            phy_vars_eNB->dlsch_eNB[i][0]->rnti,
            frame,subframe,
            i);
2911 2912
#endif
      process_HARQ_feedback(i,
2913 2914 2915 2916 2917 2918 2919
                            sched_subframe,
                            phy_vars_eNB,
                            1, // pusch_flag
                            0,
                            0,
                            0);

Raymond Knopp's avatar
 
Raymond Knopp committed
2920
#ifdef DEBUG_PHY_PROC
2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931
      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",
            phy_vars_eNB->Mod_id,frame,subframe,
            phy_vars_eNB->eNB_UE_stats[i].sector,
            harq_pid,
            i,
            ret,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status,
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
            phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
            phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[harq_pid],
            phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2932
#endif
2933 2934 2935 2936 2937 2938 2939
      
      // dump stats to VCD
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_MCS0+harq_pid,phy_vars_eNB->pusch_stats_mcs[0][(frame*10)+subframe]);
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RB0+harq_pid,phy_vars_eNB->pusch_stats_rb[0][(frame*10)+subframe]);
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_ROUND0+harq_pid,phy_vars_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(phy_vars_eNB->lte_eNB_pusch_vars[0]->ulsch_power[0]));
    } // ulsch_eNB[0] && ulsch_eNB[0]->rnti>0 && ulsch_eNB[0]->subframe_scheduling_flag == 1
2940 2941

    else if ((phy_vars_eNB->dlsch_eNB[i][0]) &&
2942
             (phy_vars_eNB->dlsch_eNB[i][0]->rnti>0)) { // check for PUCCH
2943 2944

      // check SR availability
Raymond Knopp's avatar
 
Raymond Knopp committed
2945
      do_SR = is_SR_subframe(phy_vars_eNB,i,sched_subframe);
2946
      //      do_SR = 0;
2947

2948 2949 2950
      // Now ACK/NAK
      // First check subframe_tx flag for earlier subframes
      get_n1_pucch_eNB(phy_vars_eNB,
2951 2952 2953 2954 2955 2956
                       i,
                       sched_subframe,
                       &n1_pucch0,
                       &n1_pucch1,
                       &n1_pucch2,
                       &n1_pucch3);
2957 2958

      LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d, subframe %d Checking for PUCCH (%d,%d,%d,%d) SR %d\n",
2959 2960 2961
            phy_vars_eNB->Mod_id,phy_vars_eNB->dlsch_eNB[i][0]->rnti,
            frame,subframe,
            n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,do_SR);
2962 2963

      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
2964 2965 2966
      } else {
        // otherwise we have some PUCCH detection to do

2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994
	// Null out PUCCH PRBs for noise measurement
	switch(phy_vars_eNB->lte_frame_parms.N_RB_UL) {
	case 6:
	  phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<5)); //position 5
	  break;
	case 15:
	  phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<14)); // position 14
	  break;
	case 25:
	  phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<24)); // position 24
	  break;
	case 50:
	  phy_vars_eNB->rb_mask_ul[0] |= 0x1;
	  phy_vars_eNB->rb_mask_ul[1] |= (1<<17); // position 49 (49-32)
	  break;
	case 75:
	  phy_vars_eNB->rb_mask_ul[0] |= 0x1;
	  phy_vars_eNB->rb_mask_ul[2] |= (1<<10); // position 74 (74-64)
	  break;
	case 100:
	  phy_vars_eNB->rb_mask_ul[0] |= 0x1;
	  phy_vars_eNB->rb_mask_ul[3] |= (1<<3); // position 99 (99-96)
	  break;
	default:
	  LOG_E(PHY,"Unknown number for N_RB_UL %d\n",phy_vars_eNB->lte_frame_parms.N_RB_UL);
	  break;
	}

2995 2996 2997 2998
        if (do_SR == 1) {
          phy_vars_eNB->eNB_UE_stats[i].sr_total++;

          if (abstraction_flag == 0)
2999 3000 3001 3002 3003 3004 3005 3006 3007
            metric0_SR = rx_pucch(phy_vars_eNB,
				  pucch_format1,
				  i,
				  phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,
				  0, // n2_pucch
				  0, // shortened format, should be use_srs flag, later
				  &SR_payload,
				  subframe,
				  PUCCH1_THRES);
3008

3009
#ifdef PHY_ABSTRACTION
3010
          else {
3011 3012 3013 3014 3015 3016
            metric0_SR = rx_pucch_emul(phy_vars_eNB,
				       i,
				       pucch_format1,
				       0,
				       &SR_payload,
				       sched_subframe);
3017 3018 3019 3020
            LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR (UE SR %d/%d)\n",phy_vars_eNB->Mod_id,
                  phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe,SR_payload,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex);
          }

3021 3022
#endif

3023 3024 3025 3026 3027 3028
          if (SR_payload == 1) {
            LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",phy_vars_eNB->Mod_id,
                  phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe);
            phy_vars_eNB->eNB_UE_stats[i].sr_received++;

            if (phy_vars_eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
3029 3030 3031
              /* is this test necessary? */
              if (phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status != SCH_IDLE)
                put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], 0);
3032 3033 3034 3035 3036 3037 3038 3039
              phy_vars_eNB->first_sr[i] = 0;
              phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->round=0;
              phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status=SCH_IDLE;
              LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
                    phy_vars_eNB->Mod_id,
                    phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe);
            }

3040 3041 3042 3043 3044 3045
	    if (phy_vars_eNB->mac_enabled==1) {
	      mac_xface->SR_indication(phy_vars_eNB->Mod_id,
				       phy_vars_eNB->CC_id,
				       frame,
				       phy_vars_eNB->dlsch_eNB[i][0]->rnti,subframe);
	    }
3046 3047 3048 3049 3050 3051
          }
        }// do_SR==1

        if ((n1_pucch0==-1) && (n1_pucch1==-1)) { // just check for SR
        } else if (phy_vars_eNB->lte_frame_parms.frame_type==FDD) { // FDD
          // if SR was detected, use the n1_pucch from SR, else use n1_pucch0
3052
	  //          n1_pucch0 = (SR_payload==1) ? phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex:n1_pucch0;
3053

3054 3055
	  LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,SR_payload);

3056 3057 3058 3059
          if (abstraction_flag == 0) {



3060 3061 3062 3063 3064
            metric0 = rx_pucch(phy_vars_eNB,
                               pucch_format1a,
                               i,
                               (uint16_t)n1_pucch0,
                               0, //n2_pucch
3065
                               0, // shortened format
3066 3067 3068
                               pucch_payload0,
                               subframe,
                               PUCCH1a_THRES);
3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080

            if (metric0 < metric0_SR)
	      metric0=rx_pucch(phy_vars_eNB,
			       pucch_format1a,
			       i,
			       phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,
			       0, //n2_pucch
			       0, // shortened format
			       pucch_payload0,
			       subframe,
			       PUCCH1a_THRES);
	  }
3081
          else {
3082
#ifdef PHY_ABSTRACTION
3083 3084 3085 3086 3087
            metric0 = rx_pucch_emul(phy_vars_eNB,i,
                                    pucch_format1a,
                                    0,
                                    pucch_payload0,
                                    subframe);
3088
#endif
3089 3090 3091 3092 3093 3094 3095 3096
          }

#ifdef DEBUG_PHY_PROC
          LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
                phy_vars_eNB->Mod_id,
                phy_vars_eNB->dlsch_eNB[i][0]->rnti,
                frame,subframe,
                pucch_payload0[0],metric0);
3097 3098
#endif

3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128
          process_HARQ_feedback(i,sched_subframe,phy_vars_eNB,
                                0,// pusch_flag
                                pucch_payload0,
                                2,
                                SR_payload);

        } // FDD
        else {  //TDD

          bundling_flag = phy_vars_eNB->pucch_config_dedicated[i].tdd_AckNackFeedbackMode;

          // fix later for 2 TB case and format1b

          if ((frame_parms->frame_type==FDD) ||
              (bundling_flag==bundling)    ||
              ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe!=2)||(subframe!=7)))) {
            format = pucch_format1a;
            //      msg("PUCCH 1a\n");
          } else {
            format = pucch_format1b;
            //      msg("PUCCH 1b\n");
          }

          // if SR was detected, use the n1_pucch from SR
          if (SR_payload==1) {
#ifdef DEBUG_PHY_PROC
            LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",phy_vars_eNB->Mod_id,
                  phy_vars_eNB->dlsch_eNB[i][0]->rnti,
                  frame,subframe,
                  n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
3129
#endif
3130 3131

            if (abstraction_flag == 0)
3132 3133 3134 3135 3136 3137 3138 3139 3140
              metric0_SR = rx_pucch(phy_vars_eNB,
				    format,
				    i,
				    phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,
				    0, //n2_pucch
				    0, // shortened format
				    pucch_payload0,
				    subframe,
				    PUCCH1a_THRES);
3141
            else {
3142
#ifdef PHY_ABSTRACTION
3143 3144 3145 3146 3147
              metric0 = rx_pucch_emul(phy_vars_eNB,i,
                                      format,
                                      0,
                                      pucch_payload0,
                                      subframe);
3148
#endif
3149 3150 3151 3152 3153 3154 3155
            }
          } else { //using n1_pucch0/n1_pucch1 resources
#ifdef DEBUG_PHY_PROC
            LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",phy_vars_eNB->Mod_id,
                  phy_vars_eNB->dlsch_eNB[i][0]->rnti,
                  frame,subframe,
                  n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
3156
#endif
3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167
            metric0=0;
            metric1=0;

            // Check n1_pucch0 metric
            if (n1_pucch0 != -1) {
              if (abstraction_flag == 0)
                metric0 = rx_pucch(phy_vars_eNB,
                                   format,
                                   i,
                                   (uint16_t)n1_pucch0,
                                   0, // n2_pucch
3168
                                   0, // shortened format
3169 3170 3171 3172
                                   pucch_payload0,
                                   subframe,
                                   PUCCH1a_THRES);
              else {
3173
#ifdef PHY_ABSTRACTION
3174 3175 3176 3177 3178
                metric0 = rx_pucch_emul(phy_vars_eNB,i,
                                        format,
                                        0,
                                        pucch_payload0,
                                        subframe);
3179
#endif
3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190
              }
            }

            // Check n1_pucch1 metric
            if (n1_pucch1 != -1) {
              if (abstraction_flag == 0)
                metric1 = rx_pucch(phy_vars_eNB,
                                   format,
                                   i,
                                   (uint16_t)n1_pucch1,
                                   0, //n2_pucch
3191
                                   0, // shortened format
3192 3193 3194 3195
                                   pucch_payload1,
                                   subframe,
                                   PUCCH1a_THRES);
              else {
3196
#ifdef PHY_ABSTRACTION
3197 3198 3199 3200 3201
                metric1 = rx_pucch_emul(phy_vars_eNB,i,
                                        format,
                                        1,
                                        pucch_payload1,
                                        subframe);
3202

3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230

#endif
              }
            }
          }

          if (SR_payload == 1) {
            pucch_payload = pucch_payload0;

            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
          }

#ifdef DEBUG_PHY_PROC
          LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",phy_vars_eNB->Mod_id,
                phy_vars_eNB->dlsch_eNB[i][0]->rnti,
                frame,subframe,
                metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]);
3231
#endif
3232 3233 3234 3235 3236 3237
          process_HARQ_feedback(i,sched_subframe,phy_vars_eNB,
                                0,// pusch_flag
                                pucch_payload,
                                pucch_sel,
                                SR_payload);
        }
Lionel Gauthier's avatar
Lionel Gauthier committed
3238
      }
3239 3240

    } 
3241

3242
    if ((frame % 100 == 0) && (subframe == 4)) {
3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260
      for (harq_idx=0; harq_idx<8; harq_idx++) {
        for (round=0; round<phy_vars_eNB->ulsch_eNB[i]->Mdlharq; round++) {
          if ((phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
               phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]) != 0) {
            phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] =
              (100*(phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round] -
                    phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round]))/
              (phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
               phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]);
          } else {
            phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] = 0;
          }

          phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round] =
            phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round];
          phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round] =
            phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round];
        }
3261 3262
      }
    }
3263

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3264
    if ((frame % 100 == 0) && (subframe==4)) {
3265 3266 3267
      phy_vars_eNB->eNB_UE_stats[i].dlsch_bitrate = (phy_vars_eNB->eNB_UE_stats[i].total_TBS -
          phy_vars_eNB->eNB_UE_stats[i].total_TBS_last);

3268 3269
      phy_vars_eNB->eNB_UE_stats[i].total_TBS_last = phy_vars_eNB->eNB_UE_stats[i].total_TBS;
    }
3270

3271
    num_active_cba_groups = phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups;
3272

3273
    /*if (num_active_cba_groups > 0 )
Raymond Knopp's avatar
 
Raymond Knopp committed
3274 3275 3276
      LOG_D(PHY,"[eNB] last slot %d trying cba transmission decoding UE %d num_grps %d rnti %x flag %d\n",
      last_slot, i, num_active_cba_groups,phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups],
      phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag );
3277
    */
3278
    if ((phy_vars_eNB->ulsch_eNB[i]) &&
3279 3280 3281
        (num_active_cba_groups > 0) &&
        (phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups]>0) &&
        (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag==1)) {
3282
      rnti=0;
3283 3284

#ifdef DEBUG_PHY_PROC
3285
      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",
3286 3287 3288
            phy_vars_eNB->Mod_id,harq_pid,
            frame,subframe,
            i, (uint16_t)phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups],mode_string[phy_vars_eNB->eNB_UE_stats[i].mode]);
3289
#endif
3290

3291
      if (abstraction_flag==0) {
3292 3293 3294 3295 3296 3297
        rx_ulsch(phy_vars_eNB,
                 sched_subframe,
                 phy_vars_eNB->eNB_UE_stats[i].sector,  // this is the effective sector id
                 i,
                 phy_vars_eNB->ulsch_eNB,
                 0);
3298
      }
3299

3300
#ifdef PHY_ABSTRACTION
3301
      else {
3302 3303 3304 3305
        rx_ulsch_emul(phy_vars_eNB,
                      subframe,
                      phy_vars_eNB->eNB_UE_stats[i].sector,  // this is the effective sector id
                      i);
3306
      }
3307

3308
#endif
3309

3310
      if (abstraction_flag == 0) {
3311 3312 3313 3314 3315
        ret = ulsch_decoding(phy_vars_eNB,
                             i,
                             sched_subframe,
                             0, // control_only_flag
                             phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI,
3316
                             0);//phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb>20 ? 1 : 0);
3317
      }
3318

3319
#ifdef PHY_ABSTRACTION
3320
      else {
3321 3322 3323 3324
        ret = ulsch_decoding_emul(phy_vars_eNB,
                                  sched_subframe,
                                  i,
                                  &rnti);
3325
      }
3326

3327
#endif
3328

Raymond Knopp's avatar
 
Raymond Knopp committed
3329
      if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) {
3330
#ifdef DEBUG_PHY_PROC
3331 3332
        //if (((phy_vars_eNB->proc[sched_subframe].frame_tx%10) == 0) || (phy_vars_eNB->proc[sched_subframe].frame_tx < 50))
        print_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,phy_vars_eNB->lte_frame_parms.N_RB_DL);
3333
#endif
3334 3335 3336 3337 3338 3339 3340
        access_mode = UNKNOWN_ACCESS;
        extract_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,
                    phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,
                    &phy_vars_eNB->eNB_UE_stats[i],
                    phy_vars_eNB->lte_frame_parms.N_RB_DL,
                    &rnti, &access_mode);
        phy_vars_eNB->eNB_UE_stats[i].rank = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0];
3341
      }
3342

Raymond Knopp's avatar
 
Raymond Knopp committed
3343
      /*  LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d resetting the sched_subframeuling_flag, total cba groups %d %d\n",
3344 3345
      phy_vars_eNB->Mod_id,harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i,harq_pid,
      phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups,num_active_cba_groups);
3346 3347 3348
      */
      phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=0;
      phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->status= SCH_IDLE;
3349

3350
      if ((num_active_cba_groups > 0) &&
3351 3352 3353 3354
          //  (i % num_active_cba_groups == 0) && // this ue is used a a template for the CBA
          (i + num_active_cba_groups < NUMBER_OF_UE_MAX) &&
          (phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->cba_rnti[i%num_active_cba_groups] > 0 ) &&
          (phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->num_active_cba_groups> 0)) {
3355
#ifdef DEBUG_PHY_PROC
3356 3357 3358
        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",
              phy_vars_eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid,
              i+num_active_cba_groups, i%phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups);
3359
#endif
3360 3361 3362
        phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=1;
        phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->status= CBA_ACTIVE;
        phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->TBS=phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS;
3363
      }
3364

3365
      if (ret == (1+MAX_TURBO_ITERATIONS)) {
3366 3367 3368 3369
        phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++;
3370 3371
      } // ulsch in error
      else {
3372 3373 3374 3375 3376 3377 3378 3379
        LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
              phy_vars_eNB->Mod_id,harq_pid,
              frame,subframe);

        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1;
        phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0;
        phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0;
3380 3381
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
3382 3383 3384 3385 3386 3387 3388 3389
        LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",
              frame,subframe,
              harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);

        for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++)
          LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]);

        LOG_T(PHY,"\n");
3390 3391
#endif
#endif
3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402

        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",
                phy_vars_eNB->Mod_id, frame,subframe,
                i, phy_vars_eNB->ulsch_eNB[i]->rnti,
                i % phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups, phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups]);

          // detect if there is a CBA collision
          if (phy_vars_eNB->cba_last_reception[i%num_active_cba_groups] == 0 ) {
            mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
                              phy_vars_eNB->CC_id,
3403
                              frame,subframe,
3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428
                              phy_vars_eNB->ulsch_eNB[i]->rnti,
                              phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
                              phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
                              harq_pid,
                              NULL);

            phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]+=1;//(subframe);
          } else {
            if (phy_vars_eNB->cba_last_reception[i%num_active_cba_groups] == 1 )
              LOG_N(PHY,"[eNB%d] Frame %d subframe %d : first CBA collision detected \n ",
                    phy_vars_eNB->Mod_id,frame,subframe);

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

            phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]+=1;

            mac_xface->SR_indication(phy_vars_eNB->Mod_id,
                                     phy_vars_eNB->CC_id,
                                     frame,
                                     phy_vars_eNB->dlsch_eNB[i][0]->rnti,subframe);
          }
        }
      } // ULSCH CBA not in error
3429
    }
3430

3431 3432
  } // loop i=0 ... NUMBER_OF_UE_MAX-1

3433 3434
    if (abstraction_flag == 0) {
      lte_eNB_I0_measurements(phy_vars_eNB,
3435
			      subframe,
3436 3437
                              0,
                              phy_vars_eNB->first_run_I0_measurements);
3438
      phy_vars_eNB->first_run_I0_measurements = 0;
3439
    }
3440

3441
#ifdef PHY_ABSTRACTION
3442 3443
    else {
      lte_eNB_I0_measurements_emul(phy_vars_eNB,
3444
                                   0);
3445
    }
3446

3447
#endif
3448 3449


3450
    //}
3451 3452

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3453
  phy_procedures_emos_eNB_RX(subframe,phy_vars_eNB);
3454 3455
#endif

3456
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,0);
3457
  stop_meas(&phy_vars_eNB->phy_proc_rx);
3458

3459 3460 3461 3462
}

#undef DEBUG_PHY_PROC

3463 3464 3465 3466
#ifdef Rel10
int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type)
{

3467
  int do_proc=0;// do nothing
3468 3469

  switch(r_type) {
3470
  case no_relay:
3471
    do_proc= no_relay; // perform the normal eNB operation
3472
    break;
3473

3474
  case multicast_relay:
3475
    if (((next_slot >>1) < 6) || ((next_slot >>1) > 8))
3476
      do_proc = 0; // do nothing
3477 3478 3479
    else // SF#6, SF#7 and SF#8
      do_proc = multicast_relay; // do PHY procedures eNB TX

3480
    break;
3481

3482 3483
  default: // should'not be here
    LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type);
3484
    do_proc=0;
3485 3486
    break;
  }
3487

3488 3489
  return do_proc;
}
3490 3491 3492 3493
#endif
void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t abstraction_flag,
                            relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn)
{
3494
#if defined(ENABLE_ITTI)
3495 3496 3497 3498 3499
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  unsigned int  Mod_id;
  int           result;
3500
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3501

Raymond Knopp's avatar
 
Raymond Knopp committed
3502 3503 3504

  int CC_id=0;

3505
  /*
Raymond Knopp's avatar
 
Raymond Knopp committed
3506
    if (phy_vars_eNB->proc[sched_subframe].frame_tx >= 1000)
3507
    mac_xface->macphy_exit("Exiting after 1000 Frames\n");
3508
  */
3509 3510
  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, phy_vars_eNB[0]->proc[subframe].frame_tx);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3511
  start_meas(&phy_vars_eNB[0]->phy_proc);
Lionel Gauthier's avatar
Lionel Gauthier committed
3512

3513
#if defined(ENABLE_ITTI)
3514

3515
  do {
3516 3517
    // Checks if a message has been sent to PHY sub-task
    itti_poll_msg (TASK_PHY_ENB, &msg_p);
3518

3519 3520 3521 3522
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance;
3523

3524
      switch (ITTI_MSG_ID(msg_p)) {
3525
#   if ENABLE_RAL
3526

Raymond Knopp's avatar
 
Raymond Knopp committed
3527
      case TIMER_HAS_EXPIRED:
3528 3529 3530 3531 3532
        // 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
3533

3534 3535 3536 3537 3538
        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
3539 3540


Raymond Knopp's avatar
 
Raymond Knopp committed
3541
      case PHY_MEAS_THRESHOLD_REQ:
Lionel Gauthier's avatar
Lionel Gauthier committed
3542
#warning "TO DO LIST OF THRESHOLDS"
3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634
        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
3635
#   endif
3636

3637
        /* Messages from eNB app */
Raymond Knopp's avatar
 
Raymond Knopp committed
3638
      case PHY_CONFIGURATION_REQ:
3639 3640
        LOG_I(PHY, "[eNB %d] Received %s\n", instance, msg_name);
        /* TODO */
3641

3642
        break;
3643

Raymond Knopp's avatar
 
Raymond Knopp committed
3644
      default:
3645 3646
        LOG_E(PHY, "[ENB %d] Received unexpected message %s\n", Mod_id, msg_name);
        break;
Lionel Gauthier's avatar
Lionel Gauthier committed
3647
      }
3648 3649 3650 3651

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

3654 3655
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3656

3657
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3658
    if ((((phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == TDD)&&
3659 3660 3661 3662 3663 3664 3665
          (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_tx)==SF_DL))||
         (phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == FDD))) {
#ifdef Rel10

      if (phy_procedures_RN_eNB_TX(phy_vars_eNB[CC_id]->proc[subframe].subframe_rx, phy_vars_eNB[CC_id]->proc[subframe].subframe_tx, r_type) != 0 )
#endif
        phy_procedures_eNB_TX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type,phy_vars_rn);
Raymond Knopp's avatar
 
Raymond Knopp committed
3666
    }
3667

Raymond Knopp's avatar
 
Raymond Knopp committed
3668
    if ((((phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == TDD )&&
3669 3670
          (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_rx)==SF_UL)) ||
         (phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == FDD))) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3671 3672
      phy_procedures_eNB_RX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type);
    }
3673

Raymond Knopp's avatar
 
Raymond Knopp committed
3674
    if (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_tx)==SF_S) {
3675 3676
#ifdef Rel10

Raymond Knopp's avatar
 
Raymond Knopp committed
3677
      if (phy_procedures_RN_eNB_TX(subframe, subframe, r_type) != 0 )
3678 3679
#endif
        phy_procedures_eNB_TX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type,phy_vars_rn);
Raymond Knopp's avatar
 
Raymond Knopp committed
3680
    }
3681 3682

    if ((subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_rx)==SF_S)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3683 3684
      phy_procedures_eNB_S_RX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type);
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3685

Raymond Knopp's avatar
 
Raymond Knopp committed
3686 3687
    phy_vars_eNB[CC_id]->proc[subframe].frame_tx++;
    phy_vars_eNB[CC_id]->proc[subframe].frame_rx++;
3688

3689 3690
    if (phy_vars_eNB[CC_id]->proc[subframe].frame_tx>=MAX_FRAME_NUMBER) // defined in impl_defs_top.h
      phy_vars_eNB[CC_id]->proc[subframe].frame_tx-=MAX_FRAME_NUMBER;
3691

3692 3693
    if (phy_vars_eNB[CC_id]->proc[subframe].frame_rx>=MAX_FRAME_NUMBER)
      phy_vars_eNB[CC_id]->proc[subframe].frame_rx-=MAX_FRAME_NUMBER;
Raymond Knopp's avatar
 
Raymond Knopp committed
3694
  }
3695

3696
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3697
  stop_meas(&phy_vars_eNB[0]->phy_proc);
3698 3699
}