mbmssim.c 16.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * 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
 */

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include "SIMULATION/TOOLS/defs.h"
#include "SIMULATION/RF/defs.h"
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/vars.h"
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif
#include "SCHED/defs.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"

#ifdef XFORMS
42
#include "PHY/TOOLS/lte_phy_scope.h"
43
44
45
46
#endif //XFORMS


#include "OCG_vars.h"
47
#include "unitary_defs.h"
48
49


50
51
PHY_VARS_eNB *eNB;
PHY_VARS_UE *UE;
52
53
54
55


DCI1E_5MHz_2A_M10PRB_TDD_t  DLSCH_alloc_pdu2_1E[2];
#define UL_RB_ALLOC 0x1ff;
56
#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
57
58
int main(int argc, char **argv)
{
59
60
61

  char c;

62
  int i,l,l2,aa,aarx,k;
63
  double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0;
gauthier's avatar
gauthier committed
64
  uint8_t snr1set=0;
65
66
  double snr_step=1,input_snr_step=1;
  int **txdata;
67
68
69
  double s_re0[2*30720],s_im0[2*30720],s_re1[2*30720],s_im1[2*30720];
  double r_re0[2*30720],r_im0[2*30720],r_re1[2*30720],r_im1[2*30720];
  double *s_re[2]={s_re0,s_re1},*s_im[2]={s_im0,s_im1},*r_re[2]={r_re0,r_re1},*r_im[2]={r_im0,r_im1};
70
71
72
  double iqim = 0.0;
  int subframe=1;
  char fname[40];//, vname[40];
gauthier's avatar
gauthier committed
73
74
  uint8_t transmission_mode = 1,n_tx=1,n_rx=2;
  uint16_t Nid_cell=0;
75
76
77
78
79
80
81
82

  FILE *fd;

  int eNB_id = 0;
  unsigned char mcs=0,awgn_flag=0,round;

  int n_frames=1;
  channel_desc_t *eNB2UE;
gauthier's avatar
gauthier committed
83
84
  uint32_t nsymb,tx_lev,tx_lev_dB;
  uint8_t extended_prefix_flag=1;
85
86
87
  LTE_DL_FRAME_PARMS *frame_parms;
  int hold_channel=0;

88

gauthier's avatar
gauthier committed
89
  uint16_t NB_RB=25;
90
91

  int tdd_config=3;
92

93
94
95
96
97
98
  SCM_t channel_model=MBSFN;


  unsigned char *input_buffer;
  unsigned short input_buffer_length;
  unsigned int ret;
99
100
101

  unsigned int trials,errs[4]= {0,0,0,0}; //,round_trials[4]={0,0,0,0};

gauthier's avatar
gauthier committed
102
  uint8_t N_RB_DL=25,osf=1;
knopp's avatar
   
knopp committed
103
  uint32_t perfect_ce = 0;
104

105
  lte_frame_type_t frame_type = FDD;
106

107
  uint32_t Nsoft = 1827072;
108

109
  /*
110
#ifdef XFORMS
111
  FD_lte_phy_scope_ue *form_ue;
112
113
114
  char title[255];

  fl_initialize (&argc, argv, NULL, 0, 0);
115
  form_ue = create_lte_phy_scope_ue();
116
  sprintf (title, "LTE DL SCOPE UE");
117
  fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
118
#endif
119
  */
120
121
122

  logInit();
  number_of_cards = 1;
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

  while ((c = getopt (argc, argv, "ahA:Cp:n:s:S:t:x:y:z:N:F:R:O:dm:i:Y")) != -1) {
    switch (c) {
    case 'a':
      awgn_flag=1;
      break;

    case 'd':
      frame_type = 0;
      break;

    case 'n':
      n_frames = atoi(optarg);
      break;

    case 'm':
      mcs=atoi(optarg);
      break;

    case 's':
      snr0 = atof(optarg);
      msg("Setting SNR0 to %f\n",snr0);
      break;

    case 'i':
      input_snr_step = atof(optarg);
      break;

    case 'S':
      snr1 = atof(optarg);
      snr1set=1;
      msg("Setting SNR1 to %f\n",snr1);
      break;

    case 'p': // subframe no;
      subframe=atoi(optarg);
      break;

    case 'z':
      n_rx=atoi(optarg);

      if ((n_rx==0) || (n_rx>2)) {
        msg("Unsupported number of rx antennas %d\n",n_rx);
        exit(-1);
      }

      break;

    case 'N':
      Nid_cell = atoi(optarg);
      break;

    case 'R':
      N_RB_DL = atoi(optarg);

Florian Kaltenberger's avatar
Florian Kaltenberger committed
178
      if ((N_RB_DL!=6) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=100))  {
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        printf("Unsupported Bandwidth %d\n",N_RB_DL);
        exit(-1);
      }

      break;

    case 'O':
      osf = atoi(optarg);
      break;

    case 'Y':
      perfect_ce = 1;
      break;

    default:
    case 'h':
      printf("%s -h(elp) -p(subframe) -N cell_id -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -i snr increment -z RXant \n",argv[0]);
      printf("-h This message\n");
      printf("-a Use AWGN Channel\n");
      printf("-p Use extended prefix mode\n");
      printf("-d Use TDD\n");
      printf("-n Number of frames to simulate\n");
      printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB.  If n_frames is 1 then just SNR is simulated\n");
      printf("-S Ending SNR, runs from SNR0 to SNR1\n");
      printf("-t Delay spread for multipath channel\n");
      printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
      printf("-x Transmission mode (1,2,6 for the moment)\n");
      printf("-y Number of TX antennas used in eNB\n");
      printf("-z Number of RX antennas used in UE\n");
      printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
      printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
      printf("-N Nid_cell\n");
      printf("-R N_RB_DL\n");
      printf("-O oversampling factor (1,2,4,8,16)\n");
      printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
      printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
      printf("-f Output filename (.txt format) for Pe/SNR results\n");
      printf("-F Input filename (.txt format) for RX conformance testing\n");
      exit (-1);
      break;
219
    }
220
221
  }

222
223


224
225
226
227
228
229
230
  if (awgn_flag == 1)
    channel_model = AWGN;

  // check that subframe is legal for eMBMS

  if ((subframe == 0) || (subframe == 5) ||    // TDD and FDD SFn 0,5;
      ((frame_type == FDD) && ((subframe == 4) || (subframe == 9))) || // FDD SFn 4,9;
231
232
      ((frame_type == TDD ) && ((subframe<3) || (subframe==6))))    {  // TDD SFn 1,2,6;

233
234
    printf("Illegal subframe %d for eMBMS transmission (frame_type %d)\n",subframe,frame_type);
    exit(-1);
235
236
  }

237
238
239
  if (transmission_mode==2)
    n_tx=2;

240
241
242
243
244
245
246
247
248
249
250
  lte_param_init(n_tx,
		 n_rx,
		 transmission_mode,
		 extended_prefix_flag,
		 frame_type,
		 Nid_cell,
		 tdd_config,
		 N_RB_DL,
		 0,
		 osf,
		 perfect_ce);
251
252
253
254
255
256
257
258
259
260

  if (snr1set==0) {
    if (n_frames==1)
      snr1 = snr0+.1;
    else
      snr1 = snr0+5.0;
  }

  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);

261
  frame_parms = &eNB->frame_parms;
262
263

  if (awgn_flag == 0)
264
    sprintf(fname,"embms_%d_%d.m",mcs,N_RB_DL);
265
266
  else
    sprintf(fname,"embms_awgn_%d_%d.m",mcs,N_RB_DL);
267

268
269
270
271
272
  if (!(fd = fopen(fname,"w"))) {
    printf("Cannot open %s, check permissions\n",fname);
    exit(-1);
  }
	
273
274

  if (awgn_flag==0)
275
    fprintf(fd,"SNR_%d_%d=[];errs_mch_%d_%d=[];mch_trials_%d_%d=[];\n",
276
277
278
            mcs,N_RB_DL,
            mcs,N_RB_DL,
            mcs,N_RB_DL);
279
280
  else
    fprintf(fd,"SNR_awgn_%d_%d=[];errs_mch_awgn_%d_%d=[];mch_trials_awgn_%d_%d=[];\n",
281
282
283
284
            mcs,N_RB_DL,
            mcs,N_RB_DL,
            mcs,N_RB_DL);

285
286
  fflush(fd);

287
  txdata = eNB->common_vars.txdata[0];
288
289
290
291

  nsymb = 12;

  printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d, AWGN %d\n",NUMBER_OF_OFDM_CARRIERS,
292
         frame_parms->Ncp,frame_parms->samples_per_tti,nsymb,awgn_flag);
293

294
295
  eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
                                UE->frame_parms.nb_antennas_rx,
296
                                channel_model,
297
298
				N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
				N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
299
300
301
302
303
                                0,
                                0,
                                0);

  // Create transport channel structures for 2 transport blocks (MIMO)
304
  eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0);
305

306
  if (!eNB->dlsch_MCH) {
307
308
309
    printf("Can't get eNB dlsch structures\n");
    exit(-1);
  }
310

311
  UE->dlsch_MCH[0]  = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0);
312

313
314
315
316
317
318
319
320
321
322
  eNB->frame_parms.num_MBSFN_config = 1;
  eNB->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0;
  eNB->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0;
  eNB->frame_parms.MBSFN_config[0].fourFrames_flag = 0;
  eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes
  UE->frame_parms.num_MBSFN_config = 1;
  UE->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0;
  UE->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0;
  UE->frame_parms.MBSFN_config[0].fourFrames_flag = 0;
  UE->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes
323

324
325
  fill_eNB_dlsch_MCH(eNB,mcs,1,0);
  fill_UE_dlsch_MCH(UE,mcs,1,0,0);
326

327
  if (is_pmch_subframe(0,subframe,&eNB->frame_parms)==0) {
328
329
    printf("eNB is not configured for MBSFN in subframe %d\n",subframe);
    exit(-1);
330
  } else if (is_pmch_subframe(0,subframe,&UE->frame_parms)==0) {
331
    printf("UE is not configured for MBSFN in subframe %d\n",subframe);
332
    exit(-1);
333
334
335
  }


336
  input_buffer_length = eNB->dlsch_MCH->harq_processes[0]->TBS/8;
337
338
  input_buffer = (unsigned char *)malloc(input_buffer_length+4);
  memset(input_buffer,0,input_buffer_length+4);
339
340

  for (i=0; i<input_buffer_length+4; i++) {
341
342
343
344
345
    input_buffer[i]= (unsigned char)(taus()&0xff);
  }


  snr_step = input_snr_step;
346
347

  for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
348
349
350
    UE->proc.proc_rxtx[0].frame_tx=0;
    eNB->proc.proc_rxtx[0].frame_tx=0;
    eNB->proc.proc_rxtx[0].subframe_tx=subframe;
351

352
353
354
355
356
357
358
359
360
361
362
    errs[0]=0;
    errs[1]=0;
    errs[2]=0;
    errs[3]=0;
    /*
    round_trials[0] = 0;
    round_trials[1] = 0;
    round_trials[2] = 0;
    round_trials[3] = 0;*/
    printf("********************** SNR %f (step %f)\n",SNR,snr_step);

363
    for (trials = 0; trials<n_frames; trials++) {
364
365
366
      //        printf("Trial %d\n",trials);
      fflush(stdout);
      round=0;
367

368
369
370
      //if (trials%100==0)
      //eNB2UE[0]->first_run = 1;
      eNB2UE->first_run = 1;
371
372
      memset(&eNB->common_vars.txdataF[0][0][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
      generate_mch(eNB,&eNB->proc.proc_rxtx[0],input_buffer);
373

374

375
      PHY_ofdm_mod(eNB->common_vars.txdataF[0][0],        // input,
376
                   txdata[0],         // output
377
                   frame_parms->ofdm_symbol_size,
378
379
380
                   LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb,                 // number of symbols
                   frame_parms->nb_prefix_samples,               // number of prefix samples
                   CYCLIC_PREFIX);
381
382

      if (n_frames==1) {
383
384
385
386
        write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
                     nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
        //if (eNB->frame_parms.nb_antennas_tx>1)
        //write_output("txsigF1.m","txsF1", &eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
387
388
389
      }

      tx_lev = 0;
390

391
392
393
394
      for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
        tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa]
                                [subframe*eNB->frame_parms.samples_per_tti],
                                eNB->frame_parms.samples_per_tti);
395
      }
396

397
      tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
398

399
      if (n_frames==1) {
400
        printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
401
        //    write_output("txsig0.m","txs0", &eNB->common_vars.txdata[0][0][subframe* eNB->frame_parms.samples_per_tti],
402

403
        //     eNB->frame_parms.samples_per_tti,1,1);
404
      }
405

406

407
      for (i=0; i<2*frame_parms->samples_per_tti; i++) {
408
409
410
        for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
          s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
          s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
411
        }
412
      }
413

414
415
      //Multipath channel
      multipath_channel(eNB2UE,s_re,s_im,r_re,r_im,
416
417
                        2*frame_parms->samples_per_tti,hold_channel);

418
      //AWGN
419
      sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(NB_RB*12)) - SNR;
420
      sigma2 = pow(10,sigma2_dB/10);
421

422
      if (n_frames==1)
423
424
        printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB);

425
      for (i=0; i<2*frame_parms->samples_per_tti; i++) {
426
        for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
427
          //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
428
          ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
429
            (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
430
          ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
431
432
            (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
        }
433
434
      }

435
436
      for (l=2; l<12; l++) {

437
        slot_fep_mbsfn(UE,
438
439
440
441
                       l,
                       subframe%10,
                       0,
                       0);
442
	if (UE->perfect_ce==1) {
443
	  // fill in perfect channel estimates
444
	  freq_channel(eNB2UE,UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
445
446
447
448
	  for(k=0; k<NUMBER_OF_eNB_MAX; k++) {
	    for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
	      for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
		for (i=0; i<frame_parms->N_RB_DL*12; i++) {
449
450
		  ((int16_t *) UE->common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
		  ((int16_t *) UE->common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
451
452
453
454
455
		}
	      }
	    }
	  }
	}
456
457
458

	if (l==6)
          for (l2=2;l2<7;l2++)
459
	    rx_pmch(UE,
460
461
462
463
464
		    0,
		    subframe%10,
		    l2);
	if (l==6)
          for (l2=2;l2<7;l2++)
465
	    rx_pmch(UE,
466
467
468
469
470
		    0,
		    subframe%10,
		    l2);
	if (l==11)
          for (l2=7;l2<12;l2++)
471
	    rx_pmch(UE,
472
473
474
		    0,
		    subframe%10,
		    l2);
475
476
      }

477
478
479
480
      UE->dlsch_MCH[0]->harq_processes[0]->G = get_G(&UE->frame_parms,
          UE->dlsch_MCH[0]->harq_processes[0]->nb_rb,
          UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
          get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs),
481
          1,2,
482
483
484
485
486
487
488
489
490
491
492
493
          UE->proc.proc_rxtx[0].frame_tx,subframe);
      UE->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs);

      dlsch_unscrambling(&UE->frame_parms,1,UE->dlsch_MCH[0],
                         UE->dlsch_MCH[0]->harq_processes[0]->G,
                         UE->pdsch_vars_MCH[0]->llr[0],0,subframe<<1);

      ret = dlsch_decoding(UE,
                           UE->pdsch_vars_MCH[0]->llr[0],
                           &UE->frame_parms,
                           UE->dlsch_MCH[0],
                           UE->dlsch_MCH[0]->harq_processes[0],
494
495
496
                           subframe,
                           0,0,0);

497
      if (n_frames==1)
498
499
        printf("MCH decoding returns %d\n",ret);

500
      if (ret == (1+UE->dlsch_MCH[0]->max_turbo_iterations))
501
502
        errs[0]++;

503
504
      UE->proc.proc_rxtx[0].frame_tx++;
      eNB->proc.proc_rxtx[0].frame_tx++;
505
    }
506

507
508
509
    printf("errors %d/%d (Pe %e)\n",errs[round],trials,(double)errs[round]/trials);

    if (awgn_flag==0)
knopp's avatar
   
knopp committed
510
      fprintf(fd,"SNR_%d_%d = [SNR_%d_%d %f]; errs_mch_%d_%d =[errs_mch_%d_%d  %d]; mch_trials_%d_%d =[mch_trials_%d_%d  %d];\n",
511
512
513
              mcs,N_RB_DL,mcs,N_RB_DL,SNR,
              mcs,N_RB_DL,mcs,N_RB_DL,errs[0],
              mcs,N_RB_DL,mcs,N_RB_DL,trials);
514
    else
Cedric Roux's avatar
Cedric Roux committed
515
516
517
518
      fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %f]; errs_mch_awgn_%d =[errs_mch_awgn_%d  %d]; mch_trials_awgn_%d =[mch_trials_awgn_%d %d];\n",
              N_RB_DL,N_RB_DL,SNR,
              N_RB_DL,N_RB_DL,errs[0],
              N_RB_DL,N_RB_DL,trials);
519

520
    fflush(fd);
521

522
523
    if (errs[0] == 0)
      break;
524
  }
525
526
527


  if (n_frames==1) {
528
529
530
    printf("Dumping PMCH files ( G %d)\n",UE->dlsch_MCH[0]->harq_processes[0]->G);
    dump_mch(UE,0,
             UE->dlsch_MCH[0]->harq_processes[0]->G,
531
             subframe);
532
  }
533

534
  printf("Freeing dlsch structures\n");
535
536
  free_eNB_dlsch(eNB->dlsch_MCH);
  free_ue_dlsch(UE->dlsch_MCH[0]);
537
538

  fclose(fd);
539

540
  return(0);
541
542
}