예제 #1
0
void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q) {
  for (int i=0;i<q->nof_rx_antennas;i++) {
    if (q->sf_buffer[i]) {
      free(q->sf_buffer[i]);
    }
  }
  srslte_ue_mib_free(&q->ue_mib);
  srslte_ue_sync_free(&q->ue_sync);
}
예제 #2
0
int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, int offset_time, float offset_freq) {
  int ret = SRSLTE_ERROR_INVALID_INPUTS;
  
  if (q                   != NULL && 
      file_name           != NULL && 
      srslte_nofprb_isvalid(nof_prb))
  {
    ret = SRSLTE_ERROR;
    bzero(q, sizeof(srslte_ue_sync_t));
    q->file_mode = true; 
    q->sf_len = SRSLTE_SF_LEN(srslte_symbol_sz(nof_prb));
    q->file_cfo = -offset_freq; 
    q->correct_cfo = true; 
    q->fft_size = srslte_symbol_sz(nof_prb);
    
    if (srslte_cfo_init(&q->file_cfo_correct, 2*q->sf_len)) {
      fprintf(stderr, "Error initiating CFO\n");
      goto clean_exit; 
    }
    
    if (srslte_filesource_init(&q->file_source, file_name, SRSLTE_COMPLEX_FLOAT_BIN)) {
      fprintf(stderr, "Error opening file %s\n", file_name);
      goto clean_exit; 
    }
    
    q->input_buffer = srslte_vec_malloc(2 * q->sf_len * sizeof(cf_t));
    if (!q->input_buffer) {
      perror("malloc");
      goto clean_exit;
    }
    
    INFO("Offseting input file by %d samples and %.1f kHz\n", offset_time, offset_freq/1000);
    
    srslte_filesource_read(&q->file_source, dummy_offset_buffer, offset_time);
    srslte_ue_sync_reset(q);
    
    ret = SRSLTE_SUCCESS;
  }
clean_exit:
  if (ret == SRSLTE_ERROR) {
    srslte_ue_sync_free(q);
  }
  return ret; 
}
예제 #3
0
void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t * q)
{
  for (int i=0;i<q->nof_rx_antennas;i++) {
    if (q->sf_buffer[i]) {
      free(q->sf_buffer[i]);
    }
  }
  if (q->candidates) {
    free(q->candidates);
  }
  if (q->mode_counted) {
    free(q->mode_counted);
  }
  if (q->mode_ntimes) {
    free(q->mode_ntimes);
  }
  srslte_ue_sync_free(&q->ue_sync);
  
  bzero(q, sizeof(srslte_ue_cellsearch_t));

}
예제 #4
0
int main(int argc, char **argv) {
  int ret; 
  cf_t *sf_buffer; 
  prog_args_t prog_args; 
  srslte_cell_t cell;  
  int64_t sf_cnt;
  srslte_ue_sync_t ue_sync; 
  srslte_ue_mib_t ue_mib; 
  void *uhd; 
  srslte_ue_dl_t ue_dl; 
  srslte_ofdm_t fft; 
  srslte_chest_dl_t chest; 
  uint32_t nframes=0;
  uint32_t nof_trials = 0; 
  uint32_t sfn = 0; // system frame number
  int n; 
  uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
  uint32_t sfn_offset; 
  float rssi_utra=0,rssi=0, rsrp=0, rsrq=0, snr=0;
  cf_t *ce[SRSLTE_MAX_PORTS];

  if (parse_args(&prog_args, argc, argv)) {
    exit(-1);
  }

  if (prog_args.uhd_gain > 0) {
    printf("Opening UHD device...\n");
    if (cuhd_open(prog_args.uhd_args, &uhd)) {
      fprintf(stderr, "Error opening uhd\n");
      exit(-1);
    }
    cuhd_set_rx_gain(uhd, prog_args.uhd_gain);      
  } else {
    printf("Opening UHD device with threaded RX Gain control ...\n");
    if (cuhd_open_th(prog_args.uhd_args, &uhd, false)) {
      fprintf(stderr, "Error opening uhd\n");
      exit(-1);
    }
    cuhd_set_rx_gain(uhd, 50);      
  }

  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, SIGINT);
  sigprocmask(SIG_UNBLOCK, &sigset, NULL);
  signal(SIGINT, sig_int_handler);

  cuhd_set_master_clock_rate(uhd, 30.72e6);        

  /* set receiver frequency */
  cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq);
  cuhd_rx_wait_lo_locked(uhd);
  printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
  
  uint32_t ntrial=0; 
  do {
    ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell);
    if (ret < 0) {
      fprintf(stderr, "Error searching for cell\n");
      exit(-1); 
    } else if (ret == 0 && !go_exit) {
      printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++);
    }      
  } while (ret == 0 && !go_exit); 
  
  if (go_exit) {
    exit(0);
  }
  
  /* set sampling frequency */
    int srate = srslte_sampling_freq_hz(cell.nof_prb);    
    if (srate != -1) {  
      if (srate < 10e6) {          
        cuhd_set_master_clock_rate(uhd, 4*srate);        
      } else {
        cuhd_set_master_clock_rate(uhd, srate);        
      }
      printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000);
      float srate_uhd = cuhd_set_rx_srate(uhd, (double) srate);
      if (srate_uhd != srate) {
        fprintf(stderr, "Could not set sampling rate\n");
        exit(-1);
      }
    } else {
      fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb);
      exit(-1);
    }

  INFO("Stopping UHD and flushing buffer...\n",0);
  cuhd_stop_rx_stream(uhd);
  cuhd_flush_buffer(uhd);
  
  if (srslte_ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) {
    fprintf(stderr, "Error initiating ue_sync\n");
    return -1; 
  }
  if (srslte_ue_dl_init(&ue_dl, cell)) { 
    fprintf(stderr, "Error initiating UE downlink processing module\n");
    return -1;
  }
  if (srslte_ue_mib_init(&ue_mib, cell)) {
    fprintf(stderr, "Error initaiting UE MIB decoder\n");
    return -1;
  }
  
  /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
  srslte_ue_dl_set_rnti(&ue_dl, SRSLTE_SIRNTI); 

  /* Initialize subframe counter */
  sf_cnt = 0;
    
  if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
    fprintf(stderr, "Error initiating FFT\n");
    return -1;
  }
  if (srslte_chest_dl_init(&chest, cell)) {
    fprintf(stderr, "Error initiating channel estimator\n");
    return -1;
  }
  
  int sf_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);

  cf_t *sf_symbols = srslte_vec_malloc(sf_re * sizeof(cf_t));

  for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
    ce[i] = srslte_vec_malloc(sizeof(cf_t) * sf_re);
  }
  
  cuhd_start_rx_stream(uhd);
  
  float rx_gain_offset = 0;

  /* Main loop */
  while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) {
    
    ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
    if (ret < 0) {
      fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
    }

        
    /* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
    if (ret == 1) {
      switch (state) {
        case DECODE_MIB:
          if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
            srslte_pbch_decode_reset(&ue_mib.pbch);
            n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset);
            if (n < 0) {
              fprintf(stderr, "Error decoding UE MIB\n");
              return -1;
            } else if (n == SRSLTE_UE_MIB_FOUND) {   
              srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
              printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
              sfn = (sfn + sfn_offset)%1024; 
              state = DECODE_SIB; 
            }
          }
          break;
        case DECODE_SIB:
          /* We are looking for SI Blocks, search only in appropiate places */
          if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
            n = srslte_ue_dl_decode_rnti_rv(&ue_dl, sf_buffer, data, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI,
                                 ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4);
            if (n < 0) {
              fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
              return -1;
            } else if (n == 0) {
              printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, NOI: %.2f, PDCCH-Det: %.3f\r",
                      srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000, 
                      srslte_sch_average_noi(&ue_dl.pdsch.dl_sch),
                      (float) ue_dl.nof_detected/nof_trials);                
              nof_trials++; 
            } else {
              printf("Decoded SIB1. Payload: ");
              srslte_vec_fprint_byte(stdout, data, n/8);;
              state = MEASURE;
            }
          }
        break;
        
      case MEASURE:
        
        if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
          /* Run FFT for all subframe data */
          srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols);
          
          srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync));
                  
          rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer,SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05);
          rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05);
          rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05);
          rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05);      
          snr = SRSLTE_VEC_EMA(srslte_chest_dl_get_snr(&chest),snr,0.05);      
          
          nframes++;          
        } 
        
        
        if ((nframes%100) == 0 || rx_gain_offset == 0) {
          if (cuhd_has_rssi(uhd)) {
            rx_gain_offset = 10*log10(rssi)-cuhd_get_rssi(uhd);
          } else {
            rx_gain_offset = cuhd_get_rx_gain(uhd);
          }
        }
        
        // Plot and Printf
        if ((nframes%10) == 0) {

          printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, RSSI: %5.1f dBm, RSSI/ref-symbol: %+5.1f dBm, "
                 "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r",
                srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000, 
                10*log10(rssi*1000) - rx_gain_offset,                                  
                10*log10(rssi_utra*1000)- rx_gain_offset, 
                10*log10(rsrp*1000) - rx_gain_offset, 
                10*log10(rsrq), 10*log10(snr));                
          if (srslte_verbose != SRSLTE_VERBOSE_NONE) {
            printf("\n");
          }
        }
        break;
      }
      if (srslte_ue_sync_get_sfidx(&ue_sync) == 9) {
        sfn++; 
        if (sfn == 1024) {
          sfn = 0; 
        }
      }
    } else if (ret == 0) {
      printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r", 
        srslte_sync_get_peak_value(&ue_sync.sfind), 
        ue_sync.frame_total_cnt, ue_sync.state);      
    }
   
        
    sf_cnt++;                  
  } // Main loop

  srslte_ue_sync_free(&ue_sync);
  cuhd_close(uhd);
  printf("\nBye\n");
  exit(0);
}
예제 #5
0
파일: ue_mib.c 프로젝트: HankW507/srsLTE
void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q) {
  srslte_ue_mib_free(&q->ue_mib);
  srslte_ue_sync_free(&q->ue_sync);
}
예제 #6
0
int srslte_ue_sync_init(srslte_ue_sync_t *q, 
                 srslte_cell_t cell,
                 int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*),
                 void *stream_handler) 
{
  int ret = SRSLTE_ERROR_INVALID_INPUTS;
  
  if (q                                 != NULL && 
      stream_handler                    != NULL && 
      srslte_nofprb_isvalid(cell.nof_prb)      &&
      recv_callback                     != NULL)
  {
    ret = SRSLTE_ERROR;
    
    bzero(q, sizeof(srslte_ue_sync_t));

    q->stream = stream_handler;
    q->recv_callback = recv_callback;
    q->cell = cell;
    q->fft_size = srslte_symbol_sz(q->cell.nof_prb);
    q->sf_len = SRSLTE_SF_LEN(q->fft_size);
    q->file_mode = false; 
    q->correct_cfo = true; 
    q->agc_period = 0; 
    q->sample_offset_correct_period = DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD; 
    q->sfo_ema                      = DEFAULT_SFO_EMA_COEFF; 
    
    if (cell.id == 1000) {
      
      /* If the cell is unkown, we search PSS/SSS in 5 ms */
      q->nof_recv_sf = 5; 

      q->decode_sss_on_track = true; 

    } else {
      
      /* If the cell is known, we work on a 1ms basis */
      q->nof_recv_sf = 1; 

      q->decode_sss_on_track = true; 
    }

    q->frame_len = q->nof_recv_sf*q->sf_len;

    if(srslte_sync_init(&q->sfind, q->frame_len, q->frame_len, q->fft_size)) {
      fprintf(stderr, "Error initiating sync find\n");
      goto clean_exit;
    }
    if (cell.id == 1000) {
      if(srslte_sync_init(&q->strack, q->frame_len, TRACK_FRAME_SIZE, q->fft_size)) {
        fprintf(stderr, "Error initiating sync track\n");
        goto clean_exit;
      }      
    } else {
      if(srslte_sync_init(&q->strack, q->frame_len, SRSLTE_CP_LEN_NORM(1,q->fft_size), q->fft_size)) {
        fprintf(stderr, "Error initiating sync track\n");
        goto clean_exit;
      }
    }
    
    if (cell.id == 1000) {
      /* If the cell id is unknown, enable CP detection on find */ 
      // FIXME: CP detection not working very well. Not supporting Extended CP right now
      srslte_sync_cp_en(&q->sfind, false);      
      srslte_sync_cp_en(&q->strack, false); 

      srslte_sync_set_cfo_ema_alpha(&q->sfind, 0.8);
      srslte_sync_set_cfo_ema_alpha(&q->strack, 0.1);

      srslte_sync_cfo_i_detec_en(&q->sfind, false); 

      q->nof_avg_find_frames = FIND_NOF_AVG_FRAMES; 
      srslte_sync_set_threshold(&q->sfind, 2.0);
      srslte_sync_set_threshold(&q->strack, 1.2);
      
    } else {
      srslte_sync_set_N_id_2(&q->sfind, cell.id%3);
      srslte_sync_set_N_id_2(&q->strack, cell.id%3);
      q->sfind.cp = cell.cp;
      q->strack.cp = cell.cp;
      srslte_sync_cp_en(&q->sfind, false);      
      srslte_sync_cp_en(&q->strack, false);        

      srslte_sync_cfo_i_detec_en(&q->sfind, false); 
      
      srslte_sync_set_cfo_ema_alpha(&q->sfind, 0.1);
      srslte_sync_set_cfo_ema_alpha(&q->strack, 0.1);

      /* In find phase and if the cell is known, do not average pss correlation
       * because we only capture 1 subframe and do not know where the peak is. 
       */
      q->nof_avg_find_frames = 1; 
      srslte_sync_set_em_alpha(&q->sfind, 1);
      srslte_sync_set_threshold(&q->sfind, 3.0);
      
      srslte_sync_set_em_alpha(&q->strack, 0.2);
      srslte_sync_set_threshold(&q->strack, 1.2);

    }
      
    /* FIXME: Go for zerocopy only and eliminate this allocation */
    q->input_buffer = srslte_vec_malloc(2*q->frame_len * sizeof(cf_t));
    if (!q->input_buffer) {
      perror("malloc");
      goto clean_exit;
    }
    
    srslte_ue_sync_reset(q);
    
    ret = SRSLTE_SUCCESS;
  }
  
clean_exit:
  if (ret == SRSLTE_ERROR) {
    srslte_ue_sync_free(q);
  }
  return ret; 
}
예제 #7
0
int main(int argc, char **argv) {
  int ret; 
  srslte_cell_t cell;
  srslte_ue_mib_t ue_mib; 
#ifndef DISABLE_RF
  srslte_rf_t rf; 
#endif
  int n; 
  uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
  int sfn_offset;
  uint32_t sfn_target = 0;
  uint32_t sf_target = 0;
  uint32_t ncce_target = 0;
  uint32_t L_target = 0;
  uint32_t cfi_target = 0;
  FILE *fid;
  uint16_t rnti_tmp;

  parse_args(&prog_args, argc, argv);
  
  /* If reading from file, go straight to PDSCH decoding. Otherwise, decode MIB first */
  if (prog_args.input_file_name) {
    /* preset cell configuration */
    cell.id = prog_args.file_cell_id; 
    cell.cp = SRSLTE_CP_NORM; 
    cell.phich_length = SRSLTE_PHICH_NORM;
    cell.phich_resources = SRSLTE_PHICH_R_1;
    cell.nof_ports = prog_args.file_nof_ports; 
    cell.nof_prb = prog_args.file_nof_prb; 

    if (srslte_ue_sync_init_file(&ue_sync, prog_args.file_nof_prb, 
      prog_args.input_file_name, prog_args.file_offset_time, prog_args.file_offset_freq)) {
      fprintf(stderr, "Error initiating ue_sync\n");
      exit(-1); 
    }

  }

  if (srslte_ue_mib_init(&ue_mib, cell)) {
    fprintf(stderr, "Error initaiting UE MIB decoder\n");
    exit(-1);
  }    

  if (srslte_ue_dl_init(&ue_dl, cell)) {  // This is the User RNTI
    fprintf(stderr, "Error initiating UE downlink processing module\n");
    exit(-1);
  }
  
  /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
  srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);

  /* Initialize subframe counter */

  if (prog_args.rnti_to_fix != NULL) {
  	  fid = fopen(prog_args.rnti_to_fix,"r");
  	  for (int i=0;i<65536;i++) {
  	  	if (fscanf(fid,"%d",&rnti_tmp) != EOF) {
  //		  if (rnti_tmp) printf("rnti %d val %d\n", i, rnti_tmp);
  	  		srslte_ue_dl_reset_rnti_user_to(&ue_dl, i, rnti_tmp); // check this
  		  //printf("is rnti in the list? %d\n",rnti_in_list(&ue_dl, rnti_tmp));
  	  	}
  	  }
  	  fclose(fid);
    }

  ue_sync.correct_cfo = !prog_args.disable_cfo;

  srslte_pbch_decode_reset(&ue_mib.pbch);

  INFO("\nEntering main loop...\n\n", 0);
  /* Main loop */
  ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
  if (ret < 0) {
      fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
  }
  if (ret == 7) {
	  go_exit = true;
  }
  if (ret == 1) {
	if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
    	n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset);
        if (n < 0) {
        	fprintf(stderr, "Error decoding UE MIB\n");
            exit(-1);
        } else if (n == SRSLTE_UE_MIB_FOUND) {
        	srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
        	//srslte_cell_fprint(stdout, &cell, sfn);
        	//printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
        	sfn = (sfn + sfn_offset)%1024;
		}
	}
  } // Main loop
#define M_OFF 500
  float tprob[M_OFF];
  float bprob = 0;
  int b_offset = 0, b_offset2 = 0;
  int i, j, k;
  int t_offset, l_offset, m_offset = 30*ue_sync.sf_len/11520;
  uint16_t rnti_cand[M_OFF];
  uint16_t rnti_cnt[M_OFF][2];
  int rnti_off[M_OFF];
  uint16_t bcnt = 0;
  float rnti_bprob[M_OFF];
  int found = 0;

  fid = fopen(prog_args.to_fix,"r");
  bzero(tprob, sizeof(tprob));

  while (fscanf(fid,"%d %d %d %d %d",&sfn_target, &sf_target, &ncce_target, &L_target, &cfi_target) != EOF) {
//	  printf("checking sfn %d sf %d, ncce %d, L %d \n",sfn_target,sf_target, ncce_target, L_target);
	  bprob = 0;
	  b_offset = 0;
	  b_offset2 = 0;
	  bcnt = 0;
	  found = 0;
	  if (sfn == sfn_target && sf_target == 0) {
		  l_offset = 0;
	  } else {
		  srslte_filesource_seek(&ue_sync.file_source, ((sfn_target-sfn)*10+sf_target)*ue_sync.sf_len-m_offset);
		  srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
		  l_offset = -m_offset;
	  }
	  for (i=0; i<m_offset+1; i++) {
		  for (k=0; k<2 && !found; k++) {
			  if ((i==0 && k==1) || (l_offset==0 && k==1)) {
			  } else {
				  if (k==0) t_offset = i;
				  if (k==1) t_offset = -i;
				  //printf("checking offset %d for sfn %d sf %d (%d.%d)\n",t_offset,sfn_target,sf_target,i,k);
				  tprob[t_offset-l_offset] = srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[t_offset-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 0);
				  rnti_cand[t_offset-l_offset] = ue_dl.current_rnti;
				  rnti_cnt[t_offset-l_offset][0] = rnti_cand[t_offset-l_offset];
				  rnti_cnt[t_offset-l_offset][1] = 1;
				  rnti_off[t_offset-l_offset] = t_offset;
				  rnti_bprob[t_offset-l_offset] = tprob[t_offset-l_offset];

				  if ((tprob[t_offset-l_offset] >= 97 && tprob[t_offset-l_offset] <=101) || tprob[t_offset-l_offset] >= 197) {
					  //printf("Early winner...\n");
					  srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[t_offset-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 1);
					  found = 1;
					  break;
				  }

				  for (j = 0; j < t_offset-l_offset; j++) {
					  if (rnti_cnt[j][0] == rnti_cnt[t_offset-l_offset][0] && rnti_bprob[t_offset-l_offset] > 90) {
						  rnti_cnt[j][1]++;
						  //printf("at offset %d counting rnti %x cnt %d prob %.3f\n", t_offset, rnti_cnt[j][0], rnti_cnt[j][1], rnti_bprob[j]);
						  if (rnti_bprob[j] < rnti_bprob[t_offset-l_offset]) {
							  rnti_bprob[j] = rnti_bprob[t_offset-l_offset];
							  rnti_off[j] = t_offset;
							  //printf("at offset %d updating rnti %x cnt %d prob %.3f\n", t_offset, rnti_cnt[j][0], rnti_cnt[j][1], rnti_bprob[j]);
						  }
					  }
				  }
			  }
		  }
	  }
//	  for (t_offset = l_offset; t_offset < (m_offset+1); t_offset++) {
//		  //printf("checking offset %d for sfn %d sf %d\n",t_offset,sfn_target,sf_target);
//		  tprob[t_offset-l_offset] = srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[t_offset-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 0);
//		  rnti_cand[t_offset-l_offset] = ue_dl.current_rnti;
//		  rnti_cnt[t_offset-l_offset][0] = rnti_cand[t_offset-l_offset];
//		  rnti_cnt[t_offset-l_offset][1] = 1;
//		  rnti_off[t_offset-l_offset] = t_offset;
//		  rnti_bprob[t_offset-l_offset] = tprob[t_offset-l_offset];
//
//		  if ((tprob[t_offset-l_offset] >= 97 && tprob[t_offset-l_offset] <=101) || tprob[t_offset-l_offset] >= 197) {
//			  //printf("Early winner...\n");
//			  srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[t_offset-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 1);
//			  found = 1;
//			  break;
//		  }
//
//		  for (j = 0; j < t_offset-l_offset; j++) {
//			  if (rnti_cnt[j][0] == rnti_cnt[t_offset-l_offset][0] && rnti_bprob[t_offset-l_offset] > 90) {
//				  rnti_cnt[j][1]++;
//				  //printf("at offset %d counting rnti %x cnt %d prob %.3f\n", t_offset, rnti_cnt[j][0], rnti_cnt[j][1], rnti_bprob[j]);
//				  if (rnti_bprob[j] < rnti_bprob[t_offset-l_offset]) {
//					  rnti_bprob[j] = rnti_bprob[t_offset-l_offset];
//					  rnti_off[j] = t_offset;
//					  //printf("at offset %d updating rnti %x cnt %d prob %.3f\n", t_offset, rnti_cnt[j][0], rnti_cnt[j][1], rnti_bprob[j]);
//				  }
//			  }
//		  }
//	  }
	  if (found == 0) {
		  for (j = 0; j < (m_offset*2+1); j++) {
			  //if (rnti_cnt[j][1] > 1 && rnti_bprob[j] > 90) printf("entry %d, rnti %x cnt %d prob %.3f offset %d\n", j, rnti_cnt[j][0], rnti_cnt[j][1], rnti_bprob[j], rnti_off[j]);
			  if (rnti_cnt[j][1] > bcnt) {
				  bcnt = rnti_cnt[j][1];
				  b_offset = rnti_off[j];
			  }
			  if (rnti_cnt[j][1] > 1 && rnti_bprob[j] > bprob) {
				  bprob = rnti_bprob[j];
				  b_offset2 = rnti_off[j];
			  }
		  }
		  if (rnti_cand[b_offset-l_offset] == rnti_cand[b_offset2-l_offset]) {
			  if (rnti_bprob[b_offset-l_offset] >= rnti_bprob[b_offset2-l_offset] && rnti_bprob[b_offset-l_offset] >= 97) {
				  //printf("Most popular at offset %d...\n",b_offset);
				  //srslte_filesource_seek(&ue_sync.file_source, ((sfn_target-sfn)*10+sf_target)*ue_sync.sf_len+b_offset);
				  //srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
				  srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[b_offset-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 1);
			  } else if (rnti_bprob[b_offset2-l_offset] >= 97) {
				  //printf("Most likely not unique at offset %d...\n",b_offset2);
				  //srslte_filesource_seek(&ue_sync.file_source, ((sfn_target-sfn)*10+sf_target)*ue_sync.sf_len+b_offset2);
				  //srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
				  srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[b_offset2-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 1);
			  }
		  } else {
			  //printf("Most popular at offset %d...\n",b_offset);
			  //srslte_filesource_seek(&ue_sync.file_source, ((sfn_target-sfn)*10+sf_target)*ue_sync.sf_len+b_offset);
			  //srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
			  if (rnti_bprob[b_offset-l_offset] >= 95) srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[b_offset-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 1);
			  //printf("Most likely not unique at offset %d...\n",b_offset2);
			  //srslte_filesource_seek(&ue_sync.file_source, ((sfn_target-sfn)*10+sf_target)*ue_sync.sf_len+b_offset2);
			  //srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
			  if (rnti_bprob[b_offset2-l_offset] >= 95) srslte_ue_dl_fix_control_ra(&ue_dl, &sf_buffer[b_offset2-l_offset], data, sf_target, 0, sfn_target, ncce_target, L_target, cfi_target, 1);

			  //if (rnti_bprob[b_offset2-l_offset] < 98 && rnti_bprob[b_offset-l_offset] < 98) printf("nothing found in %d.%d L=%d,%d,%d\n",sfn_target,sf_target,ncce_target, L_target, cfi_target);
		  }
	  }
	  //if (sfn_target > 0) exit(0);
  }
  srslte_ue_dl_free(&ue_dl);
  srslte_ue_sync_free(&ue_sync);
  
#ifndef DISABLE_RF
  if (!prog_args.input_file_name) {
    srslte_ue_mib_free(&ue_mib);
    srslte_rf_close(&rf);    
  }
#endif
  //printf("\nBye\n");
  exit(0);
}