Пример #1
0
int main(int argc, char **argv) {
  uint32_t cfi;
  float cfi_corr; 
  int n;

  if (argc < 3) {
    usage(argv[0]);
    exit(-1);
  }

  parse_args(argc,argv);

  if (base_init()) {
    fprintf(stderr, "Error initializing receiver\n");
    exit(-1);
  }

  n = filesource_read(&fsrc, input_buffer, flen);

  lte_fft_run_sf(&fft, input_buffer, fft_buffer);

  if (fmatlab) {
    fprintf(fmatlab, "infft=");
    vec_fprint_c(fmatlab, input_buffer, flen);
    fprintf(fmatlab, ";\n");

    fprintf(fmatlab, "outfft=");
    vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
    vec_fprint_c(fmatlab, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
    fprintf(fmatlab, ";\n");
    vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer,   CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
  }

  /* Get channel estimates for each port */
  chest_dl_estimate(&chest, fft_buffer, ce, 0);

  INFO("Decoding PCFICH\n", 0);

  
  n = pcfich_decode(&pcfich, fft_buffer, ce, chest_dl_get_noise_estimate(&chest),  0, &cfi, &cfi_corr);
  printf("cfi: %d, distance: %f\n", cfi, cfi_corr);

  base_free();

  if (n < 0) {
    fprintf(stderr, "Error decoding PCFICH\n");
    exit(-1);
  } else if (n == 0) {
    printf("Could not decode PCFICH\n");
    exit(-1);
  } else {
    if (cfi_corr > 2.8 && cfi == 1) {
      exit(0);
    } else {
      exit(-1);
    }
  }
}
Пример #2
0
int main(int argc, char **argv) {
  pbch_mib_t mib;
  int n;

  if (argc < 3) {
    usage(argv[0]);
    exit(-1);
  }

  parse_args(argc,argv);

  if (base_init()) {
    fprintf(stderr, "Error initializing receiver\n");
    exit(-1);
  }

  n = filesource_read(&fsrc, input_buffer, FLEN);

  lte_fft_run_sf(&fft, input_buffer, fft_buffer);

  if (fmatlab) {
    fprintf(fmatlab, "outfft=");
    vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
    vec_fprint_c(fmatlab, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
    fprintf(fmatlab, ";\n");
    vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer,   CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
  }

  /* Get channel estimates for each port */
  chest_ce_sf(&chest, fft_buffer, ce, 0);

  INFO("Decoding PBCH\n", 0);

  n = pbch_decode(&pbch, fft_buffer, ce, &mib);

  base_free();

  if (n < 0) {
    fprintf(stderr, "Error decoding PBCH\n");
    exit(-1);
  } else if (n == 0) {
    printf("Could not decode PBCH\n");
    exit(-1);
  } else {
    if (mib.nof_ports == 2 && mib.nof_prb == 50 && mib.phich_length == PHICH_NORM
        && mib.phich_resources == R_1 && mib.sfn == 28) {
      pbch_mib_fprint(stdout, &mib, cell.id);
      printf("This is the signal.1.92M.dat file\n");
      exit(0);
    } else {
      pbch_mib_fprint(stdout, &mib, cell.id);
      printf("This is an unknown file\n");
      exit(-1);
    }
  }
}
Пример #3
0
/** 36.211 10.3 section 6.11.1.2
 */
void pss_put_slot(cf_t *pss_signal, cf_t *slot, uint32_t nof_prb, lte_cp_t cp) {
  int k;
  k = (CP_NSYMB(cp) - 1) * nof_prb * RE_X_RB + nof_prb * RE_X_RB / 2 - 31;
  memset(&slot[k - 5], 0, 5 * sizeof(cf_t));
  memcpy(&slot[k], pss_signal, PSS_LEN * sizeof(cf_t));
  memset(&slot[k + PSS_LEN], 0, 5 * sizeof(cf_t));
}
Пример #4
0
int chest_init_LTEDL(chest_t *q, lte_cell_t cell) {
  int ret; 
  ret = chest_init(q, cell.nof_prb * RE_X_RB, CP_NSYMB(cell.cp), cell.nof_ports);
  if (ret != LIBLTE_SUCCESS) {
    return ret;
  } else {
    return chest_ref_LTEDL(q, cell);    
  }
}
Пример #5
0
/** 36.211 10.3 section 6.11.2.2
 */
void sss_put_slot(float *sss, cf_t *slot, uint32_t nof_prb, lte_cp_t cp) {
  uint32_t i, k;

  k = (CP_NSYMB(cp) - 2) * nof_prb * RE_X_RB + nof_prb * RE_X_RB / 2 - 31;
  
  if (k > 5) {
    memset(&slot[k - 5], 0, 5 * sizeof(cf_t));
    for (i = 0; i < SSS_LEN; i++) {
      __real__ slot[k + i] = sss[i];
      __imag__ slot[k + i] = 0;
    }
    memset(&slot[k + SSS_LEN], 0, 5 * sizeof(cf_t));
  }
}
Пример #6
0
int chest_init(chest_t *q, chest_interp_t interp, lte_cp_t cp, int nof_prb, int nof_ports) {

	if (nof_ports > MAX_PORTS) {
		fprintf(stderr, "Error: Maximum ports %d\n", MAX_PORTS);
		return -1;
	}
	bzero(q, sizeof(chest_t));

	q->nof_ports = nof_ports;
	q->nof_symbols = CP_NSYMB(cp);
	q->cp = cp;
	q->nof_prb = nof_prb;

	switch(interp) {
	case LINEAR:
		q->interp = interp_linear_offset;
	}

	INFO("Initializing channel estimator size %dx%d, nof_ports=%d\n",
			q->nof_symbols, nof_prb, nof_ports);

	return 0;
}
Пример #7
0
/* the gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  int i;
  lte_cell_t cell; 
  chest_dl_t chest;
  precoding_t cheq; 
  cf_t *input_signal = NULL, *output_signal[MAX_LAYERS]; 
  cf_t *output_signal2 = NULL;
  cf_t *ce[MAX_PORTS]; 
  double *outr0=NULL, *outi0=NULL;
  double *outr1=NULL, *outi1=NULL;
  double *outr2=NULL, *outi2=NULL;
  
  if (nrhs < NOF_INPUTS) {
    help();
    return;
  }

  if (!mxIsDouble(CELLID) && mxGetN(CELLID) != 1 && 
      !mxIsDouble(PORTS) && mxGetN(PORTS) != 1 && 
      mxGetM(CELLID) != 1) {
    help();
    return;
  }

  cell.id = (uint32_t) *((double*) mxGetPr(CELLID));
  cell.nof_prb = mxGetM(INPUT)/RE_X_RB;
  cell.nof_ports = (uint32_t) *((double*) mxGetPr(PORTS)); 
  if ((mxGetN(INPUT)%14) == 0) {
    cell.cp = CPNORM;    
  } else if ((mxGetN(INPUT)%12)!=0) {
    cell.cp = CPEXT;
  } else {
    mexErrMsgTxt("Invalid number of symbols\n");
    help();
    return;
  }
  
  if (chest_dl_init(&chest, cell)) {
    mexErrMsgTxt("Error initiating channel estimator\n");
    return;
  }
  
  int nsubframes;
  if (cell.cp == CPNORM) {
    nsubframes = mxGetN(INPUT)/14;
  } else {
    nsubframes = mxGetN(INPUT)/12;
  }
  
  uint32_t sf_idx=0; 
  if (nsubframes == 1) {
    if (nrhs != NOF_INPUTS+1) {
      mexErrMsgTxt("Received 1 subframe. Need to provide subframe index.\n");
      help();
      return;
    }
    sf_idx = (uint32_t) *((double*) mxGetPr(SFIDX));
  } else {
    if (nrhs != NOF_INPUTS) {
      help();
      return;
    }
  }
    
  uint32_t filter_len = 0;
  float *filter; 
  double *f; 
  
  filter_len = mxGetNumberOfElements(FREQ_FILTER);
  filter = malloc(sizeof(float) * filter_len);
  f = (double*) mxGetPr(FREQ_FILTER);
  for (i=0;i<filter_len;i++) {
    filter[i] = (float) f[i];
  }

  chest_dl_set_filter_freq(&chest, filter, filter_len);

  filter_len = mxGetNumberOfElements(TIME_FILTER);
  filter = malloc(sizeof(float) * filter_len);
  f = (double*) mxGetPr(TIME_FILTER);
  for (i=0;i<filter_len;i++) {
    filter[i] = (float) f[i];
  }
  chest_dl_set_filter_time(&chest, filter, filter_len);
  


  double *inr=(double *)mxGetPr(INPUT);
  double *ini=(double *)mxGetPi(INPUT);
  
  /** Allocate input buffers */
  int nof_re = 2*CP_NSYMB(cell.cp)*cell.nof_prb*RE_X_RB;
  for (i=0;i<MAX_PORTS;i++) {
    ce[i] = vec_malloc(nof_re * sizeof(cf_t));
  }
  input_signal = vec_malloc(nof_re * sizeof(cf_t));
  for (i=0;i<MAX_PORTS;i++) {
    output_signal[i] = vec_malloc(nof_re * sizeof(cf_t));
  }
  output_signal2 = vec_malloc(nof_re * sizeof(cf_t));
  
  precoding_init(&cheq, nof_re);
  
  /* Create output values */
  if (nlhs >= 1) {
    plhs[0] = mxCreateDoubleMatrix(nof_re * nsubframes, cell.nof_ports, mxCOMPLEX);
    outr0 = mxGetPr(plhs[0]);
    outi0 = mxGetPi(plhs[0]);
  }  
  if (nlhs >= 2) {
    plhs[1] = mxCreateDoubleMatrix(REFSIGNAL_MAX_NUM_SF(cell.nof_prb)*nsubframes, cell.nof_ports, mxCOMPLEX);
    outr1 = mxGetPr(plhs[1]);
    outi1 = mxGetPi(plhs[1]);
  }
  if (nlhs >= 3) {
    plhs[2] = mxCreateDoubleMatrix(nof_re * nsubframes, 1,  mxCOMPLEX);
    outr2 = mxGetPr(plhs[2]);
    outi2 = mxGetPi(plhs[2]);
  }
    
  for (int sf=0;sf<nsubframes;sf++) {
    /* Convert input to C complex type */
    for (i=0;i<nof_re;i++) {
      __real__ input_signal[i] = (float) *inr;
      if (ini) {
        __imag__ input_signal[i] = (float) *ini;
      }
      inr++;
      ini++;
    }
    
    if (nsubframes != 1) {
      sf_idx = sf%10;
    }
    
    if (chest_dl_estimate(&chest, input_signal, ce, sf_idx)) {
      mexErrMsgTxt("Error running channel estimator\n");
      return;
    }    
       
    if (cell.nof_ports == 1) {
      predecoding_single(&cheq, input_signal, ce[0], output_signal2, nof_re, chest_dl_get_noise_estimate(&chest));            
    } else {
      predecoding_diversity(&cheq, input_signal, ce, output_signal, cell.nof_ports, nof_re, chest_dl_get_noise_estimate(&chest));
      layerdemap_diversity(output_signal, output_signal2, cell.nof_ports, nof_re/cell.nof_ports);
    }
    
    if (nlhs >= 1) { 
      for (int j=0;j<cell.nof_ports;j++) {
        for (i=0;i<nof_re;i++) {      
          *outr0 = (double) crealf(ce[j][i]);
          if (outi0) {
            *outi0 = (double) cimagf(ce[j][i]);
          }
          outr0++;
          outi0++;
        } 
      }
    }
    if (nlhs >= 2) {    
      for (int j=0;j<cell.nof_ports;j++) {
        for (i=0;i<REFSIGNAL_NUM_SF(cell.nof_prb,j);i++) {
          *outr1 = (double) crealf(chest.pilot_estimates_average[j][i]);
          if (outi1) {
            *outi1 = (double) cimagf(chest.pilot_estimates_average[j][i]);
          }
          outr1++;
          outi1++;
        }
      }    
    }
    if (nlhs >= 3) {
      for (i=0;i<nof_re;i++) {      
        *outr2 = (double) crealf(output_signal2[i]);
        if (outi2) {
          *outi2 = (double) cimagf(output_signal2[i]);
        }
        outr2++;
        outi2++;
      }
    }
  }

  if (nlhs >= 4) {
    plhs[3] = mxCreateDoubleScalar(chest_dl_get_snr(&chest));
  }
  if (nlhs >= 5) {
    plhs[4] = mxCreateDoubleScalar(chest_dl_get_noise_estimate(&chest));
  }
  if (nlhs >= 6) {
    plhs[5] = mxCreateDoubleScalar(chest_dl_get_rsrp(&chest));
  }
  
  chest_dl_free(&chest);
  precoding_free(&cheq);

  return;
}
Пример #8
0
int base_init() {
  int i;

  if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) {
    fprintf(stderr, "Error opening file %s\n", input_file_name);
    exit(-1);
  }

  if (matlab_file_name) {
    fmatlab = fopen(matlab_file_name, "w");
    if (!fmatlab) {
      perror("fopen");
      return -1;
    }
  } else {
    fmatlab = NULL;
  }

  input_buffer = malloc(FLEN * sizeof(cf_t));
  if (!input_buffer) {
    perror("malloc");
    exit(-1);
  }

  fft_buffer = malloc(2 * CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB * sizeof(cf_t));
  if (!fft_buffer) {
    perror("malloc");
    return -1;
  }

  for (i=0;i<cell.nof_ports;i++) {
    ce[i] = malloc(2 * CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB * sizeof(cf_t));
    if (!ce[i]) {
      perror("malloc");
      return -1;
    }
  }
  
  if (!lte_cell_isvalid(&cell)) {
    fprintf(stderr, "Invalid cell properties\n");
    return -1;
  }

  if (chest_init_LTEDL(&chest, cell)) {
    fprintf(stderr, "Error initializing equalizer\n");
    return -1;
  }

  if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) {
    fprintf(stderr, "Error initializing FFT\n");
    return -1;
  }

  if (pbch_init(&pbch, cell)) {
    fprintf(stderr, "Error initiating PBCH\n");
    return -1;
  }

  DEBUG("Memory init OK\n",0);
  return 0;
}
Пример #9
0
int main(int argc, char **argv) {
  ra_pdsch_t ra_dl;
  int i;
  int nof_frames;
  int ret;
  char *data;
  dci_location_t locations[10];
  uint32_t nof_locations;
  dci_msg_t dci_msg; 
  
  data = malloc(10000);

  if (argc < 3) {
    usage(argv[0]);
    exit(-1);
  }

  parse_args(argc,argv);

  if (base_init()) {
    fprintf(stderr, "Error initializing memory\n");
    exit(-1);
  }

  if (rnti == SIRNTI) {
    INFO("Initializing common search space for SI-RNTI\n",0);
    nof_locations = pdcch_common_locations(&pdcch, locations, 10, cfi);
  } else {
    // For ue-specific, generate locations for subframe 5
    INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);
    nof_locations = pdcch_ue_locations(&pdcch, locations, 10, 5, cfi, rnti); 
  }
  
  ret = -1;
  nof_frames = 0;
  do {
    filesource_read(&fsrc, input_buffer, flen);
    if (nof_frames == 5) {
      INFO("Reading %d samples sub-frame %d\n", flen, nof_frames);

      lte_fft_run_sf(&fft, input_buffer, fft_buffer);

      if (fmatlab) {
        fprintf(fmatlab, "infft%d=", nof_frames);
        vec_fprint_c(fmatlab, input_buffer, flen);
        fprintf(fmatlab, ";\n");

        fprintf(fmatlab, "outfft%d=", nof_frames);
        vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
        vec_fprint_c(fmatlab, fft_buffer, CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
        fprintf(fmatlab, ";\n");
        vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer,  CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB);
      }

      /* Get channel estimates for each port */
      for (i=0;i<cell.nof_ports;i++) {
        chest_ce_slot_port(&chest, fft_buffer, ce[i], 2*nof_frames, i);
        chest_ce_slot_port(&chest, &fft_buffer[CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB],
            &ce[i][CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB], 2*nof_frames+1, i);
        if (fmatlab) {
          chest_fprint(&chest, fmatlab, 2*nof_frames+1, i);
        }
      }
      
      
      uint16_t crc_rem = 0;
      for (i=0;i<nof_locations && crc_rem != rnti;i++) {
        if (pdcch_extract_llr(&pdcch, fft_buffer, ce, locations[i], nof_frames, cfi)) {
          fprintf(stderr, "Error extracting LLRs\n");
          return -1;
        }
        if (pdcch_decode_msg(&pdcch, &dci_msg, Format1A, &crc_rem)) {
          fprintf(stderr, "Error decoding DCI msg\n");
          return -1;
        }
      }
      
      if (crc_rem == rnti) {
        if (dci_msg_to_ra_dl(&dci_msg, rnti, 1234, cell, cfi, &ra_dl)) {
          fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
          goto goout;
        }
        if (pdsch_harq_setup(&harq_process, ra_dl.mcs, &ra_dl.prb_alloc)) {
          fprintf(stderr, "Error configuring HARQ process\n");
          goto goout;
        }
        if (pdsch_decode(&pdsch, fft_buffer, ce, data, nof_frames%10, &harq_process, ra_dl.rv_idx)) {
          fprintf(stderr, "Error decoding PDSCH\n");
          goto goout;
        } else {
          printf("PDSCH Decoded OK!\n");
        }
      }
    }

    nof_frames++;
  } while (nof_frames <= max_frames);

  ret = 0;

goout:
  base_free();
  exit(ret);
}
Пример #10
0
int base_init() {
  int i;

  if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) {
    fprintf(stderr, "Error opening file %s\n", input_file_name);
    exit(-1);
  }

  if (matlab_file_name) {
    fmatlab = fopen(matlab_file_name, "w");
    if (!fmatlab) {
      perror("fopen");
      return -1;
    }
  } else {
    fmatlab = NULL;
  }

  flen = 2 * (SLOT_LEN(lte_symbol_sz(cell.nof_prb)));

  input_buffer = malloc(flen * sizeof(cf_t));
  if (!input_buffer) {
    perror("malloc");
    exit(-1);
  }

  fft_buffer = malloc(2 * CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB * sizeof(cf_t));
  if (!fft_buffer) {
    perror("malloc");
    return -1;
  }

  for (i=0;i<MAX_PORTS;i++) {
    ce[i] = malloc(2 * CP_NSYMB(cell.cp) * cell.nof_prb * RE_X_RB * sizeof(cf_t));
    if (!ce[i]) {
      perror("malloc");
      return -1;
    }
  }

  if (chest_init_LTEDL(&chest, cell)) {
    fprintf(stderr, "Error initializing equalizer\n");
    return -1;
  }

  if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) {
    fprintf(stderr, "Error initializing FFT\n");
    return -1;
  }

  if (regs_init(&regs, R_1, PHICH_NORM, cell)) {
    fprintf(stderr, "Error initiating regs\n");
    return -1;
  }

  if (regs_set_cfi(&regs, cfi)) {
    fprintf(stderr, "Error setting CFI %d\n", cfi);
    return -1;
  }

  if (pdcch_init(&pdcch, &regs, cell)) {
    fprintf(stderr, "Error creating PDCCH object\n");
    exit(-1);
  }

  if (pdsch_init(&pdsch, cell)) {
    fprintf(stderr, "Error creating PDSCH object\n");
    exit(-1);
  }
  pdsch_set_rnti(&pdsch, rnti);
  
  if (pdsch_harq_init(&harq_process, &pdsch)) {
    fprintf(stderr, "Error initiating HARQ process\n");
    exit(-1);
  }

  DEBUG("Memory init OK\n",0);
  return 0;
}
Пример #11
0
int main(int argc, char **argv) {
	chest_t eq;
	cf_t *input = NULL, *ce = NULL, *h = NULL;
	refsignal_t refs;
	int i, j, n_port, n_slot, cid, num_re;
	int ret = -1;
	int max_cid;
	FILE *fmatlab = NULL;
	float mse_mag, mse_phase;

	parse_args(argc,argv);

	if (output_matlab) {
		fmatlab=fopen(output_matlab, "w");
		if (!fmatlab) {
			perror("fopen");
			goto do_exit;
		}
	}

	num_re = nof_prb * RE_X_RB * CP_NSYMB(cp);

	input = malloc(num_re * sizeof(cf_t));
	if (!input) {
		perror("malloc");
		goto do_exit;
	}
	h = malloc(num_re * sizeof(cf_t));
	if (!h) {
		perror("malloc");
		goto do_exit;
	}
	ce = malloc(num_re * sizeof(cf_t));
	if (!ce) {
		perror("malloc");
		goto do_exit;
	}

	if (cell_id == -1) {
		cid = 0;
		max_cid = 504;
	} else {
		cid = cell_id;
		max_cid = cell_id;
	}
	while(cid <= max_cid) {
		if (chest_init(&eq, LINEAR, cp, nof_prb, MAX_PORTS)) {
			fprintf(stderr, "Error initializing equalizer\n");
			goto do_exit;
		}

		if (chest_ref_LTEDL(&eq, cid)) {
			fprintf(stderr, "Error initializing reference signal\n");
			goto do_exit;
		}

		for (n_slot=0;n_slot<NSLOTS_X_FRAME;n_slot++) {
			for (n_port=0;n_port<MAX_PORTS;n_port++) {

				if (refsignal_init_LTEDL(&refs, n_port, n_slot, cid, cp, nof_prb)) {
					fprintf(stderr, "Error initiating CRS slot=%d\n", i);
					return -1;
				}

				bzero(input, sizeof(cf_t) * num_re);
				for (i=0;i<num_re;i++) {
					input[i] = 0.5-rand()/RAND_MAX+I*(0.5-rand()/RAND_MAX);
				}

				bzero(ce, sizeof(cf_t) * num_re);
				bzero(h, sizeof(cf_t) * num_re);

				refsignal_put(&refs, input);

				refsignal_free(&refs);

				for (i=0;i<CP_NSYMB(cp);i++) {
					for (j=0;j<nof_prb * RE_X_RB;j++) {
						float x = -1+(float) i/CP_NSYMB(cp) + cosf(2 * M_PI * (float) j/nof_prb/RE_X_RB);
						h[i*nof_prb * RE_X_RB+j] = (3+x) * cexpf(I * x);
						input[i*nof_prb * RE_X_RB+j] *= h[i*nof_prb * RE_X_RB+j];
					}
				}

				chest_ce_slot_port(&eq, input, ce, n_slot, n_port);

				mse_mag = mse_phase = 0;
				for (i=0;i<num_re;i++) {
					mse_mag += (cabsf(h[i]) - cabsf(ce[i])) * (cabsf(h[i]) - cabsf(ce[i])) / num_re;
					mse_phase += (cargf(h[i]) - cargf(ce[i])) * (cargf(h[i]) - cargf(ce[i])) / num_re;
				}

				if (check_mse(mse_mag, mse_phase, n_port)) {
					goto do_exit;
				}

				if (fmatlab) {
					fprintf(fmatlab, "input=");
					vec_fprint_c(fmatlab, input, num_re);
					fprintf(fmatlab, ";\n");
					fprintf(fmatlab, "h=");
					vec_fprint_c(fmatlab, h, num_re);
					fprintf(fmatlab, ";\n");
					fprintf(fmatlab, "ce=");
					vec_fprint_c(fmatlab, ce, num_re);
					fprintf(fmatlab, ";\n");
					chest_fprint(&eq, fmatlab, n_slot, n_port);
				}
			}
		}
		chest_free(&eq);
		cid+=10;
		INFO("cid=%d\n", cid);
	}


	ret = 0;

do_exit:

	if (ce) {
		free(ce);
	}
	if (input) {
		free(input);
	}
	if (h) {
		free(h);
	}

	if (!ret) {
		printf("OK\n");
	} else {
		printf("Error at cid=%d, slot=%d, port=%d\n",cid, n_slot, n_port);
	}

	exit(ret);
}
Пример #12
0
int main(int argc, char **argv) {
	int distance;
	int i, n;
	int ngroup, nseq, max_nseq;
	char ack_rx;

	if (argc < 3) {
		usage(argv[0]);
		exit(-1);
	}

	parse_args(argc,argv);

	max_nseq = CP_ISNORM(cp)?PHICH_NORM_NSEQUENCES:PHICH_EXT_NSEQUENCES;

	if (base_init()) {
		fprintf(stderr, "Error initializing memory\n");
		exit(-1);
	}

	n = filesource_read(&fsrc, input_buffer, flen);

	lte_fft_run(&fft, input_buffer, fft_buffer);

	if (fmatlab) {
		fprintf(fmatlab, "infft=");
		vec_fprint_c(fmatlab, input_buffer, flen);
		fprintf(fmatlab, ";\n");

		fprintf(fmatlab, "outfft=");
		vec_fprint_c(fmatlab, fft_buffer, CP_NSYMB(cp) * nof_prb * RE_X_RB);
		fprintf(fmatlab, ";\n");
	}

	/* Get channel estimates for each port */
	for (i=0;i<nof_ports;i++) {
		chest_ce_slot_port(&chest, fft_buffer, ce[i], 0, i);
		if (fmatlab) {
			chest_fprint(&chest, fmatlab, 0, i);
		}
	}

	INFO("Decoding PHICH\n", 0);

	/* Receive all PHICH groups and sequence numbers */
	for (ngroup=0;ngroup<phich_ngroups(&phich);ngroup++) {
		for (nseq=0;nseq<max_nseq;nseq++) {

			if (phich_decode(&phich, fft_buffer, ce, ngroup, nseq, numsubframe, &ack_rx, &distance)<0) {
				printf("Error decoding ACK\n");
				exit(-1);
			}

			INFO("%d/%d, ack_rx: %d, ns: %d, distance: %d\n",
					ngroup, nseq, ack_rx, numsubframe, distance);
		}
	}

	base_free();
	fftwf_cleanup();

	if (n < 0) {
		fprintf(stderr, "Error decoding phich\n");
		exit(-1);
	} else if (n == 0) {
		printf("Could not decode phich\n");
		exit(-1);
	} else {
		exit(0);
	}
}
Пример #13
0
int base_init() {
	int i;

	if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) {
		fprintf(stderr, "Error opening file %s\n", input_file_name);
		exit(-1);
	}

	if (matlab_file_name) {
		fmatlab = fopen(matlab_file_name, "w");
		if (!fmatlab) {
			perror("fopen");
			return -1;
		}
	} else {
		fmatlab = NULL;
	}

	flen = SLOT_LEN(lte_symbol_sz(nof_prb), cp);

	input_buffer = malloc(flen * sizeof(cf_t));
	if (!input_buffer) {
		perror("malloc");
		exit(-1);
	}

	fft_buffer = malloc(CP_NSYMB(cp) * nof_prb * RE_X_RB * sizeof(cf_t));
	if (!fft_buffer) {
		perror("malloc");
		return -1;
	}

	for (i=0;i<MAX_PORTS_CTRL;i++) {
		ce[i] = malloc(CP_NSYMB(cp) * nof_prb * RE_X_RB * sizeof(cf_t));
		if (!ce[i]) {
			perror("malloc");
			return -1;
		}
	}

	if (chest_init(&chest, LINEAR, cp, nof_prb, nof_ports)) {
		fprintf(stderr, "Error initializing equalizer\n");
		return -1;
	}

	if (chest_ref_LTEDL(&chest, cell_id)) {
		fprintf(stderr, "Error initializing reference signal\n");
		return -1;
	}

	if (lte_fft_init(&fft, cp, nof_prb)) {
		fprintf(stderr, "Error initializing FFT\n");
		return -1;
	}

	if (regs_init(&regs, cell_id, nof_prb, nof_ports, phich_res, phich_length, cp)) {
		fprintf(stderr, "Error initiating regs\n");
		return -1;
	}

	if (phich_init(&phich, &regs, cell_id, nof_prb, nof_ports, cp)) {
		fprintf(stderr, "Error creating PBCH object\n");
		return -1;
	}

	DEBUG("Memory init OK\n",0);
	return 0;
}
Пример #14
0
/** Converts the MIB message to symbols mapped to SLOT #1 ready for transmission
 */
int pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *sf_symbols[MAX_PORTS]) {
  int i;
  int nof_bits;
  cf_t *slot1_symbols[MAX_PORTS];
  cf_t *x[MAX_LAYERS];
  
  if (q                 != NULL &&
      mib               != NULL)
  {
    for (i=0;i<q->cell.nof_ports;i++) {
      if (sf_symbols[i] == NULL) {
        return LIBLTE_ERROR_INVALID_INPUTS;
      } else {
        slot1_symbols[i] = &sf_symbols[i][q->cell.nof_prb * RE_X_RB * CP_NSYMB(q->cell.cp)];
      }
    }
    /* Set pointers for layermapping & precoding */
    nof_bits = 2 * q->nof_symbols;

    /* number of layers equals number of ports */
    for (i = 0; i < q->cell.nof_ports; i++) {
      x[i] = q->pbch_x[i];
    }
    memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports));
    
    if (q->frame_idx == 0) {
      /* pack MIB */
      pbch_mib_pack(mib, q->data);

      /* encode & modulate */
      crc_attach(&q->crc, q->data, 24);
      crc_set_mask(q->data, q->cell.nof_ports);

      convcoder_encode(&q->encoder, q->data, q->data_enc, 40);

      rm_conv_tx(q->data_enc, 120, q->pbch_rm_b, 4 * nof_bits);

    }

    scrambling_b_offset(&q->seq_pbch, &q->pbch_rm_b[q->frame_idx * nof_bits],
        q->frame_idx * nof_bits, nof_bits);
    mod_modulate(&q->mod, &q->pbch_rm_b[q->frame_idx * nof_bits], q->pbch_d,
        nof_bits);

    /* layer mapping & precoding */
    if (q->cell.nof_ports > 1) {
      layermap_diversity(q->pbch_d, x, q->cell.nof_ports, q->nof_symbols);
      precoding_diversity(x, q->pbch_symbols, q->cell.nof_ports,
          q->nof_symbols / q->cell.nof_ports);
    } else {
      memcpy(q->pbch_symbols[0], q->pbch_d, q->nof_symbols * sizeof(cf_t));
    }

    /* mapping to resource elements */
    for (i = 0; i < q->cell.nof_ports; i++) {
      pbch_put(q->pbch_symbols[i], slot1_symbols[i], q->cell);
    }
    q->frame_idx++;
    if (q->frame_idx == 4) {
      q->frame_idx = 0;
    }
    return LIBLTE_SUCCESS;
  } else {
    return LIBLTE_ERROR_INVALID_INPUTS;
  }
}
Пример #15
0
/* Decodes the PBCH channel
 *
 * The PBCH spans in 40 ms. This function is called every 10 ms. It tries to decode the MIB
 * given the symbols of a subframe (1 ms). Successive calls will use more subframes
 * to help the decoding process.
 *
 * Returns 1 if successfully decoded MIB, 0 if not and -1 on error
 */
int pbch_decode(pbch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], pbch_mib_t *mib) {
  uint32_t src, dst, nb;
  uint32_t nant_[3] = { 1, 2, 4 };
  uint32_t na, nant;
  cf_t *slot1_symbols;
  int i;
  int nof_bits;
  cf_t *x[MAX_LAYERS];
  cf_t *ce_slot[MAX_PORTS];
  
  int ret = LIBLTE_ERROR_INVALID_INPUTS;
  
  if (q                 != NULL &&
      sf_symbols        != NULL && 
      mib               != NULL)
  {
    for (i=0;i<q->cell.nof_ports;i++) {
      if (ce[i] == NULL) {
        return LIBLTE_ERROR_INVALID_INPUTS;
      } else {
        ce_slot[i] = &ce[i][q->cell.nof_prb * RE_X_RB * CP_NSYMB(q->cell.cp)];
      }
    }
    slot1_symbols = &sf_symbols[q->cell.nof_prb * RE_X_RB * CP_NSYMB(q->cell.cp)];

    /* Set pointers for layermapping & precoding */
    nof_bits = 2 * q->nof_symbols;

    /* number of layers equals number of ports */
    for (i = 0; i < MAX_PORTS; i++) {
      x[i] = q->pbch_x[i];
    }
    memset(&x[MAX_PORTS], 0, sizeof(cf_t*) * (MAX_LAYERS - MAX_PORTS));
    
    /* extract symbols */
    if (q->nof_symbols != pbch_get(slot1_symbols, q->pbch_symbols[0], q->cell)) {
      fprintf(stderr, "There was an error getting the PBCH symbols\n");
      return LIBLTE_ERROR;
    }

    /* extract channel estimates */
    for (i = 0; i < q->cell.nof_ports; i++) {
      if (q->nof_symbols != pbch_get(ce_slot[i], q->ce[i], q->cell)) {
        fprintf(stderr, "There was an error getting the PBCH symbols\n");
        return LIBLTE_ERROR;
      }
    }

    q->frame_idx++;
    ret = 0;

    /* Try decoding for 1 to cell.nof_ports antennas */
    for (na = 0; na < q->cell.nof_ports && !ret; na++) {
      nant = nant_[na];

      INFO("Trying %d TX antennas with %d frames\n", nant, q->frame_idx);

      /* in conctrol channels, only diversity is supported */
      if (nant == 1) {
        /* no need for layer demapping */
        predecoding_single_zf(q->pbch_symbols[0], q->ce[0], q->pbch_d,
            q->nof_symbols);
      } else {
        predecoding_diversity_zf(q->pbch_symbols[0], q->ce, x, nant,
            q->nof_symbols);
        layerdemap_diversity(x, q->pbch_d, nant, q->nof_symbols / nant);
      }

      /* demodulate symbols */
      demod_soft_sigma_set(&q->demod, 1.0);
      demod_soft_demodulate(&q->demod, q->pbch_d,
          &q->pbch_llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols);

      /* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received
      * 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234.
      * We know they are ordered.
      *
      * FIXME: There are unnecessary checks because 2,3,4 have already been processed in the previous
      * calls.
      */
      for (nb = 0; nb < q->frame_idx && !ret; nb++) {
        for (dst = 0; (dst < 4 - nb) && !ret; dst++) {
          for (src = 0; src < q->frame_idx - nb && !ret; src++) {
            DEBUG("Trying %d blocks at offset %d as subframe mod4 number %d\n",
                nb + 1, src, dst);
            ret = pbch_decode_frame(q, mib, src, dst, nb + 1, nof_bits, nant);
            
          }
        }
      }
    }

    /* If not found, make room for the next packet of radio frame symbols */
    if (q->frame_idx == 4) {
      memmove(q->pbch_llr, &q->pbch_llr[nof_bits], nof_bits * 3 * sizeof(float));
      q->frame_idx = 3;
    }
  }
  return ret;
}