phy_procedures_lte_eNb.c 118 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21 22 23

/*! \file phy_procedures_lte_eNB.c
 * \brief Implementation of eNB procedures from 36.213 LTE specifications
24
 * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas
25 26 27
 * \date 2011
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk
29 30 31 32 33 34 35 36 37
 * \note
 * \warning
 */

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

38
#include "PHY/LTE_TRANSPORT/if4_tools.h"
Sandeep Kumar's avatar
Sandeep Kumar committed
39
#include "PHY/LTE_TRANSPORT/if5_tools.h"
40

41 42 43 44
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif

45
//#define DEBUG_PHY_PROC (Already defined in cmake)
46 47 48 49 50 51 52
//#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"

53 54
#include "T.h"

55
#include "assertions.h"
gauthier's avatar
gauthier committed
56
#include "msc.h"
57

58 59
#include <time.h>

60
#if defined(ENABLE_ITTI)
gauthier's avatar
gauthier committed
61
#   include "intertask_interface.h"
62 63
#endif

64

65
#if defined(FLEXRAN_AGENT_SB_IF)
66
//Agent-related headers
67
#include "ENB_APP/flexran_agent_extern.h"
68
#include "ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h"
69
#include "LAYER2/MAC/flexran_agent_mac_proto.h"
70
#endif
71

72 73 74 75 76 77
//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

78 79
void exit_fun(const char* s);

80
extern int exit_openair;
81 82
struct timespec start_fh, start_fh_prev;
int start_fh_sf, start_fh_prev_sf;
83 84
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
85

86 87 88
unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(32)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(32)));
int eNB_sync_buffer1[640*6] __attribute__ ((aligned(32)));
89 90
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

91
extern uint16_t hundred_times_log10_NPRB[100];
92

93
unsigned int max_peak_val;
94
int max_sync_pos;
95

96 97 98
int harq_pid_updated[NUMBER_OF_UE_MAX][8] = {{0}};
int harq_pid_round[NUMBER_OF_UE_MAX][8] = {{0}};

99 100 101 102 103 104
//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

105
#if defined(SMBV) 
106 107
extern const char smbv_fname[];
extern unsigned short config_frames[4];
108
extern uint8_t smbv_frame_cnt;
109 110 111 112 113 114
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

knopp's avatar
knopp committed
115
uint8_t is_SR_subframe(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id)
116
{
knopp's avatar
knopp committed
117

118 119
  const int subframe = proc->subframe_rx;
  const int frame = proc->frame_rx;
120

121
  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
122 123
        eNB->Mod_id,eNB->ulsch[UE_id]->rnti,frame,subframe,
        eNB->scheduling_request_config[UE_id].sr_ConfigIndex);
124

125 126
  if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
    if ((subframe%5) == eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
127
      return(1);
128 129
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
    if (subframe==(eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
130
      return(1);
131 132
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
    if ((10*(frame&1)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
133
      return(1);
134 135
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
    if ((10*(frame&3)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
136
      return(1);
137 138
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
    if ((10*(frame&7)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
139
      return(1);
140 141 142 143
  }

  return(0);
}
144

145

146
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
147
{
148
  uint8_t i;
149

150 151

  LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
152 153
        eNB->Mod_id,
        eNB->CC_id,
154
        (uint16_t)rnti);
155 156

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
157
    if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
158
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
159 160
      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
      return(-1);
161
    } else {
162
      if (eNB->UE_stats[i].crnti==0) {
163
        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
164
        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
165 166 167
        eNB->dlsch[i][0]->rnti = rnti;
        eNB->ulsch[i]->rnti = rnti;
        eNB->UE_stats[i].crnti = rnti;
168

169 170 171
	eNB->UE_stats[i].Po_PUCCH1_below = 0;
	eNB->UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
	eNB->UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
172
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
173 174 175
	      eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
	      eNB->rx_total_gain_dB,
	      eNB->UE_stats[i].Po_PUCCH);
176
  
177
        return(i);
178
      }
179
    }
180 181 182 183
  }
  return(-1);
}

184
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
185
  uint8_t i;
186
  int CC_id;
187
  PHY_VARS_eNB *eNB;
188 189

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
190
    eNB = PHY_vars_eNB_g[Mod_idP][CC_id];
191
    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
192
      if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
Wilson's avatar
Wilson committed
193
	MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rntiP);
194 195 196
	LOG_E(PHY,"Can't remove UE, not enough memory allocated\n");
	return(-1);
      } else {
197
	if (eNB->UE_stats[i].crnti==rntiP) {
198
	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
199 200 201

	  LOG_D(PHY,"eNB %d removing UE %d with rnti %x\n",eNB->Mod_id,i,rntiP);

202
	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
203 204 205 206
	  clean_eNb_dlsch(eNB->dlsch[i][0]);
	  clean_eNb_ulsch(eNB->ulsch[i]);
	  //eNB->UE_stats[i].crnti = 0;
	  memset(&eNB->UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
207 208
	  //  mac_exit_wrapper("Removing UE");
	  
209

210 211
	  return(i);
	}
212
      }
213
    }
214
  }
215
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
216 217 218
  return(-1);
}

219
int8_t find_next_ue_index(PHY_VARS_eNB *eNB)
220
{
221
  uint8_t i;
222

223
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
224 225
    if (eNB->UE_stats[i].crnti==0) {
      /*if ((eNB->dlsch[i]) &&
226 227
	(eNB->dlsch[i][0]) &&
	(eNB->dlsch[i][0]->rnti==0))*/
228 229 230
      LOG_D(PHY,"Next free UE id is %d\n",i);
      return(i);
    }
231
  }
232

233 234 235
  return(-1);
}

236
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 harq_flag)
237 238 239 240
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
241
  int i;
knopp's avatar
knopp committed
242
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
243 244

  if (UE_id==-1) {
245
    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
246 247
    *round=0;
    return(-1);
248 249
  }

250 251
  if ((harq_flag == openair_harq_DL) || (harq_flag == openair_harq_RA))  {// this is a DL request

252
    DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch[(uint32_t)UE_id][0];
253

254 255 256 257 258 259 260 261 262 263
    if (harq_flag == openair_harq_RA) {
      if (DLSCH_ptr->harq_processes[0] != NULL) {
	*harq_pid = 0;
	*round = DLSCH_ptr->harq_processes[0]->round;
	return 0;
      } else {
	return -1;
      }
    }

264 265
    /* let's go synchronous for the moment - maybe we can change at some point */
    i = (frame * 10 + subframe) % 8;
266

267 268 269 270 271
    if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
      *harq_pid = i;
      *round = DLSCH_ptr->harq_processes[i]->round;
    } else if (DLSCH_ptr->harq_processes[i]->status == SCH_IDLE) {
      *harq_pid = i;
272
      *round = 0;
273 274 275
    } else {
      printf("%s:%d: bad state for harq process - PLEASE REPORT!!\n", __FILE__, __LINE__);
      abort();
276
    }
277
  } else { // This is a UL request
278

279 280 281
    ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch[(uint32_t)UE_id];
    ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,subframe);
    ulsch_frame    = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,frame,subframe);
282
    // Note this is for TDD configuration 3,4,5 only
283
    *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
284 285
                                  ulsch_frame,
                                  ulsch_subframe);
286
    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
287
    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
288
  }
289

290 291 292
  return(0);
}

293
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
294
{
295
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
296 297
}

298 299
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
300
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
301 302
}

303
#ifdef EMOS
304
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *eNB)
305
{
306 307 308 309

}
#endif

310
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type)
311 312
{
  UNUSED(r_type);
313
  int subframe = proc->subframe_rx;
314

315
#ifdef DEBUG_PHY_PROC
316
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", eNB->Mod_id,proc->frame_rx, subframe);
317
#endif
318

319

320
  if (eNB->abstraction_flag == 0) {
321
    lte_eNB_I0_measurements(eNB,
322
			    subframe,
323
                            0,
324
                            eNB->first_run_I0_measurements);
knopp's avatar
knopp committed
325
  }
326

327
#ifdef PHY_ABSTRACTION
knopp's avatar
knopp committed
328
  else {
329
    lte_eNB_I0_measurements_emul(eNB,
330
                                 0);
331
  }
332

knopp's avatar
knopp committed
333 334
#endif

335

336 337
}

knopp's avatar
knopp committed
338 339


340
#ifdef EMOS
341
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *eNB)
342 343
{

344 345
  uint8_t aa;
  uint16_t last_subframe_emos;
346
  uint16_t pilot_pos1 = 3 - eNB->frame_parms.Ncp, pilot_pos2 = 10 - 2*eNB->frame_parms.Ncp;
347
  uint32_t bytes;
348 349 350

  last_subframe_emos=0;

knopp's avatar
knopp committed
351

knopp's avatar
knopp committed
352

knopp's avatar
knopp committed
353

354
#ifdef EMOS_CHANNEL
355

356
  //if (last_slot%2==1) // this is for all UL subframes
357
  if (subframe==3)
358 359 360 361 362 363 364
    for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
      memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*eNB->frame_parms.N_RB_UL*12],
             &eNB->pusch_vars[0]->drs_ch_estimates[0][aa][eNB->frame_parms.N_RB_UL*12*pilot_pos1],
             eNB->frame_parms.N_RB_UL*12*sizeof(int));
      memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*eNB->frame_parms.N_RB_UL*12],
             &eNB->pusch_vars[0]->drs_ch_estimates[0][aa][eNB->frame_parms.N_RB_UL*12*pilot_pos2],
             eNB->frame_parms.N_RB_UL*12*sizeof(int));
365
    }
366

367 368
#endif

knopp's avatar
knopp committed
369
  if (subframe==4) {
370
    emos_dump_eNB.timestamp = rt_get_time_ns();
371 372 373 374 375
    emos_dump_eNB.frame_tx = eNB->proc[subframe].frame_rx;
    emos_dump_eNB.rx_total_gain_dB = eNB->rx_total_gain_dB;
    emos_dump_eNB.mimo_mode = eNB->transmission_mode[0];
    memcpy(&emos_dump_eNB.measurements,
           &eNB->measurements[0],
376
           sizeof(PHY_MEASUREMENTS_eNB));
377
    memcpy(&emos_dump_eNB.UE_stats[0],&eNB->UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));
378 379

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

381 382
    //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
    if (bytes!=sizeof(fifo_dump_emos_eNB)) {
knopp's avatar
knopp committed
383
      LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n",
384
            eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
385
    } else {
386
      if (eNB->proc[(subframe+1)%10].frame_tx%100==0) {
knopp's avatar
knopp committed
387
        LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n",
388
              eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes);
389
      }
390
    }
391 392 393 394 395 396 397
  }
}
#endif


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
398 399
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)};
400

gauthier's avatar
gauthier committed
401

knopp's avatar
knopp committed
402

Cedric Roux's avatar
Cedric Roux committed
403
unsigned int taus(void);
404
DCI_PDU DCI_pdu_tmp;
knopp's avatar
knopp committed
405

406

407
void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,relaying_type_t r_type) {
408 409


Cedric Roux's avatar
Cedric Roux committed
410
#if defined(Rel10) || defined(Rel14)
411 412
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
413
  //  uint8_t sync_area=255;
414
#endif
415

416
  int subframe = proc->subframe_tx;
417

418
  if (eNB->abstraction_flag==0) {
419 420
    // This is DL-Cell spec pilots in Control region
    generate_pilots_slot(eNB,
421
			 eNB->common_vars.txdataF[0],
422 423
			 AMP,
			 subframe<<1,1);
knopp's avatar
knopp committed
424
  }
425
  
Cedric Roux's avatar
Cedric Roux committed
426
#if defined(Rel10) || defined(Rel14)
427 428 429 430
  // if mcch is active, send regardless of the node type: eNB or RN
  // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing
  mch_pduP = mac_xface->get_mch_sdu(eNB->Mod_id,
				    eNB->CC_id,
431
				    proc->frame_tx,
432 433 434 435 436 437
				    subframe);
  
  switch (r_type) {
  case no_relay:
    if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
      LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
438 439
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs,
	    eNB->dlsch_MCH->harq_processes[0]->TBS>>3);
440 441
    else {
      LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
442
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area,
443 444
	    (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment");
      mch_pduP = NULL;
gauthier's avatar
gauthier committed
445
    }
446
    
knopp's avatar
knopp committed
447
    break;
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
    
  case multicast_relay:
    if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) {
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN  sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,
	    mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);
    } else if (rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8
      mch_pduP= &mch_pdu;
      memcpy(&mch_pduP->payload, // could be a simple copy
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b,
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->Pdu_size = (uint16_t) (rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->mcs = rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs;
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,subframe%5,
	    rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size);
knopp's avatar
knopp committed
464
    } else {
465
      mch_pduP=NULL;
knopp's avatar
knopp committed
466
    }
467 468
    
    rn->mch_avtive[subframe]=0;
knopp's avatar
knopp committed
469
    break;
470
    
471
  default:
472
    LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
473
	  eNB->Mod_id,proc->frame_tx,subframe,r_type);
474 475 476 477 478
    mch_pduP=NULL;
    break;
  }// switch
  
  if (mch_pduP) {
479
    fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0);
480
    // Generate PMCH
481
    generate_mch(eNB,proc,(uint8_t*)mch_pduP->payload);
482
  } else {
483
    LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",proc->frame_tx,subframe);
knopp's avatar
knopp committed
484
  }
485
  
486
#endif
487
}
488

489
void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
490

491 492
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int **txdataF = eNB->common_vars.txdataF[0];
493
  uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
494 495
  int subframe = proc->subframe_tx;
  int frame = proc->frame_tx;
496

497
  // generate Cell-Specific Reference Signals for both slots
498
  if (eNB->abstraction_flag==0) {
499 500 501 502 503 504 505 506 507 508 509 510 511 512
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
    generate_pilots_slot(eNB,
			 txdataF,
			 AMP,
			 subframe<<1,0);
    // check that 2nd slot is for DL
    if (subframe_select(fp,subframe) == SF_DL)
      generate_pilots_slot(eNB,
			   txdataF,
			   AMP,
			   (subframe<<1)+1,0);
    
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
  }    
513

514
  // First half of PSS/SSS (FDD, slot 0)
knopp's avatar
knopp committed
515
  if (subframe == 0) {
516
    if ((fp->frame_type == FDD) &&
517
	(eNB->abstraction_flag==0)) {
518 519 520 521 522 523 524 525 526 527 528
      generate_pss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   0);
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 5 : 4,
		   0);
      
529
    }
530
    
531
    // generate PBCH (Physical Broadcast CHannel) info
532
    if ((frame&3) == 0) {
533
      pbch_pdu[2] = 0;
534
      
535
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
536
      switch (fp->N_RB_DL) {
knopp's avatar
knopp committed
537
      case 6:
538 539
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
	break;
540
	
knopp's avatar
knopp committed
541
      case 15:
542 543 544
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
	break;
	
knopp's avatar
knopp committed
545
      case 25:
546 547 548
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
	
knopp's avatar
knopp committed
549
      case 50:
550 551 552
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
	break;
	
knopp's avatar
knopp committed
553
      case 75:
554 555 556
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
	break;
	
knopp's avatar
knopp committed
557
      case 100:
558 559 560
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
	break;
	
knopp's avatar
knopp committed
561
      default:
562 563 564
	// FIXME if we get here, this should be flagged as an error, right?
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
knopp's avatar
knopp committed
565
      }
566
      
567
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
568 569 570
	((fp->phich_config_common.phich_duration << 4)&0x10);
      
      switch (fp->phich_config_common.phich_resource) {
knopp's avatar
knopp committed
571
      case oneSixth:
572 573 574
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
	break;
	
knopp's avatar
knopp committed
575
      case half:
576 577 578
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
	break;
	
knopp's avatar
knopp committed
579
      case one:
580 581 582
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
	break;
	
knopp's avatar
knopp committed
583
      case two:
584 585 586
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
	break;
	
knopp's avatar
knopp committed
587
      default:
588 589
	// unreachable
	break;
knopp's avatar
knopp committed
590
      }
591
      
592 593
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((frame>>8)&0x3);
      pbch_pdu[1] = frame&0xfc;
594
      pbch_pdu[0] = 0;
knopp's avatar
knopp committed
595
    }
596 597 598 599
      
    /// First half of SSS (TDD, slot 1)
    
    if ((fp->frame_type == TDD)&&
600
	(eNB->abstraction_flag==0)){
601 602 603 604 605 606
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   1);
    }
607

608
    /// generate PBCH
609
    if (eNB->abstraction_flag==0) {
610
      generate_pbch(&eNB->pbch,
611 612 613 614
                    txdataF,
                    AMP,
                    fp,
                    pbch_pdu,
615
                    frame&3);
616
    }
617 618 619
#ifdef PHY_ABSTRACTION
    else {
      generate_pbch_emul(eNB,pbch_pdu);
620
    }
621
#endif
622

623
  }
624 625
  else if ((subframe == 1) &&
	   (fp->frame_type == TDD)&&
626
	   (eNB->abstraction_flag==0)) {
627 628 629 630 631
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 2);
632
  }
633 634 635 636
  
  // Second half of PSS/SSS (FDD, slot 10)
  else if ((subframe == 5) && 
	   (fp->frame_type == FDD) &&
637
	   (eNB->abstraction_flag==0)) {
638 639 640 641 642 643 644 645 646 647
    generate_pss(txdataF,
		 AMP,
		 &eNB->frame_parms,
		 (fp->Ncp==NORMAL) ? 6 : 5,
		 10);
    generate_sss(txdataF,
		 AMP,
		 &eNB->frame_parms,
		 (fp->Ncp==NORMAL) ? 5 : 4,
		 10);
648

649
  }
650

651 652 653
  //  Second-half of SSS (TDD, slot 11)
  else if ((subframe == 5) &&
	   (fp->frame_type == TDD) &&
654
	   (eNB->abstraction_flag==0)) {
655 656 657 658 659
    generate_sss(txdataF,
		 AMP,
		 fp,
		 (fp->Ncp==NORMAL) ? 6 : 5,
		 11);
knopp's avatar
knopp committed
660
  }
knopp's avatar
knopp committed
661

662 663 664
  // Second half of PSS (TDD, slot 12)
  else if ((subframe == 6) &&
	   (fp->frame_type == TDD) &&
665
	   (eNB->abstraction_flag==0)) {
666 667 668 669 670 671
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 12);
  }
knopp's avatar
knopp committed
672

673
}
knopp's avatar
knopp committed
674

knopp's avatar
knopp committed
675
void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
676

677
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
678 679
  int frame = proc->frame_tx;
  int subframe = proc->subframe_tx;
680 681 682 683 684 685 686 687 688

  // if we have SI_RNTI, configure dlsch parameters and CCE index
  if (dci_alloc->rnti == SI_RNTI) {
    LOG_D(PHY,"Generating dlsch params for SI_RNTI\n");
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
689
				       &eNB->dlsch_SI,
690
				       fp,
691
				       NULL,
692 693 694
				       SI_RNTI,
				       0,
				       P_RNTI,
695 696
				       eNB->UE_stats[0].DL_pmi_single,
				       0);
697 698
    
    
699
    eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE;
700
    
701
    LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
702
	  eNB->dlsch_SI->nCCE[subframe]);
703 704 705 706
    
#if defined(SMBV) 
    
    // configure SI DCI
707 708
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",frame,subframe,i);
709 710 711 712 713 714 715 716 717 718 719 720 721 722
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", dci_alloc, i);
    }
    
#endif
    
    
  } else if (dci_alloc->ra_flag == 1) {  // This is format 1A allocation for RA
    // configure dlsch parameters and CCE index
    LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");    
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
723
				       &eNB->dlsch_ra,
724
				       fp,
725
				       NULL,
726 727 728
				       SI_RNTI,
				       dci_alloc->rnti,
				       P_RNTI,
729 730
				       eNB->UE_stats[0].DL_pmi_single,
				       0);
731 732
    
    
733
    eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE;
734
    
735
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
736
	  eNB->dlsch_ra->nCCE[subframe]);
737 738 739
#if defined(SMBV) 
    
    // configure RA DCI
740 741
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",frame,subframe,i);
742
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", dci_alloc, i);
knopp's avatar
knopp committed
743
    }
744 745 746 747 748 749 750 751 752 753
    
#endif
    
  }
  
  else if ((dci_alloc->format != format0)&&
	   (dci_alloc->format != format3)&&
	   (dci_alloc->format != format3A)&&
	   (dci_alloc->format != format4)){ // this is a normal DLSCH allocation
    
knopp's avatar
knopp committed
754

755 756 757 758
    
    if (UE_id>=0) {
#if defined(SMBV) 
      // Configure this user
759 760
      if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",frame,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
761 762
              dci_alloc->rnti,eNB->transmission_mode[(uint8_t)UE_id]);
	smbv_configure_user(smbv_fname,UE_id+1,eNB->transmission_mode[(uint8_t)UE_id],dci_alloc->rnti);
knopp's avatar
knopp committed
763
      }
764 765
      
#endif
766

767 768 769 770 771 772
      LOG_D(PHY,"Generating dlsch params for RNTI %x\n",dci_alloc->rnti);      
      generate_eNB_dlsch_params_from_dci(frame,
					 subframe,
					 &dci_alloc->dci_pdu[0],
					 dci_alloc->rnti,
					 dci_alloc->format,
773
					 eNB->dlsch[(uint8_t)UE_id],
774
					 fp,
775
					 &eNB->pdsch_config_dedicated[UE_id],
776 777 778
					 SI_RNTI,
					 0,
					 P_RNTI,
779 780
					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single,
					 eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id]);
781
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
782
	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe);
783 784
      
      
Cedric Roux's avatar
Cedric Roux committed
785 786
      T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
        T_INT(dci_alloc->rnti), T_INT(dci_alloc->format),
Cedric Roux's avatar
Cedric Roux committed
787
        T_INT(eNB->dlsch[(int)UE_id][0]->current_harq_pid),
788 789
        T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[eNB->dlsch[(int)UE_id][0]->current_harq_pid]->mcs),
        T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[eNB->dlsch[(int)UE_id][0]->current_harq_pid]->TBS));
790

791
      eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
792
      
Cedric Roux's avatar
Cedric Roux committed
793
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
794
	    dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe]);
795 796 797 798
      
#if defined(SMBV) 
      
      // configure UE-spec DCI
799 800
      if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",frame,subframe,i);
801
	smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1,dci_alloc, i);
knopp's avatar
knopp committed
802
      }
803
      
804
#endif
805 806 807
      
      LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
	    eNB->Mod_id, dci_alloc->rnti,
808
	    frame, subframe,UE_id,
809 810
	    dci_alloc->format,
	    1<<dci_alloc->L);
knopp's avatar
knopp committed
811
    } else {
812
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
813
	    eNB->Mod_id,frame,dci_alloc->rnti);
814
    }
knopp's avatar
knopp committed
815
  }
816 817
  
}
818

knopp's avatar
knopp committed
819
void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
820

821
  int harq_pid;
822
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
823
  int frame = proc->frame_tx;
knopp's avatar
knopp committed
824
  int subframe = proc->subframe_tx;
825
  /*
826 827 828
  uint16_t srsPeriodicity=0;
  uint16_t srsOffset=0;
  uint16_t srsConfigIndex=0;
829
  uint16_t do_srs=0;
830
  */
831
  uint16_t is_srs_pos=0;
832

833
  LOG_D(PHY,
834 835 836
	"[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8"), aggregation %d\n",
	eNB->Mod_id,
	subframe2harq_pid(fp,
837
			  pdcch_alloc2ul_frame(fp,frame,subframe),
838
			  pdcch_alloc2ul_subframe(fp,subframe)),
839
	frame,
840
	subframe,
841
	pdcch_alloc2ul_frame(fp,frame,subframe),
842 843 844 845 846
	pdcch_alloc2ul_subframe(fp,subframe),
	dci_alloc->rnti,
	dci_alloc->dci_pdu[0],
	1<<dci_alloc->L);
  
847
  is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe));
848
  /*
849 850 851 852
  if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup) {
    srsConfigIndex = eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex;
    compute_srs_pos(fp->frame_type, srsConfigIndex, &srsPeriodicity, &srsOffset);
    if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) {
853
      do_srs = 1;
854
    }
855
  }
856 857 858
      LOG_D(PHY,"frame %d (%d), subframe %d (%d), UE_id %d: is_srs_pos %d, do_SRS %d, index %d, period %d, offset %d \n",
	    frame,pdcch_alloc2ul_frame(fp,frame,subframe),subframe,pdcch_alloc2ul_subframe(fp,subframe),
	    UE_id,is_srs_pos,do_srs,srsConfigIndex,srsPeriodicity,srsOffset);
859
  */
860

861
  generate_eNB_ulsch_params_from_dci(eNB,
knopp's avatar
knopp committed
862
				     proc,
863
				     &dci_alloc->dci_pdu[0],
864 865 866 867 868 869 870
				     dci_alloc->rnti,
				     format0,
				     UE_id,
				     SI_RNTI,
				     0,
				     P_RNTI,
				     CBA_RNTI,
871
				     is_srs_pos);  
872 873
  
  LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n",
874
	eNB->Mod_id,frame,subframe,dci_alloc->rnti,
875 876 877 878 879
	dci_alloc->firstCCE);
  
#if defined(SMBV) 
  
  // configure UE-spec DCI for UL Grant
880 881
  if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
    LOG_D(PHY,"[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",frame,subframe,i);
882
    smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i);
knopp's avatar
knopp committed
883
  }
884 885 886 887 888 889
  
#endif
  
  
  // get the hard_pid for this subframe 
  harq_pid = subframe2harq_pid(fp,
890
			       pdcch_alloc2ul_frame(fp,frame,subframe),
891 892 893
			       pdcch_alloc2ul_subframe(fp,subframe));
  
  if (harq_pid==255) { // should not happen, log an error and exit, this is a fatal error
894
    LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,frame);
895 896 897 898
    mac_xface->macphy_exit("FATAL\n"); 
  }
  
  if ((dci_alloc->rnti  >= CBA_RNTI) && (dci_alloc->rnti < P_RNTI))
899
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
900
  else
901
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
902
  
Cedric Roux's avatar
Cedric Roux committed
903
  T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
Cedric Roux's avatar
Cedric Roux committed
904 905 906 907 908 909
    T_INT(dci_alloc->rnti), T_INT(harq_pid),
    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->mcs),
    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->round),
    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->first_rb),
    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->nb_rb),
    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->TBS));
910
}
911

912
void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols) {
913

914 915
  int frame=proc->frame_tx;
  int subframe=proc->subframe_tx;
916 917 918
  int harq_pid = dlsch->current_harq_pid;
  LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
  int input_buffer_length = dlsch_harq->TBS/8;
919
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
920
  uint8_t *DLSCH_pdu=NULL;
921
  uint8_t DLSCH_pdu_tmp[input_buffer_length+4]; //[768*8];
922 923
  uint8_t DLSCH_pdu_rar[256];
  int i;
924

925
  LOG_D(PHY,
Cedric Roux's avatar
Cedric Roux committed
926
	"[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 %"PRIx64", rv %"PRIu8" (round %"PRIu8")\n",
927
	eNB->Mod_id, dlsch->rnti,harq_pid,
928
	frame, subframe, input_buffer_length,
929 930 931 932 933
	get_G(fp,
	      dlsch_harq->nb_rb,
	      dlsch_harq->rb_alloc,
	      get_Qm(dlsch_harq->mcs),
	      dlsch_harq->Nl,
934 935 936 937
	      num_pdcch_symbols,
	      frame,
	      subframe,
	      dlsch_harq->mimo_mode==TM7?7:0),
938 939 940 941 942
	dlsch_harq->nb_rb,
	dlsch_harq->mcs,
	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
	dlsch_harq->rvidx,
	dlsch_harq->round);
943

944
#if defined(MESSAGE_CHART_GENERATOR_PHY)
945 946 947 948 949 950 951 952 953 954 955
  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")",
		     frame, subframe,
		     input_buffer_length,
		     get_G(fp,
			   dlsch_harq->nb_rb,
			   dlsch_harq->rb_alloc,
			   get_Qm(dlsch_harq->mcs),
			   dlsch_harq->Nl,
956 957 958 959
			   num_pdcch_symbols,
			   frame,
			   subframe,
			   dlsch_harq->mimo_mode==TM7?7:0),
960 961 962 963 964 965 966 967 968 969 970 971 972
		     dlsch_harq->nb_rb,
		     dlsch_harq->mcs,
		     pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
		     dlsch_harq->rvidx,
		     dlsch_harq->round);
#endif

  if (ue_stats) ue_stats->dlsch_sliding_cnt++;

  if (dlsch_harq->round == 0) {

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

974 975 976 977 978 979 980
    if (eNB->mac_enabled==1) {
      if (ra_flag == 0) {
	DLSCH_pdu = mac_xface->get_dlsch_sdu(eNB->Mod_id,
					     eNB->CC_id,
					     frame,
					     dlsch->rnti,
					     0);
knopp's avatar
knopp committed
981
      }
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
      else {
	int16_t crnti = mac_xface->fill_rar(eNB->Mod_id,
					    eNB->CC_id,
					    frame,
					    DLSCH_pdu_rar,
					    fp->N_RB_UL,
					    input_buffer_length);
	DLSCH_pdu = DLSCH_pdu_rar;

	int UE_id;

	if (crnti!=0) 
	  UE_id = add_ue(crnti,eNB);
	else 
	  UE_id = -1;
997
	    
998 999 1000 1001 1002 1003 1004 1005 1006 1007
	if (UE_id==-1) {
	  LOG_W(PHY,"[eNB] Max user count reached.\n");
	  mac_xface->cancel_ra_proc(eNB->Mod_id,
				    eNB->CC_id,
				    frame,
				    crnti);
	} else {
	  eNB->UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE;
	  // Initialize indicator for first SR (to be cleared after ConnectionSetup is acknowledged)
	  eNB->first_sr[(uint32_t)UE_id] = 1;
1008
	      
1009 1010
	  generate_eNB_ulsch_params_from_rar(DLSCH_pdu,
					     frame,
1011
					     subframe,
1012 1013
					     eNB->ulsch[(uint32_t)UE_id],
					     fp);
1014
	      
1015 1016 1017 1018 1019 1020
	  LOG_D(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n",
		frame,
		subframe,
		UE_id,
		eNB->ulsch[(uint32_t)UE_id]->Msg3_frame,
		eNB->ulsch[(uint32_t)UE_id]->Msg3_subframe);
Cedric Roux's avatar
Cedric Roux committed
1021

1022 1023 1024 1025 1026 1027 1028 1029 1030
          /* TODO: get rid of this hack. The problem is that the eNodeB may
           * sometimes wrongly generate PHICH because somewhere 'phich_active' was
           * not reset to 0, due to an unidentified reason. When adding this
           * resetting here the problem seems to disappear completely.
           */
          LOG_D(PHY, "hack: set phich_active to 0 for UE %d fsf %d %d all HARQs\n", UE_id, frame, subframe);
          for (i = 0; i < 8; i++)
            eNB->ulsch[(uint32_t)UE_id]->harq_processes[i]->phich_active = 0;

1031 1032 1033
          mac_xface->set_msg3_subframe(eNB->Mod_id, eNB->CC_id, frame, subframe, (uint16_t)crnti,
                                       eNB->ulsch[UE_id]->Msg3_frame, eNB->ulsch[UE_id]->Msg3_subframe);

Cedric Roux's avatar
Cedric Roux committed
1034 1035 1036
          T(T_ENB_PHY_MSG3_ALLOCATION, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
            T_INT(UE_id), T_INT((uint16_t)crnti), T_INT(1 /* 1 is for initial transmission*/),
            T_INT(eNB->ulsch[UE_id]->Msg3_frame), T_INT(eNB->ulsch[UE_id]->Msg3_subframe));
1037
	}
1038 1039 1040 1041 1042
	if (ue_stats) ue_stats->total_TBS_MAC += dlsch_harq->TBS;
      }
    }
    else {
      DLSCH_pdu = DLSCH_pdu_tmp;
1043
	  
1044 1045 1046
      for (i=0; i<input_buffer_length; i++)
	DLSCH_pdu[i] = (unsigned char)(taus()&0xff);
    }
1047 1048
	
#if defined(SMBV) 
1049

1050 1051 1052 1053 1054
    // Configures the data source of allocation (allocation is configured by DCI)
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",frame,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
      //          smbv_configure_datalist_for_user(smbv_fname, find_ue(dlsch->rnti,eNB)+1, DLSCH_pdu, input_buffer_length);
    }
1055

1056
#endif
1057 1058 1059