mirror of https://github.com/PentHertz/srsLTE.git
Moved BCCH-BCH MIB unpacking to RRC layer
This commit is contained in:
parent
1adfc16e1d
commit
4232020557
|
@ -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.")
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,11 +36,13 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
lte_cell_t *cell);
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;i<BCH_PAYLOAD_LEN && !chkzeros;i++) {
|
||||
chkzeros += data[i];
|
||||
}
|
||||
if (chkzeros) {
|
||||
|
@ -393,7 +266,7 @@ uint32_t pbch_crc_check(pbch_t *q, uint8_t *bits, uint32_t nof_ports) {
|
|||
}
|
||||
}
|
||||
|
||||
int pbch_decode_frame(pbch_t *q, pbch_mib_t *mib, uint32_t src, uint32_t dst, uint32_t n,
|
||||
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;
|
||||
|
||||
|
@ -412,36 +285,22 @@ int pbch_decode_frame(pbch_t *q, pbch_mib_t *mib, uint32_t src, uint32_t dst, ui
|
|||
}
|
||||
|
||||
/* unrate matching */
|
||||
rm_conv_rx(q->temp, 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;i<q->cell.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;i<q->cell.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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;i<BCH_PAYLOAD_LEN;i++) {
|
||||
bch_payload_tx[i] = rand()%2;
|
||||
}
|
||||
|
||||
pbch_encode(&pbch, &mib_tx, slot1_symbols);
|
||||
pbch_encode(&pbch, bch_payload_tx, slot1_symbols);
|
||||
|
||||
/* combine outputs */
|
||||
for (i=1;i<cell.nof_ports;i++) {
|
||||
|
@ -120,9 +121,9 @@ int main(int argc, char **argv) {
|
|||
slot1_symbols[0][j] += slot1_symbols[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pbch_decode_reset(&pbch);
|
||||
if (1 != pbch_decode(&pbch, slot1_symbols[0], ce, &mib_rx)) {
|
||||
if (1 != pbch_decode(&pbch, slot1_symbols[0], ce, bch_payload_rx, &nof_rx_ports, NULL)) {
|
||||
printf("Error decoding\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -134,11 +135,16 @@ int main(int argc, char **argv) {
|
|||
free(slot1_symbols[i]);
|
||||
}
|
||||
|
||||
if (!memcmp(&mib_tx, &mib_rx, sizeof(pbch_mib_t))) {
|
||||
if (nof_rx_ports == cell.nof_ports && !memcmp(bch_payload_rx, bch_payload_tx, sizeof(uint8_t) * BCH_PAYLOAD_LEN)) {
|
||||
printf("OK\n");
|
||||
exit(0);
|
||||
} else {
|
||||
pbch_mib_fprint(stdout, &mib_rx, cell.id);
|
||||
printf("Error\n");
|
||||
printf("Tx ports: %d - Rx ports: %d\n", cell.nof_ports, nof_rx_ports);
|
||||
printf("Tx payload: ");
|
||||
vec_fprint_hex(stdout, bch_payload_tx, BCH_PAYLOAD_LEN);
|
||||
printf("Rx payload: ");
|
||||
vec_fprint_hex(stdout, bch_payload_rx, BCH_PAYLOAD_LEN);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,9 @@ lte_cell_t cell = {
|
|||
6, // nof_prb
|
||||
1, // nof_ports
|
||||
0, // cell_id
|
||||
CPNORM // cyclic prefix
|
||||
CPNORM, // cyclic prefix
|
||||
R_1, // PHICH resources
|
||||
PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
int flen;
|
||||
|
@ -151,7 +153,7 @@ int base_init() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (regs_init(®s, R_1, PHICH_NORM, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating REGs\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,9 @@ lte_cell_t cell = {
|
|||
6, // nof_prb
|
||||
1, // nof_ports
|
||||
1000, // cell_id
|
||||
CPNORM // cyclic prefix
|
||||
CPNORM, // cyclic prefix
|
||||
R_1, // PHICH resources
|
||||
PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
void usage(char *prog) {
|
||||
|
@ -111,12 +113,13 @@ int main(int argc, char **argv) {
|
|||
cid = cell.id;
|
||||
max_cid = cell.id;
|
||||
}
|
||||
|
||||
while(cid <= max_cid) {
|
||||
cell.id = cid;
|
||||
|
||||
printf("Testing CellID=%d...\n", cid);
|
||||
|
||||
if (regs_init(®s, R_1, PHICH_NORM, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,9 @@ lte_cell_t cell = {
|
|||
6, // cell.cell.cell.nof_prb
|
||||
1, // cell.cell.nof_ports
|
||||
0, // cell.id
|
||||
CPNORM // cyclic prefix
|
||||
CPNORM, // cyclic prefix
|
||||
R_1, // PHICH resources
|
||||
PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
uint32_t cfi = 2;
|
||||
|
@ -165,7 +167,7 @@ int base_init() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (regs_init(®s, R_1, PHICH_NORM, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
uint32_t cfi = 1;
|
||||
|
@ -142,7 +144,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (regs_init(®s, R_1, PHICH_NORM, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,9 @@ lte_cell_t cell = {
|
|||
6, // nof_prb
|
||||
1, // nof_ports
|
||||
0, // cell_id
|
||||
CPNORM // cyclic prefix
|
||||
CPNORM, // cyclic prefix
|
||||
R_1, // PHICH resources
|
||||
PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
int flen;
|
||||
|
@ -168,7 +170,7 @@ int base_init() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (regs_init(®s, R_1, PHICH_NORM, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,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;
|
||||
|
|
|
@ -40,13 +40,13 @@ lte_cell_t cell = {
|
|||
50, // cell.nof_prb
|
||||
2, // cell.nof_ports
|
||||
150, // cell.id
|
||||
CPNORM // cyclic prefix
|
||||
CPNORM, // cyclic prefix
|
||||
R_1, // PHICH resources
|
||||
PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
int flen;
|
||||
int nof_ctrl_symbols = 1;
|
||||
phich_resources_t phich_res = R_1;
|
||||
phich_length_t phich_length = PHICH_NORM;
|
||||
int numsubframe = 0;
|
||||
|
||||
FILE *fmatlab = NULL;
|
||||
|
@ -89,19 +89,19 @@ void parse_args(int argc, char **argv) {
|
|||
break;
|
||||
case 'g':
|
||||
if (!strcmp(argv[optind], "1/6")) {
|
||||
phich_res = R_1_6;
|
||||
cell.phich_resources = R_1_6;
|
||||
} else if (!strcmp(argv[optind], "1/2")) {
|
||||
phich_res = R_1_2;
|
||||
cell.phich_resources = R_1_2;
|
||||
} else if (!strcmp(argv[optind], "1")) {
|
||||
phich_res = R_1;
|
||||
cell.phich_resources = R_1;
|
||||
} else if (!strcmp(argv[optind], "2")) {
|
||||
phich_res = R_2;
|
||||
cell.phich_resources = R_2;
|
||||
} else {
|
||||
fprintf(stderr, "Invalid phich ng factor %s. Setting to default.\n", argv[optind]);
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
phich_length = PHICH_EXT;
|
||||
cell.phich_length = PHICH_EXT;
|
||||
break;
|
||||
case 'n':
|
||||
cell.nof_prb = atoi(argv[optind]);
|
||||
|
@ -176,7 +176,7 @@ int base_init() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (regs_init(®s, phich_res, phich_length, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,9 @@ lte_cell_t cell = {
|
|||
6, // nof_prb
|
||||
1, // nof_ports
|
||||
1000, // cell_id
|
||||
CPNORM // cyclic prefix
|
||||
CPNORM, // cyclic prefix
|
||||
R_1, // PHICH resources
|
||||
PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
phich_resources_t phich_res = R_1;
|
||||
|
@ -145,7 +147,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
printf("Testing CellID=%d...\n", cid);
|
||||
|
||||
if (regs_init(®s, phich_res, phich_length, cell)) {
|
||||
if (regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
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)
|
||||
{
|
||||
int ret = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
@ -65,7 +64,7 @@ int ue_dl_init(ue_dl_t *q,
|
|||
fprintf(stderr, "Error initiating channel estimator\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
if (regs_init(&q->regs, 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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<nbytes;i++) {
|
||||
bit_pack(bits_packed[i], &bits_packed, 8);
|
||||
}
|
||||
if (nof_bits%8) {
|
||||
bit_pack(bits_packed[i], &bits_packed, nof_bits%8);
|
||||
}
|
||||
}
|
||||
|
||||
void bit_pack(uint32_t value, uint8_t **bits, int nof_bits)
|
||||
{
|
||||
int i;
|
||||
|
@ -41,6 +54,18 @@ void bit_pack(uint32_t value, uint8_t **bits, int nof_bits)
|
|||
*bits += nof_bits;
|
||||
}
|
||||
|
||||
void bit_unpack_vector(uint8_t *bits_packed, uint8_t *bit_unpacked, int nof_bits)
|
||||
{
|
||||
uint32_t i, nbytes;
|
||||
nbytes = nof_bits/8;
|
||||
for (i=0;i<nbytes;i++) {
|
||||
bits_packed[i] = bit_unpack(&bit_unpacked, 8);
|
||||
}
|
||||
if (nof_bits%8) {
|
||||
bits_packed[i] = bit_unpack(&bit_unpacked, nof_bits%8);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bit_unpack(uint8_t **bits, int nof_bits)
|
||||
{
|
||||
int i;
|
||||
|
|
Loading…
Reference in New Issue