diff --git a/lte/phy/examples/CMakeLists.txt b/lte/phy/examples/CMakeLists.txt index 573a9772b..114674cc5 100644 --- a/lte/phy/examples/CMakeLists.txt +++ b/lte/phy/examples/CMakeLists.txt @@ -52,10 +52,10 @@ LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND) ################################################################# add_executable(pdsch_ue pdsch_ue.c iodev.c cell_search_utils.c) -target_link_libraries(pdsch_ue lte_phy) +target_link_libraries(pdsch_ue lte_rrc lte_phy) add_executable(pdsch_enodeb pdsch_enodeb.c) -target_link_libraries(pdsch_enodeb lte_phy) +target_link_libraries(pdsch_enodeb lte_rrc lte_phy) IF(${CUHD_FIND} EQUAL -1) SET_TARGET_PROPERTIES(pdsch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") @@ -82,10 +82,10 @@ ENDIF(${GRAPHICS_FIND} EQUAL -1) IF(${CUHD_FIND} GREATER -1) add_executable(cell_search cell_search.c cell_search_utils.c) - target_link_libraries(cell_search lte_phy cuhd ) + target_link_libraries(cell_search lte_rrc lte_phy cuhd ) add_executable(cell_measurement cell_measurement.c cell_search_utils.c) - target_link_libraries(cell_measurement cuhd lte_phy) + target_link_libraries(cell_measurement cuhd lte_rrc lte_phy) MESSAGE(STATUS " UHD examples will be installed.") diff --git a/lte/phy/examples/cell_measurement.c b/lte/phy/examples/cell_measurement.c index 4e01b0262..ba1a1961f 100644 --- a/lte/phy/examples/cell_measurement.c +++ b/lte/phy/examples/cell_measurement.c @@ -119,7 +119,6 @@ int main(int argc, char **argv) { prog_args_t prog_args; lte_cell_t cell; int64_t sf_cnt; - pbch_mib_t mib; ue_sync_t ue_sync; void *uhd; @@ -138,7 +137,7 @@ int main(int argc, char **argv) { cuhd_rx_wait_lo_locked(uhd); printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000); - if (cell_search(uhd, prog_args.force_N_id_2, &cell, &mib)) { + if (cell_search(uhd, prog_args.force_N_id_2, &cell)) { fprintf(stderr, "Cell not found\n"); exit(-1); } diff --git a/lte/phy/examples/cell_search.c b/lte/phy/examples/cell_search.c index bf3d83112..0242457fe 100644 --- a/lte/phy/examples/cell_search.c +++ b/lte/phy/examples/cell_search.c @@ -124,8 +124,9 @@ int main(int argc, char **argv) { int nof_freqs; lte_earfcn_t channels[MAX_EARFCN]; uint32_t freq; - pbch_mib_t mib; - + uint8_t bch_payload[BCH_PAYLOAD_LEN]; + uint32_t nof_tx_ports; + parse_args(argc, argv); printf("Opening UHD device...\n"); @@ -179,10 +180,13 @@ int main(int argc, char **argv) { if (n == CS_CELL_DETECTED) { for (int i=0;i<3;i++) { if (found_cells[i].peak > threshold/2) { - if (decode_pbch(uhd, &found_cells[i], nof_frames_total, &mib)) { + if (decode_pbch(uhd, &found_cells[i], nof_frames_total, bch_payload, &nof_tx_ports, NULL)) { fprintf(stderr, "Error decoding PBCH\n"); exit(-1); - } + } else { + printf("Cell found with %d ports. Decoded MIB: \n", nof_tx_ports); + vec_fprint_hex(stdout, bch_payload, BCH_PAYLOAD_LEN); + } } } } diff --git a/lte/phy/examples/cell_search_utils.c b/lte/phy/examples/cell_search_utils.c index f7a3d1d30..e511af237 100644 --- a/lte/phy/examples/cell_search_utils.c +++ b/lte/phy/examples/cell_search_utils.c @@ -36,11 +36,13 @@ #include #include "liblte/phy/phy.h" +#include "liblte/rrc/rrc.h" #ifndef DISABLE_UHD #include "liblte/cuhd/cuhd.h" -int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_frames_total, pbch_mib_t *mib) +int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_frames_total, + uint8_t bch_payload[BCH_PAYLOAD_LEN], uint32_t *nof_tx_ports, uint32_t *sfn_offset) { ue_mib_t uemib; int n; @@ -55,8 +57,6 @@ int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_fram goto free_and_exit; } - bzero(mib, sizeof(pbch_mib_t)); - if (ue_mib_init(&uemib, found_cell->cell_id, found_cell->cp)) { fprintf(stderr, "Error initiating PBCH decoder\n"); goto free_and_exit; @@ -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, mib); + n = ue_mib_decode(&uemib, buffer, flen, bch_payload, nof_tx_ports, sfn_offset); if (n == LIBLTE_ERROR || n == LIBLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling ue_mib_decode()\n"); goto free_and_exit; @@ -93,7 +93,6 @@ int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_fram if (n == MIB_FOUND) { printf("\n\nMIB decoded in %d ms (%d half frames)\n", nof_frames*5, nof_frames); - pbch_mib_fprint(stdout, mib, found_cell->cell_id); ret = LIBLTE_SUCCESS; } else { ret = LIBLTE_ERROR; @@ -211,9 +210,11 @@ int find_all_cells(void *uhd, ue_celldetect_result_t found_cell[3]) return nof_detected_cells; } -int cell_search(void *uhd, int force_N_id_2, lte_cell_t *cell, pbch_mib_t *mib) +int cell_search(void *uhd, int force_N_id_2, lte_cell_t *cell) { int ret; + uint32_t nof_tx_ports; + uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_packed[BCH_PAYLOAD_LEN]; ue_celldetect_result_t found_cells[3]; bzero(found_cells, 3*sizeof(ue_celldetect_result_t)); @@ -243,7 +244,7 @@ int cell_search(void *uhd, int force_N_id_2, lte_cell_t *cell, pbch_mib_t *mib) } printf("Decoding PBCH for cell %d (N_id_2=%d)\n", found_cells[max_peak_cell].cell_id, max_peak_cell); - if (decode_pbch(uhd, &found_cells[max_peak_cell], 400, mib)) { + if (decode_pbch(uhd, &found_cells[max_peak_cell], 400, bch_payload, &nof_tx_ports, NULL)) { fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", found_cells[max_peak_cell].cell_id); return LIBLTE_ERROR; } @@ -254,8 +255,10 @@ int cell_search(void *uhd, int force_N_id_2, lte_cell_t *cell, pbch_mib_t *mib) cell->cp = found_cells[max_peak_cell].cp; cell->id = found_cells[max_peak_cell].cell_id; - cell->nof_prb = mib->nof_prb; - cell->nof_ports = mib->nof_ports; + cell->nof_ports = nof_tx_ports; + + bit_pack_vector(bch_payload, bch_payload_packed, BCH_PAYLOAD_LEN); + bcch_bch_mib_unpack(bch_payload_packed, BCH_PAYLOAD_LEN, cell, NULL); /* set sampling frequency */ int srate = lte_sampling_freq_hz(cell->nof_prb); diff --git a/lte/phy/examples/cell_search_utils.h b/lte/phy/examples/cell_search_utils.h index 8d5d4f5dd..a73a52ec5 100644 --- a/lte/phy/examples/cell_search_utils.h +++ b/lte/phy/examples/cell_search_utils.h @@ -31,7 +31,9 @@ int decode_pbch(void *uhd, ue_celldetect_result_t *found_cell, uint32_t nof_frames_total, - pbch_mib_t *mib); + uint8_t bch_payload[BCH_PAYLOAD_LEN], + uint32_t *nof_tx_ports, + uint32_t *sfn_offset); int find_all_cells(void *uhd, ue_celldetect_result_t found_cell[3]); @@ -42,5 +44,4 @@ int find_cell(void *uhd, int cell_search(void *uhd, int force_N_id_2, - lte_cell_t *cell, - pbch_mib_t *mib); \ No newline at end of file + lte_cell_t *cell); \ No newline at end of file diff --git a/lte/phy/examples/iodev.c b/lte/phy/examples/iodev.c index d617221b3..1f1e63b17 100644 --- a/lte/phy/examples/iodev.c +++ b/lte/phy/examples/iodev.c @@ -51,12 +51,12 @@ int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) { } /* Setup USRP or input file */ -int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell, pbch_mib_t *mib) { +int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell) { if (config->input_file_name) { - mib->phich_resources = R_1; - mib->phich_length = PHICH_NORM; + cell->phich_resources = R_1; + cell->phich_length = PHICH_NORM; cell->id = config->cell_id_file; cell->cp = CPNORM; @@ -99,7 +99,7 @@ int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell, pbch_mib_t *mi cuhd_rx_wait_lo_locked(q->uhd); DEBUG("Set uhd_freq to %.3f MHz\n", (double ) config->uhd_freq); - if (cell_search(q->uhd, config->force_N_id_2, cell, mib)) { + if (cell_search(q->uhd, config->force_N_id_2, cell)) { fprintf(stderr, "Cell not found\n"); return LIBLTE_ERROR; } diff --git a/lte/phy/examples/iodev.h b/lte/phy/examples/iodev.h index b6c36adc5..a437325a1 100644 --- a/lte/phy/examples/iodev.h +++ b/lte/phy/examples/iodev.h @@ -81,8 +81,7 @@ typedef struct LIBLTE_API { LIBLTE_API int iodev_init(iodev_t *q, iodev_cfg_t *config, - lte_cell_t *cell, - pbch_mib_t *mib); + lte_cell_t *cell); LIBLTE_API void iodev_free(iodev_t *q); diff --git a/lte/phy/examples/pdsch_enodeb.c b/lte/phy/examples/pdsch_enodeb.c index 2e1660e54..6f78098cf 100644 --- a/lte/phy/examples/pdsch_enodeb.c +++ b/lte/phy/examples/pdsch_enodeb.c @@ -32,6 +32,7 @@ #include #include "liblte/phy/phy.h" +#include "liblte/rrc/rrc.h" #ifndef DISABLE_UHD #include "liblte/cuhd/cuhd.h" @@ -44,7 +45,9 @@ lte_cell_t cell = { 6, // nof_prb 1, // nof_ports 1, // cell_id - CPNORM // cyclic prefix + CPNORM, // cyclic prefix + R_1, // PHICH resources + PHICH_NORM // PHICH length }; uint32_t cfi=1; @@ -173,7 +176,7 @@ void base_init() { exit(-1); } - if (regs_init(®s, R_1, PHICH_NORM, cell)) { + if (regs_init(®s, cell)) { fprintf(stderr, "Error initiating regs\n"); exit(-1); } @@ -236,7 +239,7 @@ int main(int argc, char **argv) { cf_t pss_signal[PSS_LEN]; float sss_signal0[SSS_LEN]; // for subframe 0 float sss_signal5[SSS_LEN]; // for subframe 5 - pbch_mib_t mib; + uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_packed[BCH_PAYLOAD_LEN/8]; ra_pdsch_t ra_dl; ra_prb_t prb_alloc; refsignal_t refs[NSLOTS_X_FRAME]; @@ -245,7 +248,8 @@ int main(int argc, char **argv) { cf_t *sf_symbols[MAX_PORTS]; dci_msg_t dci_msg; dci_location_t locations[NSUBFRAMES_X_FRAME][10]; - + uint32_t sfn; + #ifdef DISABLE_UHD if (argc < 3) { usage(argv[0]); @@ -274,11 +278,9 @@ int main(int argc, char **argv) { } } - mib.nof_ports = cell.nof_ports; - mib.nof_prb = cell.nof_prb; - mib.phich_length = PHICH_NORM; - mib.phich_resources = R_1; - mib.sfn = 0; + cell.phich_length = PHICH_NORM; + cell.phich_resources = R_1; + sfn = 0; for (i = 0; i < MAX_PORTS; i++) { // now there's only 1 port sf_symbols[i] = sf_buffer; @@ -338,8 +340,10 @@ int main(int argc, char **argv) { CPNORM); } + bcch_bch_mib_pack(&cell, sfn, bch_payload_packed, BCH_PAYLOAD_LEN/8); + bit_pack_vector(bch_payload_packed, bch_payload, BCH_PAYLOAD_LEN); if (sf_idx == 0) { - pbch_encode(&pbch, &mib, sf_symbols); + pbch_encode(&pbch, bch_payload, sf_symbols); } for (n=0;n<2;n++) { @@ -379,8 +383,8 @@ int main(int argc, char **argv) { } nf++; } - mib.sfn = (mib.sfn + 1) % 1024; - printf("SFN: %4d\r", mib.sfn); + sfn = (sfn + 1) % 1024; + printf("SFN: %4d\r", sfn); fflush(stdout); } diff --git a/lte/phy/examples/pdsch_ue.c b/lte/phy/examples/pdsch_ue.c index f1949ad50..3095ec8e7 100644 --- a/lte/phy/examples/pdsch_ue.c +++ b/lte/phy/examples/pdsch_ue.c @@ -171,7 +171,6 @@ int main(int argc, char **argv) { lte_cell_t cell; ue_dl_t ue_dl; int64_t sf_cnt; - pbch_mib_t mib; bool printed_sib = false; int rlen; @@ -186,11 +185,11 @@ int main(int argc, char **argv) { /* Initialize subframe counter */ sf_cnt = 0; - if (iodev_init(&iodev, &prog_args.io_config, &cell, &mib)) { + if (iodev_init(&iodev, &prog_args.io_config, &cell)) { exit(-1); } - if (ue_dl_init(&ue_dl, cell, mib.phich_resources, mib.phich_length, 1234)) { + if (ue_dl_init(&ue_dl, cell, 1234)) { fprintf(stderr, "Error initiating UE downlink processing module\n"); exit(-1); } diff --git a/lte/phy/include/liblte/phy/phch/pbch.h b/lte/phy/include/liblte/phy/phch/pbch.h index 22b7bb106..2716f1d89 100644 --- a/lte/phy/include/liblte/phy/phch/pbch.h +++ b/lte/phy/include/liblte/phy/phch/pbch.h @@ -41,19 +41,15 @@ #include "liblte/phy/fec/viterbi.h" #include "liblte/phy/fec/crc.h" +#define BCH_PAYLOAD_LEN 24 +#define BCH_PAYLOADCRC_LEN (BCH_PAYLOAD_LEN+16) +#define BCH_ENCODED_LEN 3*(BCH_PAYLOADCRC_LEN) + #define PBCH_RE_CPNORM 240 -#define PBCH_RE_CPEXT 216 +#define PBCH_RE_CPEXT 216 typedef _Complex float cf_t; -typedef struct LIBLTE_API { - uint32_t nof_ports; - uint32_t nof_prb; - uint32_t sfn; - phich_length_t phich_length; - phich_resources_t phich_resources; -}pbch_mib_t; - /* PBCH object */ typedef struct LIBLTE_API { lte_cell_t cell; @@ -67,10 +63,10 @@ typedef struct LIBLTE_API { cf_t *pbch_d; float *pbch_llr; float *temp; - float *pbch_rm_f; + float pbch_rm_f[BCH_ENCODED_LEN]; uint8_t *pbch_rm_b; - uint8_t *data; - uint8_t *data_enc; + uint8_t data[BCH_PAYLOADCRC_LEN]; + uint8_t data_enc[BCH_ENCODED_LEN]; uint32_t frame_idx; @@ -91,16 +87,14 @@ LIBLTE_API void pbch_free(pbch_t *q); LIBLTE_API int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], - pbch_mib_t *mib); + uint8_t bch_payload[BCH_PAYLOAD_LEN], + uint32_t *nof_tx_ports, + uint32_t *sfn_offset); LIBLTE_API int pbch_encode(pbch_t *q, - pbch_mib_t *mib, - cf_t *slot1_symbols[MAX_PORTS]); + uint8_t bch_payload[BCH_PAYLOAD_LEN], + cf_t *slot1_symbols[MAX_PORTS]); LIBLTE_API void pbch_decode_reset(pbch_t *q); -LIBLTE_API void pbch_mib_fprint(FILE *stream, - pbch_mib_t *mib, - uint32_t cell_id); - #endif // PBCH_ diff --git a/lte/phy/include/liblte/phy/phch/regs.h b/lte/phy/include/liblte/phy/phch/regs.h index 1b2f470d6..b3e015016 100644 --- a/lte/phy/include/liblte/phy/phch/regs.h +++ b/lte/phy/include/liblte/phy/phch/regs.h @@ -76,8 +76,6 @@ typedef struct LIBLTE_API { }regs_t; LIBLTE_API int regs_init(regs_t *h, - phich_resources_t phich_res, - phich_length_t phich_len, lte_cell_t cell); LIBLTE_API void regs_free(regs_t *h); diff --git a/lte/phy/include/liblte/phy/ue/ue_dl.h b/lte/phy/include/liblte/phy/ue/ue_dl.h index c60e49ae4..8a8ad8630 100644 --- a/lte/phy/include/liblte/phy/ue/ue_dl.h +++ b/lte/phy/include/liblte/phy/ue/ue_dl.h @@ -84,8 +84,6 @@ typedef struct LIBLTE_API { /* This function shall be called just after the initial synchronization */ LIBLTE_API int ue_dl_init(ue_dl_t *q, lte_cell_t cell, - phich_resources_t phich_resources, - phich_length_t phich_length, uint16_t user_rnti); LIBLTE_API void ue_dl_free(ue_dl_t *q); diff --git a/lte/phy/include/liblte/phy/ue/ue_mib.h b/lte/phy/include/liblte/phy/ue/ue_mib.h index 75f8c69bb..272c56b37 100644 --- a/lte/phy/include/liblte/phy/ue/ue_mib.h +++ b/lte/phy/include/liblte/phy/ue/ue_mib.h @@ -91,7 +91,9 @@ LIBLTE_API void ue_mib_reset(ue_mib_t *q); LIBLTE_API int ue_mib_decode(ue_mib_t *q, cf_t *signal, uint32_t nsamples, - pbch_mib_t *mib); + uint8_t bch_payload[BCH_PAYLOAD_LEN], + uint32_t *nof_tx_ports, + uint32_t *sfn_offset); LIBLTE_API void ue_mib_set_threshold(ue_mib_t *q, float threshold); diff --git a/lte/phy/include/liblte/phy/utils/bit.h b/lte/phy/include/liblte/phy/utils/bit.h index 3100ccf95..6a2f53831 100644 --- a/lte/phy/include/liblte/phy/utils/bit.h +++ b/lte/phy/include/liblte/phy/utils/bit.h @@ -34,10 +34,29 @@ #include "liblte/config.h" -LIBLTE_API uint32_t bit_unpack(uint8_t **bits, int nof_bits); -LIBLTE_API void bit_pack(uint32_t value, uint8_t **bits, int nof_bits); -LIBLTE_API void bit_fprint(FILE *stream, uint8_t *bits, int nof_bits); -LIBLTE_API uint32_t bit_diff(uint8_t *x, uint8_t *y, int nbits); +LIBLTE_API void bit_pack_vector(uint8_t *bit_unpacked, + uint8_t *bits_packed, + int nof_bits); + +LIBLTE_API void bit_unpack_vector(uint8_t *bits_packed, + uint8_t *bit_unpacked, + int nof_bits); + +LIBLTE_API uint32_t bit_unpack(uint8_t **bits, + int nof_bits); + +LIBLTE_API void bit_pack(uint32_t value, + uint8_t **bits, + int nof_bits); + +LIBLTE_API void bit_fprint(FILE *stream, + uint8_t *bits, + int nof_bits); + +LIBLTE_API uint32_t bit_diff(uint8_t *x, + uint8_t *y, + int nbits); + LIBLTE_API uint32_t bit_count(uint32_t n); #endif // BIT_ diff --git a/lte/phy/lib/phch/src/pbch.c b/lte/phy/lib/phch/src/pbch.c index beab9976f..26f10a3b6 100644 --- a/lte/phy/lib/phch/src/pbch.c +++ b/lte/phy/lib/phch/src/pbch.c @@ -185,22 +185,10 @@ int pbch_init(pbch_t *q, lte_cell_t cell) { if (!q->temp) { goto clean; } - q->pbch_rm_f = malloc(sizeof(float) * 120); - if (!q->pbch_rm_f) { - goto clean; - } q->pbch_rm_b = malloc(sizeof(float) * q->nof_symbols * 4 * 2); if (!q->pbch_rm_b) { goto clean; } - q->data = malloc(sizeof(uint8_t) * 40); - if (!q->data) { - goto clean; - } - q->data_enc = malloc(sizeof(uint8_t) * 120); - if (!q->data_enc) { - goto clean; - } ret = LIBLTE_SUCCESS; } clean: @@ -232,129 +220,14 @@ void pbch_free(pbch_t *q) { if (q->temp) { free(q->temp); } - if (q->pbch_rm_f) { - free(q->pbch_rm_f); - } if (q->pbch_rm_b) { free(q->pbch_rm_b); } - if (q->data_enc) { - free(q->data_enc); - } - if (q->data) { - free(q->data); - } sequence_free(&q->seq_pbch); modem_table_free(&q->mod); viterbi_free(&q->decoder); } -/** Unpacks MIB from PBCH message. - * msg buffer must be 24 byte length at least - */ -void pbch_mib_unpack(uint8_t *msg, pbch_mib_t *mib) { - int bw, phich_res; - - bw = bit_unpack(&msg, 3); - switch (bw) { - case 0: - mib->nof_prb = 6; - break; - case 1: - mib->nof_prb = 15; - break; - default: - mib->nof_prb = (bw - 1) * 25; - break; - } - if (*msg) { - mib->phich_length = PHICH_EXT; - } else { - mib->phich_length = PHICH_NORM; - } - msg++; - - phich_res = bit_unpack(&msg, 2); - switch (phich_res) { - case 0: - mib->phich_resources = R_1_6; - break; - case 1: - mib->phich_resources = R_1_2; - break; - case 2: - mib->phich_resources = R_1; - break; - case 3: - mib->phich_resources = R_2; - break; - } - mib->sfn = bit_unpack(&msg, 8) << 2; -} - -/** Unpacks MIB from PBCH message. - * msg buffer must be 24 byte length at least - */ -void pbch_mib_pack(pbch_mib_t *mib, uint8_t *msg) { - int bw, phich_res = 0; - - bzero(msg, 24); - - if (mib->nof_prb <= 6) { - bw = 0; - } else if (mib->nof_prb <= 15) { - bw = 1; - } else { - bw = 1 + mib->nof_prb / 25; - } - bit_pack(bw, &msg, 3); - - *msg = mib->phich_length == PHICH_EXT; - msg++; - - switch (mib->phich_resources) { - case R_1_6: - phich_res = 0; - break; - case R_1_2: - phich_res = 1; - break; - case R_1: - phich_res = 2; - break; - case R_2: - phich_res = 3; - break; - } - bit_pack(phich_res, &msg, 2); - bit_pack(mib->sfn >> 2, &msg, 8); -} - -void pbch_mib_fprint(FILE *stream, pbch_mib_t *mib, uint32_t cell_id) { - printf(" - Cell ID: %d\n", cell_id); - printf(" - Nof ports: %d\n", mib->nof_ports); - printf(" - PRB: %d\n", mib->nof_prb); - printf(" - PHICH Length: %s\n", - mib->phich_length == PHICH_EXT ? "Extended" : "Normal"); - printf(" - PHICH Resources: "); - switch (mib->phich_resources) { - case R_1_6: - printf("1/6"); - break; - case R_1_2: - printf("1/2"); - break; - case R_1: - printf("1"); - break; - case R_2: - printf("2"); - break; - } - printf("\n"); - printf(" - SFN: %d\n", mib->sfn); -} - void pbch_decode_reset(pbch_t *q) { q->frame_idx = 0; } @@ -362,7 +235,7 @@ void pbch_decode_reset(pbch_t *q) { void crc_set_mask(uint8_t *data, int nof_ports) { int i; for (i = 0; i < 16; i++) { - data[24 + i] = (data[24 + i] + crc_mask[nof_ports - 1][i]) % 2; + data[BCH_PAYLOAD_LEN + i] = (data[BCH_PAYLOAD_LEN + i] + crc_mask[nof_ports - 1][i]) % 2; } } @@ -374,13 +247,13 @@ void crc_set_mask(uint8_t *data, int nof_ports) { * Returns 0 if the data is correct, -1 otherwise */ uint32_t pbch_crc_check(pbch_t *q, uint8_t *bits, uint32_t nof_ports) { - uint8_t data[40]; - memcpy(data, bits, 40 * sizeof(uint8_t)); + uint8_t data[BCH_PAYLOADCRC_LEN]; + memcpy(data, bits, BCH_PAYLOADCRC_LEN * sizeof(uint8_t)); crc_set_mask(data, nof_ports); - int ret = crc_checksum(&q->crc, data, 40); + int ret = crc_checksum(&q->crc, data, BCH_PAYLOADCRC_LEN); if (ret == 0) { uint32_t chkzeros=0; - for (int i=0;i<24 && !chkzeros;i++) { + for (int i=0;itemp, 4 * nof_bits, q->pbch_rm_f, 120); + rm_conv_rx(q->temp, 4 * nof_bits, q->pbch_rm_f, BCH_ENCODED_LEN); /* FIXME: If channel estimates are zero, received LLR are NaN. Check and return error */ - for (j = 0; j < 120; j++) { + for (j = 0; j < BCH_ENCODED_LEN; j++) { if (isnan(q->pbch_rm_f[j]) || isinf(q->pbch_rm_f[j])) { return 0; } } /* decode */ - viterbi_decode_f(&q->decoder, q->pbch_rm_f, q->data, 40); - - int c = 0; - for (j = 0; j < 40; j++) { - c += q->data[j]; - } - if (!c) { - c = 1; - } - - if (!pbch_crc_check(q, q->data, nof_ports)) { - /* unpack MIB */ - pbch_mib_unpack(q->data, mib); - - mib->nof_ports = nof_ports; - mib->sfn += dst - src; + viterbi_decode_f(&q->decoder, q->pbch_rm_f, q->data, BCH_PAYLOADCRC_LEN); + if (!pbch_crc_check(q, q->data, nof_ports)) { return 1; } else { - return 0; + return LIBLTE_SUCCESS; } } @@ -453,7 +312,9 @@ int pbch_decode_frame(pbch_t *q, pbch_mib_t *mib, uint32_t src, uint32_t dst, ui * * Returns 1 if successfully decoded MIB, 0 if not and -1 on error */ -int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], pbch_mib_t *mib) { +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; @@ -464,8 +325,7 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], pbch_ int ret = LIBLTE_ERROR_INVALID_INPUTS; if (q != NULL && - slot1_symbols != NULL && - mib != NULL) + slot1_symbols != NULL) { for (i=0;icell.nof_ports;i++) { if (ce_slot1[i] == NULL) { @@ -531,8 +391,7 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], pbch_ 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++) { - ret = pbch_decode_frame(q, mib, src, dst, nb + 1, nof_bits, nant); - + ret = pbch_decode_frame(q, src, dst, nb + 1, nof_bits, nant); } } } @@ -544,18 +403,29 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], pbch_ q->frame_idx = 3; } } + if (ret == 1) { + if (sfn_offset) { + *sfn_offset = dst - src; + } + if (nof_tx_ports) { + *nof_tx_ports = nant; + } + if (bch_payload) { + memcpy(bch_payload, q->data, sizeof(uint8_t) * BCH_PAYLOAD_LEN); + } + } return ret; } /** 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 *slot1_symbols[MAX_PORTS]) { +int pbch_encode(pbch_t *q, uint8_t bch_payload[BCH_PAYLOAD_LEN], cf_t *slot1_symbols[MAX_PORTS]) { int i; int nof_bits; cf_t *x[MAX_LAYERS]; if (q != NULL && - mib != NULL) + bch_payload != NULL) { for (i=0;icell.nof_ports;i++) { if (slot1_symbols[i] == NULL) { @@ -572,16 +442,15 @@ int pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *slot1_symbols[MAX_PORTS]) { 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); + memcpy(q->data, bch_payload, sizeof(uint8_t) * BCH_PAYLOAD_LEN); /* encode & modulate */ - crc_attach(&q->crc, q->data, 24); + crc_attach(&q->crc, q->data, BCH_PAYLOAD_LEN); crc_set_mask(q->data, q->cell.nof_ports); + + convcoder_encode(&q->encoder, q->data, q->data_enc, BCH_PAYLOADCRC_LEN); - convcoder_encode(&q->encoder, q->data, q->data_enc, 40); - - rm_conv_tx(q->data_enc, 120, q->pbch_rm_b, 4 * nof_bits); + rm_conv_tx(q->data_enc, BCH_ENCODED_LEN, q->pbch_rm_b, 4 * nof_bits); } diff --git a/lte/phy/lib/phch/src/regs.c b/lte/phy/lib/phch/src/regs.c index 1f6112f9d..902ef2375 100644 --- a/lte/phy/lib/phch/src/regs.c +++ b/lte/phy/lib/phch/src/regs.c @@ -672,7 +672,7 @@ int regs_set_cfi(regs_t *h, uint32_t cfi) { * Sets all REG indices and initializes PCFICH, PHICH and PDCCH REGs * Returns 0 if OK, -1 on error */ -int regs_init(regs_t *h, phich_resources_t phich_res, phich_length_t phich_len, lte_cell_t cell) { +int regs_init(regs_t *h, lte_cell_t cell) { int ret = LIBLTE_ERROR_INVALID_INPUTS; uint32_t i, k; uint32_t j[4], jmax, prb; @@ -690,8 +690,8 @@ int regs_init(regs_t *h, phich_resources_t phich_res, phich_length_t phich_len, h->cell = cell; h->max_ctrl_symbols = max_ctrl_symbols; h->cfi_initiated = false; - h->phich_res = phich_res; - h->phich_len = phich_len; + h->phich_res = cell.phich_resources; + h->phich_len = cell.phich_length; h->nof_regs = 0; for (i = 0; i < max_ctrl_symbols; i++) { diff --git a/lte/phy/lib/phch/test/pbch_file_test.c b/lte/phy/lib/phch/test/pbch_file_test.c index 78e2b982a..e4d52b459 100644 --- a/lte/phy/lib/phch/test/pbch_file_test.c +++ b/lte/phy/lib/phch/test/pbch_file_test.c @@ -42,9 +42,13 @@ lte_cell_t cell = { 6, // nof_prb 2, // nof_ports 150, // cell_id - CPNORM // cyclic prefix + CPNORM, // cyclic prefix + R_1, // PHICH resources + PHICH_NORM // PHICH length }; +uint8_t bch_payload_file[BCH_PAYLOAD_LEN] = {0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + #define FLEN 9600 filesource_t fsrc; @@ -177,9 +181,10 @@ void base_free() { } int main(int argc, char **argv) { - pbch_mib_t mib; + uint8_t bch_payload[BCH_PAYLOAD_LEN]; int n; - + uint32_t nof_tx_ports, sfn_offset; + if (argc < 3) { usage(argv[0]); exit(-1); @@ -209,10 +214,9 @@ int main(int argc, char **argv) { INFO("Decoding PBCH\n", 0); - n = pbch_decode(&pbch, fft_buffer, ce, &mib); + n = pbch_decode(&pbch, fft_buffer, ce, bch_payload, &nof_tx_ports, &sfn_offset); base_free(); - if (n < 0) { fprintf(stderr, "Error decoding PBCH\n"); exit(-1); @@ -220,13 +224,12 @@ int main(int argc, char **argv) { 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("MIB decoded OK. Nof ports: %d. SFN offset: %d Payload: ", nof_tx_ports, sfn_offset); + vec_fprint_hex(stdout, bch_payload, BCH_PAYLOAD_LEN); + if (nof_tx_ports == 2 && sfn_offset == 0 && !memcmp(bch_payload, bch_payload_file, BCH_PAYLOAD_LEN)) { 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); } diff --git a/lte/phy/lib/phch/test/pbch_test.c b/lte/phy/lib/phch/test/pbch_test.c index 77ad172bb..4f1a106b1 100644 --- a/lte/phy/lib/phch/test/pbch_test.c +++ b/lte/phy/lib/phch/test/pbch_test.c @@ -37,7 +37,9 @@ lte_cell_t cell = { 6, // nof_prb 1, // nof_ports 1, // cell_id - CPNORM // cyclic prefix + CPNORM, // cyclic prefix + R_1, // PHICH resources + PHICH_NORM // PHICH length }; void usage(char *prog) { @@ -74,11 +76,12 @@ void parse_args(int argc, char **argv) { int main(int argc, char **argv) { pbch_t pbch; - pbch_mib_t mib_tx, mib_rx; + uint8_t bch_payload_tx[BCH_PAYLOAD_LEN], bch_payload_rx[BCH_PAYLOAD_LEN]; int i, j; cf_t *ce[MAX_PORTS]; int nof_re; cf_t *slot1_symbols[MAX_PORTS]; + uint32_t nof_rx_ports; parse_args(argc,argv); @@ -106,13 +109,11 @@ int main(int argc, char **argv) { exit(-1); } - mib_tx.nof_ports = cell.nof_ports; - mib_tx.nof_prb = 50; - mib_tx.phich_length = PHICH_EXT; - mib_tx.phich_resources = R_1_6; - mib_tx.sfn = 124; + for (i=0;iregs, phich_resources, phich_length, q->cell)) { + if (regs_init(&q->regs, q->cell)) { fprintf(stderr, "Error initiating REGs\n"); goto clean_exit; } @@ -154,7 +153,6 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16 uint32_t nof_locations; uint16_t crc_rem; dci_format_t format; - pbch_mib_t mib; int ret = LIBLTE_ERROR; cf_t *ce_slot1[MAX_PORTS]; struct timeval t[3]; @@ -180,14 +178,13 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16 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, &mib) == 1) { - q->sfn = mib.sfn; + 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 == 1024) { + if (q->sfn == 4) { q->sfn = 0; } } diff --git a/lte/phy/lib/ue/src/ue_mib.c b/lte/phy/lib/ue/src/ue_mib.c index 855f855c9..82d16046a 100644 --- a/lte/phy/lib/ue/src/ue_mib.c +++ b/lte/phy/lib/ue/src/ue_mib.c @@ -139,7 +139,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, pbch_mib_t *mib) +static int mib_decoder_run(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,7 +163,7 @@ static int mib_decoder_run(ue_mib_t * q, cf_t *input, pbch_mib_t *mib) } /* Decode PBCH */ - ret = pbch_decode(&q->pbch, q->slot1_symbols, q->ce, mib); + 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"); } else if (ret == 1) { @@ -181,7 +182,9 @@ int counter1=0,counter2=0,counter3=0,counter4=0; int ue_mib_decode(ue_mib_t * q, cf_t *signal, uint32_t nsamples, - pbch_mib_t *mib) + uint8_t bch_payload[BCH_PAYLOAD_LEN], + uint32_t *nof_tx_ports, + uint32_t *sfn_offset) { int ret = LIBLTE_ERROR_INVALID_INPUTS; uint32_t peak_idx=0; @@ -226,7 +229,7 @@ int ue_mib_decode(ue_mib_t * q, 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], mib); + ret = mib_decoder_run(q, &signal[nf*MIB_FRAME_SIZE+peak_idx], bch_payload, nof_tx_ports, sfn_offset); counter3++; } else if ((ret == LIBLTE_SUCCESS && peak_idx != 0) || (ret == 1 && nf*MIB_FRAME_SIZE + peak_idx + 960 > nsamples)) diff --git a/lte/phy/lib/ue/test/ue_celldetect_mib_test.c b/lte/phy/lib/ue/test/ue_celldetect_mib_test.c index 027f9b33e..040f60baf 100644 --- a/lte/phy/lib/ue/test/ue_celldetect_mib_test.c +++ b/lte/phy/lib/ue/test/ue_celldetect_mib_test.c @@ -97,8 +97,9 @@ void parse_args(int argc, char **argv) { int decode_pbch(void *uhd, cf_t *buffer, ue_celldetect_result_t *found_cell) { ue_mib_t uemib; - pbch_mib_t mib; + uint8_t bch_payload[BCH_PAYLOAD_LEN]; int n; + uint32_t nof_tx_ports; uint32_t nof_frames = 0; uint32_t flen = MIB_FRAME_SIZE; @@ -121,7 +122,7 @@ int decode_pbch(void *uhd, cf_t *buffer, ue_celldetect_result_t *found_cell) INFO("Calling ue_mib_decode() %d/%d\n", nof_frames, nof_frames_total); - n = ue_mib_decode(&uemib, buffer, flen, &mib); + n = ue_mib_decode(&uemib, buffer, flen, bch_payload, &nof_tx_ports, NULL); if (n == LIBLTE_ERROR || n == LIBLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling ue_mib_decode()\n"); return LIBLTE_ERROR; @@ -136,8 +137,8 @@ int decode_pbch(void *uhd, cf_t *buffer, ue_celldetect_result_t *found_cell) nof_frames++; } while (n != MIB_FOUND && nof_frames < nof_frames_total); if (n == MIB_FOUND) { - printf("\n\nMIB decoded in %d ms (%d half frames)\n", nof_frames*5, nof_frames); - pbch_mib_fprint(stdout, &mib, found_cell->cell_id); + printf("\n\nMIB decoded in %d ms (%d half frames). %d TX ports\n", nof_frames*5, nof_frames, nof_tx_ports); + vec_fprint_hex(stdout, bch_payload, BCH_PAYLOAD_LEN); } else { printf("\nCould not decode MIB\n"); } diff --git a/lte/phy/lib/utils/src/bit.c b/lte/phy/lib/utils/src/bit.c index 4443bc744..c2637281e 100644 --- a/lte/phy/lib/utils/src/bit.c +++ b/lte/phy/lib/utils/src/bit.c @@ -31,6 +31,19 @@ #include "liblte/phy/utils/bit.h" + +void bit_pack_vector(uint8_t *bit_unpacked, uint8_t *bits_packed, int nof_bits) +{ + uint32_t i, nbytes; + nbytes = nof_bits/8; + for (i=0;i