int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp, int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), void *stream_handler) { srslte_cell_t cell; // If the ports are set to 0, ue_mib goes through 1, 2 and 4 ports to blindly detect nof_ports cell.nof_ports = 0; cell.id = cell_id; cell.cp = cp; cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; if (srslte_ue_mib_init(&q->ue_mib, cell)) { fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; } srslte_ue_sync_decode_sss_on_track(&q->ue_sync, true); return SRSLTE_SUCCESS; }
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); }
int srslte_ue_mib_init(srslte_ue_mib_t * q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && cell.nof_ports <= SRSLTE_MAX_PORTS) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_ue_mib_t)); if (srslte_pbch_init(&q->pbch, cell)) { fprintf(stderr, "Error initiating PBCH\n"); goto clean_exit; } if (cell.nof_ports == 0) { cell.nof_ports = SRSLTE_MAX_PORTS; } q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); if (!q->sf_symbols) { perror("malloc"); goto clean_exit; } for (int i=0;i<cell.nof_ports;i++) { q->ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); if (!q->ce[i]) { perror("malloc"); goto clean_exit; } } if (srslte_ofdm_rx_init(&q->fft, cell.cp, cell.nof_prb)) { fprintf(stderr, "Error initializing FFT\n"); goto clean_exit; } if (srslte_chest_dl_init(&q->chest, cell)) { fprintf(stderr, "Error initializing reference signal\n"); goto clean_exit; } srslte_ue_mib_reset(q); ret = SRSLTE_SUCCESS; } clean_exit: if (ret == SRSLTE_ERROR) { srslte_ue_mib_free(q); } return ret; }
int srslte_ue_mib_init(srslte_ue_mib_t * q, cf_t *in_buffer[SRSLTE_MAX_PORTS], uint32_t max_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_ue_mib_t)); if (srslte_pbch_init(&q->pbch)) { fprintf(stderr, "Error initiating PBCH\n"); goto clean_exit; } q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t)); if (!q->sf_symbols) { perror("malloc"); goto clean_exit; } for (int i=0;i<SRSLTE_MAX_PORTS;i++) { q->ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t)); if (!q->ce[i]) { perror("malloc"); goto clean_exit; } } if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, in_buffer[0], q->sf_symbols, max_prb)) { fprintf(stderr, "Error initializing FFT\n"); goto clean_exit; } if (srslte_chest_dl_init(&q->chest, max_prb)) { fprintf(stderr, "Error initializing reference signal\n"); goto clean_exit; } srslte_ue_mib_reset(q); ret = SRSLTE_SUCCESS; } clean_exit: if (ret == SRSLTE_ERROR) { srslte_ue_mib_free(q); } return ret; }
int srslte_ue_mib_sync_set_cell(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp) { srslte_cell_t cell; // If the ports are set to 0, ue_mib goes through 1, 2 and 4 ports to blindly detect nof_ports cell.nof_ports = 0; cell.id = cell_id; cell.cp = cp; cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; if (srslte_ue_mib_set_cell(&q->ue_mib, cell)) { fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } if (srslte_ue_sync_set_cell(&q->ue_sync, cell)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; }
int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q, int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) { for (int i=0;i<nof_rx_antennas;i++) { q->sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(SRSLTE_UE_MIB_NOF_PRB)); } q->nof_rx_antennas = nof_rx_antennas; if (srslte_ue_mib_init(&q->ue_mib, q->sf_buffer, SRSLTE_UE_MIB_NOF_PRB)) { fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } if (srslte_ue_sync_init_multi(&q->ue_sync, SRSLTE_UE_MIB_NOF_PRB, false, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; } srslte_ue_sync_decode_sss_on_track(&q->ue_sync, true); return SRSLTE_SUCCESS; }
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); }
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); }