Fixed issues with cell_measurement

This commit is contained in:
ismagom 2014-10-24 11:06:04 +01:00
parent b2c009e1fa
commit 17dd292089
16 changed files with 308 additions and 251 deletions

View File

@ -113,6 +113,9 @@ int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) {
return cuhd_recv(h, data, nsamples, 1);
}
extern float mean_exec_time;
enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state;
int main(int argc, char **argv) {
int ret;
@ -121,8 +124,18 @@ int main(int argc, char **argv) {
lte_cell_t cell;
int64_t sf_cnt;
ue_sync_t ue_sync;
ue_mib_t ue_mib;
void *uhd;
ue_dl_t ue_dl;
lte_fft_t fft;
chest_t chest;
uint32_t nframes=0;
uint32_t nof_trials = 0;
uint32_t sfn = 0; // system frame number
int n;
uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN];
uint32_t sfn_offset;
float rssi=0, rsrp=0, rsrq=0;
parse_args(&prog_args, argc, argv);
@ -154,14 +167,15 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1);
}
if (ue_mib_init_known_cell(&ue_mib, cell, false)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n");
exit(-1);
}
pdsch_set_rnti(&ue_dl.pdsch, SIRNTI);
/* Initialize subframe counter */
sf_cnt = 0;
lte_fft_t fft;
chest_t chest;
if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n");
return -1;
@ -172,11 +186,8 @@ int main(int argc, char **argv) {
}
int sf_re = SF_LEN_RE(cell.nof_prb, cell.cp);
printf("%d RE allocated\n", sf_re);
cf_t *sf_symbols = vec_malloc(sf_re * sizeof(cf_t));
uint32_t nframes=0;
bool sib1_decoded = false;
int n;
/* Main loop */
while (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) {
@ -186,29 +197,57 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error calling ue_sync_work()\n");
}
float rssi=0, rsrp=0, rsrq=0;
/* iodev_receive returns 1 if successfully read 1 aligned subframe */
if (ret == 1) {
if (!sib1_decoded) {
n = ue_dl_decode(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), SIRNTI);
switch (state) {
case DECODE_MIB:
if (ue_sync_get_sfidx(&ue_sync) == 0) {
pbch_decode_reset(&ue_mib.pbch);
n = ue_mib_decode_aligned_frame(&ue_mib, &sf_buffer[ue_sync_sf_len(&ue_sync)/2], bch_payload_unpacked, NULL, &sfn_offset);
if (n < 0) {
fprintf(stderr, "\nError running receiver\n");fflush(stdout);
fprintf(stderr, "Error decoding UE MIB\n");
exit(-1);
} else if (n > 0) {
} else if (n == MIB_FOUND) {
bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN);
bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn);
printf("MIB found SFN: %d, offset: %d\n", sfn, sfn_offset);
sfn = (sfn<<2) + sfn_offset;
state = DECODE_SIB;
}
}
break;
case DECODE_SIB:
sfn=0;
/* If we are looking for SI Blocks, search only in appropiate places */
if ((sfn % 2) == 0 && (ue_sync_get_sfidx(&ue_sync) == 5)) {
n = ue_dl_decode(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), sfn, SIRNTI);
if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
exit(-1);
} else if (n == 0) {
// Printf
// if (!(sf_cnt%20)) {
printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, ExecTime: %5.1f us, NOI: %.2f, Nof Trials: %4d, Nof Error: %4d\r",
ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000,
mean_exec_time, pdsch_average_noi(&ue_dl.pdsch),
(int) nof_trials, (int) ue_dl.pkt_errors);
// }
nof_trials++;
} else {
printf("\n\nDecoded SIB1 Message Len %d: ",n);
bit_unpack_vector(data, data_unpacked, n);
void *dlsch_msg = bcch_dlsch_unpack(data_unpacked, n);
if (dlsch_msg) {
printf("\n");fflush(stdout);
sib1_decoded = true;
cell_access_info_t cell_info;
bcch_dlsch_sib1_get_cell_access_info(dlsch_msg, &cell_info);
printf("Cell ID: 0x%x\n", cell_info.cell_id);
}
state = MEASURE;
}
} else {
}
break;
case MEASURE:
/* Run FFT for all subframe data */
lte_fft_run_sf(&fft, sf_buffer, sf_symbols);
@ -226,12 +265,21 @@ int main(int argc, char **argv) {
10*log10(rsrp*1000)-prog_args.uhd_gain,
10*log10(rsrq));
}
break;
}
if (ue_sync_get_sfidx(&ue_sync) == 0) {
sfn++;
if (sfn == 1024) {
sfn = 0;
}
}
} else if (ret == 0) {
printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r",
sync_get_peak_value(&ue_sync.sfind),
ue_sync.frame_total_cnt, ue_sync.state);
}
sf_cnt++;
} // Main loop

View File

@ -49,7 +49,7 @@ int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_fram
int ret = LIBLTE_ERROR;
uint32_t nof_frames = 0;
uint32_t flen = MIB_FRAME_SIZE;
uint32_t flen = MIB_FRAME_SIZE_SEARCH;
cf_t *buffer = vec_malloc(sizeof(cf_t) * flen);
if (!buffer) {
@ -75,7 +75,7 @@ int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_fram
DEBUG("Calling ue_mib_decode() %d/%d\n", nof_frames, nof_frames_total);
n = ue_mib_decode(&uemib, buffer, flen);
n = ue_mib_sync_and_decode(&uemib, buffer, flen);
if (n == LIBLTE_ERROR || n == LIBLTE_ERROR_INVALID_INPUTS) {
fprintf(stderr, "Error calling ue_mib_decode()\n");
goto free_and_exit;

View File

@ -204,9 +204,12 @@ int main(int argc, char **argv) {
break;
}
fprintf(stderr, "Change in ue_dl API\n");
exit(-1);
/* iodev_receive returns 1 if successfully read 1 aligned subframe */
if (ret == 1) {
rlen = ue_dl_decode(&ue_dl, sf_buffer, data, iodev_get_sfidx(&iodev), prog_args.rnti);
rlen = ue_dl_decode(&ue_dl, sf_buffer, data, iodev_get_sfidx(&iodev), 0, prog_args.rnti);
if (rlen < 0) {
fprintf(stderr, "\nError running receiver\n");fflush(stdout);
exit(-1);
@ -220,11 +223,10 @@ int main(int argc, char **argv) {
// Plot and Printf
if (!(sf_cnt % 10)) {
printf("CFO: %+.4f KHz, SFO: %+.4f Khz, NOI: %.2f Errors: %4d/%4d/%4d, BLER: %.1e, Texec: %.2f\r",
printf("CFO: %+.4f KHz, SFO: %+.4f Khz, NOI: %.2f Errors: %4d/%4d, BLER: %.1e, Texec: %.2f\r",
ue_sync_get_cfo(&iodev.sframe)/1000, ue_sync_get_sfo(&iodev.sframe)/1000,
pdsch_average_noi(&ue_dl.pdsch),
(int) ue_dl.pkt_errors, (int) ue_dl.pkts_total, (int) ue_dl.nof_trials,
(float) ue_dl.pkt_errors / ue_dl.pkts_total,
(int) ue_dl.pkt_errors, (int) ue_dl.pkts_total, (float) ue_dl.pkt_errors / ue_dl.pkts_total,
mean_exec_time);
}

View File

@ -29,6 +29,7 @@
#ifndef _LTEBASE_
#define _LTEBASE_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "liblte/config.h"
@ -86,6 +87,9 @@ typedef enum {CPNORM, CPEXT} lte_cp_t;
#define SF_LEN(symbol_sz) (2*SLOT_LEN(symbol_sz))
#define SF_LEN_MAX (SF_LEN(SYMBOL_SZ_MAX))
#define SLOT_LEN_PRB(nof_prb) (SLOT_LEN(lte_symbol_sz(nof_prb)))
#define SF_LEN_PRB(nof_prb) (SF_LEN(lte_symbol_sz(nof_prb)))
#define SLOT_LEN_RE(nof_prb, cp) (nof_prb*RE_X_RB*CP_NSYMB(cp))
#define SF_LEN_RE(nof_prb, cp) (2*SLOT_LEN_RE(nof_prb, cp))
@ -139,6 +143,9 @@ LIBLTE_API enum band_geographical_area {
LIBLTE_API bool lte_cell_isvalid(lte_cell_t *cell);
LIBLTE_API void lte_cell_fprint(FILE *stream,
lte_cell_t *cell);
LIBLTE_API bool lte_N_id_2_isvalid(uint32_t N_id_2);
LIBLTE_API bool lte_N_id_1_isvalid(uint32_t N_id_1);

View File

@ -73,10 +73,6 @@ typedef struct LIBLTE_API {
uint64_t pkt_errors;
uint64_t pkts_total;
uint64_t nof_trials;
uint32_t sfn;
bool pbch_decoded;
uint16_t user_rnti;
}ue_dl_t;
@ -92,6 +88,7 @@ LIBLTE_API int ue_dl_decode(ue_dl_t *q,
cf_t *sf_buffer,
uint8_t *data,
uint32_t sf_idx,
uint32_t sfn,
uint16_t rnti);
#endif

View File

@ -56,8 +56,8 @@
#include "liblte/phy/common/fft.h"
#define MIB_NOF_PORTS 2
#define MIB_FRAME_SIZE 9600
#define MIB_MAX_PORTS 4
#define MIB_FRAME_SIZE_SEARCH 9600
#define MIB_FRAME_UNALIGNED -3
#define MIB_FOUND 1
@ -66,10 +66,8 @@
typedef struct LIBLTE_API {
sync_t sfind;
uint32_t cell_id;
cf_t *slot1_symbols;
cf_t *ce[MIB_NOF_PORTS];
cf_t *ce[MIB_MAX_PORTS];
lte_fft_t fft;
chest_t chest;
@ -88,14 +86,24 @@ LIBLTE_API int ue_mib_init(ue_mib_t *q,
uint32_t cell_id,
lte_cp_t cp);
LIBLTE_API int ue_mib_init_known_cell(ue_mib_t *q,
lte_cell_t cell,
bool do_sync);
LIBLTE_API void ue_mib_free(ue_mib_t *q);
LIBLTE_API void ue_mib_reset(ue_mib_t *q);
LIBLTE_API int ue_mib_decode(ue_mib_t *q,
LIBLTE_API int ue_mib_sync_and_decode(ue_mib_t *q,
cf_t *signal,
uint32_t nsamples);
LIBLTE_API int ue_mib_decode_aligned_frame(ue_mib_t * q,
cf_t *input,
uint8_t bch_payload[BCH_PAYLOAD_LEN],
uint32_t *nof_tx_ports,
uint32_t *sfn_offset);
LIBLTE_API void ue_mib_get_payload(ue_mib_t *q,
uint8_t bch_payload[BCH_PAYLOAD_LEN],
uint32_t *nof_tx_ports,

View File

@ -99,6 +99,8 @@ LIBLTE_API int ue_sync_init(ue_sync_t *q,
LIBLTE_API void ue_sync_free(ue_sync_t *q);
LIBLTE_API uint32_t ue_sync_sf_len(ue_sync_t *q);
LIBLTE_API int ue_sync_get_buffer(ue_sync_t *q,
cf_t **sf_symbols);

View File

@ -38,7 +38,7 @@
#define SLOT_SZ(q) (q->nof_symbols * q->symbol_sz)
#define SF_SZ(q) (2 * SLOT_SZ(q))
#define VOLK_INTERP
//#define VOLK_INTERP
void chest_fprint(chest_t *q, FILE *stream, uint32_t nslot, uint32_t port_id) {
chest_ref_fprint(q, stream, nslot, port_id);

View File

@ -65,6 +65,10 @@ bool lte_cell_isvalid(lte_cell_t *cell) {
}
}
void lte_cell_fprint(FILE *stream, lte_cell_t *cell) {
fprintf(stream, "PCI: %d, CP: %s, PRB: %d, Ports: %d\n", cell->id, lte_cp_string(cell->cp), cell->nof_prb, cell->nof_ports);
}
bool lte_N_id_2_isvalid(uint32_t N_id_2) {
if (N_id_2 < 3) {
return true;

View File

@ -77,7 +77,7 @@ int precoding_diversity(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_ports,
}
return 4 * i;
} else {
fprintf(stderr, "Number of ports must be 2 or 4 for transmit diversity\n");
fprintf(stderr, "Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)\n", nof_ports);
return -1;
}
}
@ -180,7 +180,7 @@ int predecoding_diversity_zf(cf_t *y, cf_t *ce[MAX_PORTS], cf_t *x[MAX_LAYERS],
}
return i;
} else {
fprintf(stderr, "Number of ports must be 2 or 4 for transmit diversity\n");
fprintf(stderr, "Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)\n", nof_ports);
return -1;
}
}

View File

@ -270,6 +270,8 @@ int pbch_decode_frame(pbch_t *q, uint32_t src, uint32_t dst, uint32_t n,
uint32_t nof_bits, uint32_t nof_ports) {
int j;
INFO("Trying to decode PBCH %d bits, %d ports, src: %d, dst: %d, n=%d\n", nof_bits, nof_ports, src, dst, n);
memcpy(&q->temp[dst * nof_bits], &q->pbch_llr[src * nof_bits],
n * nof_bits * sizeof(float));
@ -290,6 +292,7 @@ int pbch_decode_frame(pbch_t *q, uint32_t src, uint32_t dst, uint32_t n,
/* FIXME: If channel estimates are zero, received LLR are NaN. Check and return error */
for (j = 0; j < BCH_ENCODED_LEN; j++) {
if (isnan(q->pbch_rm_f[j]) || isinf(q->pbch_rm_f[j])) {
printf("Some CE are NaN or Inf!\n");
return LIBLTE_ERROR;
}
}
@ -316,8 +319,7 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS],
uint8_t bch_payload[BCH_PAYLOAD_LEN], uint32_t *nof_tx_ports, uint32_t *sfn_offset)
{
uint32_t src, dst, nb;
uint32_t nant_[3] = { 1, 2, 4 };
uint32_t na, nant;
uint32_t nant;
int i;
int nof_bits;
cf_t *x[MAX_LAYERS];
@ -360,9 +362,8 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS],
ret = 0;
/* Try decoding for 1 to cell.nof_ports antennas */
for (na = 0; na < q->cell.nof_ports && !ret; na++) {
nant = nant_[na];
for (nant = 1; nant <= q->cell.nof_ports && !ret; nant++) {
if (nant != 3) {
DEBUG("Trying %d TX antennas with %d frames\n", nant, q->frame_idx);
/* in conctrol channels, only diversity is supported */
@ -392,17 +393,6 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS],
for (dst = 0; (dst < 4 - nb) && !ret; dst++) {
for (src = 0; src < q->frame_idx - nb && !ret; src++) {
ret = pbch_decode_frame(q, 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;
}
}
if (ret == 1) {
if (sfn_offset) {
*sfn_offset = dst - src;
@ -415,6 +405,18 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS],
vec_fprint_hex(stdout, bch_payload, BCH_PAYLOAD_LEN);
}
}
}
}
}
}
}
/* 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;
}

View File

@ -573,6 +573,7 @@ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, lte_cp_t cp) {
case 4:
return 2;
default:
fprintf(stderr, "Invalid number of ports %d\n", nof_port);
return LIBLTE_ERROR;
}
break;
@ -585,6 +586,7 @@ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, lte_cp_t cp) {
return 2;
}
default:
fprintf(stderr, "Invalid symbol %d\n", symbol);
return LIBLTE_ERROR;
}
}
@ -697,7 +699,7 @@ int regs_init(regs_t *h, lte_cell_t cell) {
for (i = 0; i < max_ctrl_symbols; i++) {
n[i] = regs_num_x_symbol(i, h->cell.nof_ports, h->cell.cp);
if (n[i] == -1) {
return -1;
goto clean_and_exit;
}
h->nof_regs += h->cell.nof_prb * n[i];
}
@ -752,7 +754,7 @@ int regs_init(regs_t *h, lte_cell_t cell) {
ret = LIBLTE_SUCCESS;
}
clean_and_exit:
if (ret == LIBLTE_ERROR) {
if (ret != LIBLTE_SUCCESS) {
regs_free(h);
}
return ret;

View File

@ -232,6 +232,8 @@ int sync_find(sync_t *q, cf_t *input, uint32_t find_offset, uint32_t *peak_posit
{
int peak_pos;
ret = LIBLTE_ERROR;
if (peak_position) {
*peak_position = 0;
}

View File

@ -48,13 +48,12 @@ int ue_dl_init(ue_dl_t *q,
{
ret = LIBLTE_ERROR;
bzero(q, sizeof(ue_dl_t));
q->cell = cell;
q->user_rnti = user_rnti;
q->pkt_errors = 0;
q->pkts_total = 0;
q->nof_trials = 0;
q->sfn = 0;
q->pbch_decoded = false;
if (lte_fft_init(&q->fft, q->cell.cp, q->cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n");
@ -144,7 +143,7 @@ void ue_dl_free(ue_dl_t *q) {
LIBLTE_API float mean_exec_time=0;
int frame_cnt=0;
int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti)
int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32_t sfn, uint16_t rnti)
{
uint32_t cfi, cfi_distance, i;
ra_pdsch_t ra_dl;
@ -154,7 +153,6 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16
uint16_t crc_rem;
dci_format_t format;
int ret = LIBLTE_ERROR;
cf_t *ce_slot1[MAX_PORTS];
struct timeval t[3];
/* Run FFT for all subframe data */
@ -168,31 +166,9 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16
gettimeofday(&t[2], NULL);
get_time_interval(t);
mean_exec_time = (float) VEC_CMA((float) t[0].tv_usec, mean_exec_time, frame_cnt);
frame_cnt++;
for (int i=0;i<MAX_PORTS;i++) {
ce_slot1[i] = &q->ce[i][SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp)];
}
/* Decode PBCH if not yet decoded to obtain the System Frame Number (SFN) */
if (sf_idx == 0) {
// FIXME: There is no need to do this every frame!
pbch_decode_reset(&q->pbch);
if (pbch_decode(&q->pbch, &q->sf_symbols[SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp)], ce_slot1, NULL, NULL, &q->sfn) == 1) {
q->pbch_decoded = true;
INFO("Decoded SFN: %d\n", q->sfn);
} else {
INFO("Not decoded MIB (SFN: %d)\n", q->sfn);
q->sfn++;
if (q->sfn == 4) {
q->sfn = 0;
}
}
}
/* If we are looking for SI Blocks, search only in appropiate places */
if (((rnti == SIRNTI && (q->sfn % 2) == 0 && sf_idx == 5) ||
rnti != SIRNTI))
{
/* First decode PCFICH and obtain CFI */
if (pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, sf_idx, &cfi, &cfi_distance)<0) {
@ -216,7 +192,6 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16
format = Format1;
}
crc_rem = 0;
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
if (pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, locations[i], sf_idx, cfi)) {
@ -231,6 +206,7 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16
}
if (crc_rem == rnti) {
printf("Hem trobat\n");
if (dci_msg_to_ra_dl(&dci_msg, rnti, q->user_rnti, q->cell, cfi, &ra_dl)) {
fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
return LIBLTE_ERROR;
@ -238,7 +214,7 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16
uint32_t rvidx;
if (rnti == SIRNTI) {
switch((q->sfn%8)/2) {
switch((sfn%8)/2) {
case 0:
rvidx = 0;
break;
@ -287,10 +263,6 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16
}
}
}
if (rnti == SIRNTI && (q->sfn%8) == 0) {
q->nof_trials++;
}
}
if (crc_rem == rnti && ret == LIBLTE_SUCCESS) {
return ra_dl.mcs.tbs;

View File

@ -36,56 +36,61 @@
#include "liblte/phy/utils/debug.h"
#include "liblte/phy/utils/vector.h"
#define FIND_FFTSIZE 128
#define FIND_SFLEN 5*SF_LEN(FIND_FFTSIZE)
#define MIB_FIND_THRESHOLD 0.0
int ue_mib_init(ue_mib_t * q,
uint32_t cell_id,
lte_cp_t cp)
{
int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (q != NULL) {
ret = LIBLTE_ERROR;
lte_cell_t cell;
cell.nof_ports = MIB_NOF_PORTS;
cell.nof_ports = MIB_MAX_PORTS;
cell.nof_prb = 6;
cell.id = cell_id;
cell.cp = cp;
return ue_mib_init_known_cell(q, cell, true);
}
q->cell_id = cell_id;
int ue_mib_init_known_cell(ue_mib_t * q,
lte_cell_t cell,
bool do_sync)
{
int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (q != NULL &&
cell.nof_ports <= MIB_MAX_PORTS)
{
ret = LIBLTE_ERROR;
bzero(q, sizeof(ue_mib_t));
q->slot1_symbols = malloc(SLOT_LEN_RE(6, cp) * sizeof(cf_t));
q->slot1_symbols = vec_malloc(SLOT_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
if (!q->slot1_symbols) {
perror("malloc");
goto clean_exit;
}
for (int i=0;i<MIB_NOF_PORTS;i++) {
q->ce[i] = malloc(SLOT_LEN_RE(6, cp) * sizeof(cf_t));
for (int i=0;i<cell.nof_ports;i++) {
q->ce[i] = vec_malloc(SLOT_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
if (!q->ce[i]) {
perror("malloc");
goto clean_exit;
}
}
if (sync_init(&q->sfind, FIND_SFLEN, FIND_FFTSIZE)) {
if (do_sync) {
if (sync_init(&q->sfind, 5*SF_LEN_PRB(cell.nof_prb), lte_symbol_sz(cell.nof_prb))) {
goto clean_exit;
}
sync_set_threshold(&q->sfind, MIB_FIND_THRESHOLD);
sync_sss_en(&q->sfind, true);
sync_set_N_id_2(&q->sfind, cell_id % 3);
sync_set_N_id_2(&q->sfind, cell.id % 3);
sync_cp_en(&q->sfind, false);
sync_set_cp(&q->sfind, cp);
sync_set_cp(&q->sfind, cell.cp);
}
if (lte_fft_init(&q->fft, cp, cell.nof_prb)) {
if (lte_fft_init(&q->fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n");
goto clean_exit;
}
@ -114,7 +119,7 @@ void ue_mib_free(ue_mib_t * q)
if (q->slot1_symbols) {
free(q->slot1_symbols);
}
for (int i=0;i<MIB_NOF_PORTS;i++) {
for (int i=0;i<MIB_MAX_PORTS;i++) {
if (q->ce[i]) {
free(q->ce[i]);
}
@ -139,7 +144,8 @@ void ue_mib_set_threshold(ue_mib_t * q, float threshold)
sync_set_threshold(&q->sfind, threshold);
}
static int mib_decoder_run(ue_mib_t * q, cf_t *input)
int ue_mib_decode_aligned_frame(ue_mib_t * q, cf_t *input,
uint8_t bch_payload[BCH_PAYLOAD_LEN], uint32_t *nof_tx_ports, uint32_t *sfn_offset)
{
int ret = LIBLTE_SUCCESS;
@ -162,9 +168,9 @@ static int mib_decoder_run(ue_mib_t * q, cf_t *input)
}
/* Decode PBCH */
ret = pbch_decode(&q->pbch, q->slot1_symbols, q->ce, q->bch_payload, &q->nof_tx_ports, &q->sfn_offset);
ret = pbch_decode(&q->pbch, q->slot1_symbols, q->ce, bch_payload, nof_tx_ports, sfn_offset);
if (ret < 0) {
fprintf(stderr, "Error decoding PBCH\n");
fprintf(stderr, "Error decoding PBCH (%d)\n", ret);
} else if (ret == 1) {
INFO("MIB decoded: %u\n", q->frame_cnt/2);
ue_mib_reset(q);
@ -176,6 +182,7 @@ static int mib_decoder_run(ue_mib_t * q, cf_t *input)
}
return ret;
}
int counter1=0,counter2=0,counter3=0,counter4=0;
void ue_mib_get_payload(ue_mib_t *q,
@ -192,7 +199,7 @@ void ue_mib_get_payload(ue_mib_t *q,
}
}
int ue_mib_decode(ue_mib_t * q,
int ue_mib_sync_and_decode(ue_mib_t * q,
cf_t *signal,
uint32_t nsamples)
{
@ -204,23 +211,23 @@ int ue_mib_decode(ue_mib_t * q,
if (q != NULL &&
signal != NULL)
{
if (nsamples < MIB_FRAME_SIZE) {
fprintf(stderr, "Error: nsamples must be greater than %d\n", MIB_FRAME_SIZE);
if (nsamples < MIB_FRAME_SIZE_SEARCH) {
fprintf(stderr, "Error: nsamples must be greater than %d\n", MIB_FRAME_SIZE_SEARCH);
return LIBLTE_ERROR;
}
ret = LIBLTE_SUCCESS;
if (nsamples % MIB_FRAME_SIZE) {
printf("Warning: nsamples must be a multiple of %d. Some samples will be ignored\n", MIB_FRAME_SIZE);
nsamples = (nsamples/MIB_FRAME_SIZE) * MIB_FRAME_SIZE;
if (nsamples % MIB_FRAME_SIZE_SEARCH) {
printf("Warning: nsamples must be a multiple of %d. Some samples will be ignored\n", MIB_FRAME_SIZE_SEARCH);
nsamples = (nsamples/MIB_FRAME_SIZE_SEARCH) * MIB_FRAME_SIZE_SEARCH;
}
nof_input_frames = nsamples/MIB_FRAME_SIZE;
nof_input_frames = nsamples/MIB_FRAME_SIZE_SEARCH;
for (uint32_t nf=0;nf<nof_input_frames;nf++) {
/* Find peak and cell id */
ret = sync_find(&q->sfind, signal, nf*MIB_FRAME_SIZE, &peak_idx);
ret = sync_find(&q->sfind, signal, nf*MIB_FRAME_SIZE_SEARCH, &peak_idx);
if (ret < 0) {
fprintf(stderr, "Error finding correlation peak (%d)\n", ret);
return -1;
@ -234,15 +241,15 @@ int ue_mib_decode(ue_mib_t * q,
/* Check if we have space for reading the MIB and we are in Subframe #0 */
if (ret == 1 &&
nf*MIB_FRAME_SIZE + peak_idx + 960 <= nsamples &&
nf*MIB_FRAME_SIZE_SEARCH + peak_idx + MIB_FRAME_SIZE_SEARCH/10 <= nsamples &&
sync_sss_detected(&q->sfind) &&
sync_get_sf_idx(&q->sfind) == 0)
{
INFO("Trying to decode MIB\n",0);
ret = mib_decoder_run(q, &signal[nf*MIB_FRAME_SIZE+peak_idx]);
ret = ue_mib_decode_aligned_frame(q, &signal[nf*MIB_FRAME_SIZE_SEARCH+peak_idx], q->bch_payload, &q->nof_tx_ports, &q->sfn_offset);
counter3++;
} else if ((ret == LIBLTE_SUCCESS && peak_idx != 0) ||
(ret == 1 && nf*MIB_FRAME_SIZE + peak_idx + 960 > nsamples))
(ret == 1 && nf*MIB_FRAME_SIZE_SEARCH + peak_idx + MIB_FRAME_SIZE_SEARCH/10 > nsamples))
{
printf("Not enough space for PBCH\n",0);
ret = MIB_FRAME_UNALIGNED;

View File

@ -68,7 +68,7 @@ int ue_sync_init(ue_sync_t *q,
ue_sync_reset(q);
q->decode_sss_on_track = false;
q->decode_sss_on_track = true;
q->stream = stream_handler;
q->recv_callback = recv_callback;
q->cell = cell;
@ -113,6 +113,10 @@ clean_exit:
return ret;
}
uint32_t ue_sync_sf_len(ue_sync_t *q) {
return CURRENT_SFLEN;
}
void ue_sync_free(ue_sync_t *q) {
if (q->input_buffer) {
free(q->input_buffer);