diff --git a/lte/phy/examples/pdsch_enodeb.c b/lte/phy/examples/pdsch_enodeb.c index 10d9c190a..34947396e 100644 --- a/lte/phy/examples/pdsch_enodeb.c +++ b/lte/phy/examples/pdsch_enodeb.c @@ -229,7 +229,8 @@ int main(int argc, char **argv) { int i, n; char *data; cf_t *sf_symbols[MAX_PORTS]; - dci_t dci_tx; + dci_msg_t dci_msg; + dci_location_t locations[NSUBFRAMES_X_FRAME][10]; #ifdef DISABLE_UHD if (argc < 3) { @@ -279,7 +280,6 @@ int main(int argc, char **argv) { } #endif - dci_init(&dci_tx, 1); bzero(&ra_dl, sizeof(ra_pdsch_t)); ra_dl.harq_process = 0; ra_pdsch_set_mcs(&ra_dl, QPSK, 5); @@ -288,16 +288,18 @@ int main(int argc, char **argv) { ra_dl.alloc_type = alloc_type0; ra_dl.type0_alloc.rbg_bitmask = 0xffffffff; - dci_msg_pack_pdsch(&ra_dl, &dci_tx.msg[0], Format1, cell.nof_prb, false); - dci_tx.nof_dcis++; + dci_msg_pack_pdsch(&ra_dl, &dci_msg, Format1, cell.nof_prb, false); - pdcch_init_search_ue(&pdcch, 1234, cfi); - ra_prb_get_dl(&prb_alloc, &ra_dl, cell.nof_prb); ra_prb_get_re_dl(&prb_alloc, cell.nof_prb, 1, cell.nof_prb<10?(cfi+1):cfi, CPNORM); ra_dl.mcs.tbs = ra_tbs_from_idx(ra_dl.mcs.tbs_idx, cell.nof_prb); ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); + + /* Initiate valid DCI locations */ + for (i=0;i cell.nof_prb) { @@ -426,26 +426,33 @@ int rx_run(cf_t *input, int sf_idx) { fprintf(stderr, "Error setting CFI\n"); return -1; } + + /* Search only UE-specific locations */ + nof_locations = pdcch_ue_locations(&pdcch, locations, 10, sf_idx, cfi, 1234); + + pdcch_extract_llr(&pdcch, fft_buffer, ce, nof_frames, cfi); + + + nof_dcis = pdcch_decode_msg(&pdcch, &dci_msg, locations, nof_locations, Format1, 1234); + if (nof_dcis < 0) { + fprintf(stderr, "Error decoding DCI messages\n"); + return -1; + } - pdcch_init_search_ue(&pdcch, 1234, cfi); + INFO("Received %d DCI messages\n", nof_dcis); - dci_set.nof_dcis = 0; - nof_dcis = pdcch_decode(&pdcch, fft_buffer, ce, &dci_set, sf_idx, cfi); - INFO("Received %d DCIs\n", nof_dcis); - for (i=0;i #include +#include #include #include "liblte/phy/fec/convcoder.h" #include "parity.h" -int convcoder_encode(convcoder_t *q, char *input, char *output, int frame_length) { - unsigned int sr; - int i,j; - int len = q->tail_biting ? frame_length : (frame_length + q->K - 1); +int convcoder_encode(convcoder_t *q, char *input, char *output, uint32_t frame_length) { + uint32_t sr; + uint32_t i,j; + uint32_t len = q->tail_biting ? frame_length : (frame_length + q->K - 1); if (q->tail_biting) { sr = 0; diff --git a/lte/phy/lib/fec/src/parity.c b/lte/phy/lib/fec/src/parity.c index 568994888..b12edfaee 100644 --- a/lte/phy/lib/fec/src/parity.c +++ b/lte/phy/lib/fec/src/parity.c @@ -4,26 +4,27 @@ */ #include +#include -unsigned char Partab[256]; -int P_init; +uint8_t Partab[256]; +uint32_t P_init; /* Create 256-entry odd-parity lookup table * Needed only on non-ia32 machines */ void partab_init(void) { - int i, cnt, ti; + uint32_t i, cnt, ti; - /* Initialize parity lookup table */ - for (i = 0; i < 256; i++) { - cnt = 0; - ti = i; - while (ti) { - if (ti & 1) - cnt++; - ti >>= 1; - } - Partab[i] = cnt & 1; - } - P_init = 1; + /* Initialize parity lookup table */ + for (i = 0; i < 256; i++) { + cnt = 0; + ti = i; + while (ti) { + if (ti & 1) + cnt++; + ti >>= 1; + } + Partab[i] = cnt & 1; + } + P_init = 1; } diff --git a/lte/phy/lib/fec/src/parity.h b/lte/phy/lib/fec/src/parity.h index dfda24f57..5ad4b1b5c 100644 --- a/lte/phy/lib/fec/src/parity.h +++ b/lte/phy/lib/fec/src/parity.h @@ -10,16 +10,16 @@ /* Determine parity of argument: 1 = odd, 0 = even */ #ifdef __i386__ -static inline int parityb(unsigned char x){ +static inline uint32_t parityb(uint8_t x){ __asm__ __volatile__ ("test %1,%1;setpo %0" : "=qhm" (x) : "qh" (x)); return x; } #else void partab_init(); -static inline int parityb(unsigned char x){ - extern unsigned char Partab[256]; - extern int P_init; +static inline uint32_t parityb(uint8_t x){ + extern uint8_t Partab[256]; + extern uint32_t P_init; if(!P_init){ partab_init(); } @@ -28,7 +28,7 @@ static inline int parityb(unsigned char x){ #endif -static inline int parity(int x){ +static inline uint32_t parity(int x){ /* Fold down to one byte */ x ^= (x >> 16); x ^= (x >> 8); diff --git a/lte/phy/lib/fec/src/rm_conv.c b/lte/phy/lib/fec/src/rm_conv.c index 3b4254c5f..0c10c9a0d 100644 --- a/lte/phy/lib/fec/src/rm_conv.c +++ b/lte/phy/lib/fec/src/rm_conv.c @@ -27,25 +27,27 @@ #include #include +#include + #include "liblte/phy/fec/rm_conv.h" #define NCOLS 32 #define NROWS_MAX NCOLS -unsigned char RM_PERM_CC[NCOLS] = { 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, +uint8_t RM_PERM_CC[NCOLS] = { 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31, 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30 }; -unsigned char RM_PERM_CC_INV[NCOLS] = +uint8_t RM_PERM_CC_INV[NCOLS] = { 16, 0, 24, 8, 20, 4, 28, 12, 18, 2, 26, 10, 22, 6, 30, 14, 17, 1, 25, 9, 21, 5, 29, 13, 19, 3, 27, 11, 23, 7, 31, 15 }; -int rm_conv_tx(char *input, int in_len, char *output, int out_len) { +int rm_conv_tx(char *input, uint32_t in_len, char *output, uint32_t out_len) { char tmp[3 * NCOLS * NROWS_MAX]; int nrows, ndummy, K_p; int i, j, k, s; - nrows = (int) (in_len / 3 - 1) / NCOLS + 1; + nrows = (uint32_t) (in_len / 3 - 1) / NCOLS + 1; if (nrows > NROWS_MAX) { fprintf(stderr, "Input too large. Max input length is %d\n", 3 * NCOLS * NROWS_MAX); @@ -89,7 +91,7 @@ int rm_conv_tx(char *input, int in_len, char *output, int out_len) { /* Undoes Convolutional Code Rate Matching. * 3GPP TS 36.212 v10.1.0 section 5.1.4.2 */ -int rm_conv_rx(float *input, int in_len, float *output, int out_len) { +int rm_conv_rx(float *input, uint32_t in_len, float *output, uint32_t out_len) { int nrows, ndummy, K_p; int i, j, k; @@ -97,7 +99,7 @@ int rm_conv_rx(float *input, int in_len, float *output, int out_len) { float tmp[3 * NCOLS * NROWS_MAX]; - nrows = (int) (out_len / 3 - 1) / NCOLS + 1; + nrows = (uint32_t) (out_len / 3 - 1) / NCOLS + 1; if (nrows > NROWS_MAX) { fprintf(stderr, "Output too large. Max output length is %d\n", 3 * NCOLS * NROWS_MAX); diff --git a/lte/phy/lib/fec/src/rm_turbo.c b/lte/phy/lib/fec/src/rm_turbo.c index f678a7685..6e677b0d4 100644 --- a/lte/phy/lib/fec/src/rm_turbo.c +++ b/lte/phy/lib/fec/src/rm_turbo.c @@ -30,16 +30,17 @@ #include #include #include +#include #include "liblte/phy/fec/rm_turbo.h" #define NCOLS 32 #define NROWS_MAX NCOLS -unsigned char RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, +uint8_t RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31 }; -int rm_turbo_init(rm_turbo_t *q, int buffer_len) { +int rm_turbo_init(rm_turbo_t *q, uint32_t buffer_len) { q->buffer_len = buffer_len; q->buffer = malloc(buffer_len * sizeof(float)); if (!q->buffer) { @@ -60,15 +61,16 @@ void rm_turbo_free(rm_turbo_t *q) { * * TODO: Soft buffer size limitation according to UE category */ -int rm_turbo_tx(rm_turbo_t *q, char *input, int in_len, char *output, - int out_len, int rv_idx) { +int rm_turbo_tx(rm_turbo_t *q, char *input, uint32_t in_len, char *output, + uint32_t out_len, uint32_t rv_idx) { char *tmp = (char*) q->buffer; - int nrows, ndummy, K_p; + int ndummy, kidx; + int nrows, K_p; - int i, j, k, s, kidx, N_cb, k0; + int i, j, k, s, N_cb, k0; - nrows = (int) (in_len / 3 - 1) / NCOLS + 1; + nrows = (uint32_t) (in_len / 3 - 1) / NCOLS + 1; K_p = nrows * NCOLS; if (3 * K_p > q->buffer_len) { fprintf(stderr, @@ -113,10 +115,10 @@ int rm_turbo_tx(rm_turbo_t *q, char *input, int in_len, char *output, } /* Bit selection and transmission 5.1.4.1.2 */ - N_cb = 3 * K_p; // TODO: Soft buffer size limitation + N_cb = 3 * K_p; // TODO: Soft buffer size limitation k0 = nrows - * (2 * (int) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); + * (2 * (uint32_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); k = 0; j = 0; @@ -133,8 +135,8 @@ int rm_turbo_tx(rm_turbo_t *q, char *input, int in_len, char *output, /* Undoes Turbo Code Rate Matching. * 3GPP TS 36.212 v10.1.0 section 5.1.4.1 */ -int rm_turbo_rx(rm_turbo_t *q, float *input, int in_len, float *output, - int out_len, int rv_idx) { +int rm_turbo_rx(rm_turbo_t *q, float *input, uint32_t in_len, float *output, + uint32_t out_len, uint32_t rv_idx) { int nrows, ndummy, K_p, k0, N_cb, jp, kidx; int i, j, k; @@ -143,7 +145,7 @@ int rm_turbo_rx(rm_turbo_t *q, float *input, int in_len, float *output, float *tmp = (float*) q->buffer; - nrows = (int) (out_len / 3 - 1) / NCOLS + 1; + nrows = (uint32_t) (out_len / 3 - 1) / NCOLS + 1; K_p = nrows * NCOLS; if (3 * K_p > q->buffer_len) { fprintf(stderr, @@ -164,7 +166,7 @@ int rm_turbo_rx(rm_turbo_t *q, float *input, int in_len, float *output, /* Undo bit collection. Account for dummy bits */ N_cb = 3 * K_p; // TODO: Soft buffer size limitation k0 = nrows - * (2 * (int) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); + * (2 * (uint32_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); k = 0; j = 0; @@ -185,7 +187,7 @@ int rm_turbo_rx(rm_turbo_t *q, float *input, int in_len, float *output, isdummy = true; } } else { - int jpp = (jp - K_p - 1) / 2; + uint32_t jpp = (jp - K_p - 1) / 2; kidx = (RM_PERM_TC[jpp / nrows] + NCOLS * (jpp % nrows) + 1) % K_p; if ((kidx - ndummy) < 0) { isdummy = true; diff --git a/lte/phy/lib/fec/src/tc_interl_lte.c b/lte/phy/lib/fec/src/tc_interl_lte.c index 227d4d9f9..b77c04779 100644 --- a/lte/phy/lib/fec/src/tc_interl_lte.c +++ b/lte/phy/lib/fec/src/tc_interl_lte.c @@ -27,6 +27,7 @@ #include #include +#include #include "liblte/phy/common/phy_common.h" #include "liblte/phy/fec/tc_interl.h" @@ -39,7 +40,7 @@ * ************************************************/ -const int f1_list[NOF_TC_CB_SIZES] = { 3, 7, 19, 7, 7, 11, 5, 11, 7, 41, 103, +const uint32_t f1_list[NOF_TC_CB_SIZES] = { 3, 7, 19, 7, 7, 11, 5, 11, 7, 41, 103, 15, 9, 17, 9, 21, 101, 21, 57, 23, 13, 27, 11, 27, 85, 29, 33, 15, 17, 33, 103, 19, 19, 37, 19, 21, 21, 115, 193, 21, 133, 81, 45, 23, 243, 151, 155, 25, 51, 47, 91, 29, 29, 247, 29, 89, 91, 157, 55, 31, 17, 35, 227, 65, 19, @@ -52,7 +53,7 @@ const int f1_list[NOF_TC_CB_SIZES] = { 3, 7, 19, 7, 7, 11, 5, 11, 7, 41, 103, 39, 127, 39, 39, 31, 113, 41, 251, 43, 21, 43, 45, 45, 161, 89, 323, 47, 23, 47, 263 }; -const int f2_list[NOF_TC_CB_SIZES] = { 10, 12, 42, 16, 18, 20, 22, 24, 26, 84, +const uint32_t f2_list[NOF_TC_CB_SIZES] = { 10, 12, 42, 16, 18, 20, 22, 24, 26, 84, 90, 32, 34, 108, 38, 120, 84, 44, 46, 48, 50, 52, 36, 56, 58, 60, 62, 32, 198, 68, 210, 36, 74, 76, 78, 120, 82, 84, 86, 44, 90, 46, 94, 48, 98, 40, 102, 52, 106, 72, 110, 168, 114, 58, 118, 180, 122, 62, 84, 64, 66, 68, 420, @@ -65,9 +66,9 @@ const int f2_list[NOF_TC_CB_SIZES] = { 10, 12, 42, 16, 18, 20, 22, 24, 26, 84, 280, 142, 480, 146, 444, 120, 152, 462, 234, 158, 80, 96, 902, 166, 336, 170, 86, 174, 176, 178, 120, 182, 184, 186, 94, 190, 480 }; -int tc_interl_LTE_gen(tc_interl_t *h, int long_cb) { - int cb_table_idx, f1, f2; - unsigned long long i, j; +int tc_interl_LTE_gen(tc_interl_t *h, uint32_t long_cb) { + uint32_t cb_table_idx, f1, f2; + uint64_t i, j; if (long_cb > h->max_long_cb) { fprintf(stderr, "Interleaver initiated for max_long_cb=%d\n", @@ -90,8 +91,8 @@ int tc_interl_LTE_gen(tc_interl_t *h, int long_cb) { h->reverse[0] = 0; for (i = 1; i < long_cb; i++) { j = (f1 * i + f2 * i * i) % (long_cb); - h->forward[i] = j; - h->reverse[j] = i; + h->forward[i] = (uint32_t) j; + h->reverse[j] = (uint32_t) i; } return 0; diff --git a/lte/phy/lib/fec/src/tc_interl_umts.c b/lte/phy/lib/fec/src/tc_interl_umts.c index 5c2e3213d..931749347 100644 --- a/lte/phy/lib/fec/src/tc_interl_umts.c +++ b/lte/phy/lib/fec/src/tc_interl_umts.c @@ -28,13 +28,14 @@ #include #include #include +#include #include "liblte/phy/fec/tc_interl.h" #include "liblte/phy/fec/turbocoder.h" #define TURBO_RATE 3 -int mcd(int x, int y); +uint32_t mcd(uint32_t x, uint32_t y); /************************************************ * @@ -53,14 +54,14 @@ const unsigned char table_v[52] = { 3, 2, 2, 3, 2, 5, 2, 3, 2, 6, 3, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5, 2, 5, 2, 6, 3, 3, 2, 3, 2, 2, 6, 5, 2, 5, 2, 2, 2, 19, 5, 2, 3, 2, 3, 2, 6, 3, 7, 7, 6, 3 }; -int tc_interl_init(tc_interl_t *h, int max_long_cb) { +int tc_interl_init(tc_interl_t *h, uint32_t max_long_cb) { int ret = -1; - h->forward = malloc(sizeof(int) * max_long_cb); + h->forward = malloc(sizeof(uint32_t) * max_long_cb); if (!h->forward) { perror("malloc"); goto clean_exit; } - h->reverse = malloc(sizeof(int) * max_long_cb); + h->reverse = malloc(sizeof(uint32_t) * max_long_cb); if (!h->reverse) { perror("malloc"); goto clean_exit; @@ -83,17 +84,17 @@ void tc_interl_free(tc_interl_t *h) { bzero(h, sizeof(tc_interl_t)); } -int tc_interl_UMTS_gen(tc_interl_t *h, int long_cb) { +int tc_interl_UMTS_gen(tc_interl_t *h, uint32_t long_cb) { - int i, j; - int res, prim, aux; - int kp, k; - int *per, *desper; - unsigned char v; - unsigned short p; - unsigned short s[MAX_COLS], q[MAX_ROWS], r[MAX_ROWS], T[MAX_ROWS]; - unsigned short U[MAX_COLS * MAX_ROWS]; - int M_Rows, M_Cols, M_long; + uint32_t i, j; + uint32_t res, prim, aux; + uint32_t kp, k; + uint32_t *per, *desper; + uint8_t v; + uint16_t p; + uint16_t s[MAX_COLS], q[MAX_ROWS], r[MAX_ROWS], T[MAX_ROWS]; + uint16_t U[MAX_COLS * MAX_ROWS]; + uint32_t M_Rows, M_Cols, M_long; M_long = long_cb; @@ -260,8 +261,8 @@ int tc_interl_UMTS_gen(tc_interl_t *h, int long_cb) { } -int mcd(int x, int y) { - int r = 1; +uint32_t mcd(uint32_t x, uint32_t y) { + uint32_t r = 1; while (r) { r = x % y; diff --git a/lte/phy/lib/fec/src/turbocoder.c b/lte/phy/lib/fec/src/turbocoder.c index 75aebb6e9..7483601d9 100644 --- a/lte/phy/lib/fec/src/turbocoder.c +++ b/lte/phy/lib/fec/src/turbocoder.c @@ -26,12 +26,14 @@ */ -#include "liblte/phy/fec/turbocoder.h" #include +#include + +#include "liblte/phy/fec/turbocoder.h" #define NOF_REGS 3 -int tcod_init(tcod_t *h, int max_long_cb) { +int tcod_init(tcod_t *h, uint32_t max_long_cb) { if (tc_interl_init(&h->interl, max_long_cb)) { return -1; @@ -45,13 +47,13 @@ void tcod_free(tcod_t *h) { h->max_long_cb = 0; } -int tcod_encode(tcod_t *h, char *input, char *output, int long_cb) { +int tcod_encode(tcod_t *h, char *input, char *output, uint32_t long_cb) { char reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; - int i, k = 0, j; + uint32_t i, k = 0, j; char bit; char in, out; - int *per; + uint32_t *per; if (long_cb > h->max_long_cb) { fprintf(stderr, "Turbo coder initiated for max_long_cb=%d\n", diff --git a/lte/phy/lib/fec/src/turbodecoder.c b/lte/phy/lib/fec/src/turbodecoder.c index 2fbb61787..250b078fd 100644 --- a/lte/phy/lib/fec/src/turbodecoder.c +++ b/lte/phy/lib/fec/src/turbodecoder.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -38,13 +39,13 @@ * Decoder * ************************************************/ -void map_gen_beta(map_gen_t *s, llr_t *input, llr_t *parity, int long_cb) { +void map_gen_beta(map_gen_t *s, llr_t *input, llr_t *parity, uint32_t long_cb) { llr_t m_b[8], new[8], old[8]; llr_t x, y, xy; int k; - int end = long_cb + RATE; + uint32_t end = long_cb + RATE; llr_t *beta = s->beta; - int i; + uint32_t i; for (i = 0; i < 8; i++) { old[i] = beta[8 * (end) + i]; @@ -84,15 +85,15 @@ void map_gen_beta(map_gen_t *s, llr_t *input, llr_t *parity, int long_cb) { } void map_gen_alpha(map_gen_t *s, llr_t *input, llr_t *parity, llr_t *output, - int long_cb) { + uint32_t long_cb) { llr_t m_b[8], new[8], old[8], max1[8], max0[8]; llr_t m1, m0; llr_t x, y, xy; llr_t out; - int k; - int end = long_cb; + uint32_t k; + uint32_t end = long_cb; llr_t *beta = s->beta; - int i; + uint32_t i; old[0] = 0; for (i = 1; i < 8; i++) { @@ -168,8 +169,8 @@ void map_gen_free(map_gen_t *h) { } void map_gen_dec(map_gen_t *h, llr_t *input, llr_t *parity, llr_t *output, - int long_cb) { - int k; + uint32_t long_cb) { + uint32_t k; h->beta[(long_cb + TAIL) * NUMSTATES] = 0; for (k = 1; k < NUMSTATES; k++) @@ -184,10 +185,10 @@ void map_gen_dec(map_gen_t *h, llr_t *input, llr_t *parity, llr_t *output, * TURBO DECODER INTERFACE * ************************************************/ -int tdec_init(tdec_t *h, int max_long_cb) { +int tdec_init(tdec_t *h, uint32_t max_long_cb) { int ret = -1; bzero(h, sizeof(tdec_t)); - int len = max_long_cb + TOTALTAIL; + uint32_t len = max_long_cb + TOTALTAIL; h->max_long_cb = max_long_cb; @@ -256,8 +257,8 @@ void tdec_free(tdec_t *h) { bzero(h, sizeof(tdec_t)); } -void tdec_iteration(tdec_t *h, llr_t *input, int long_cb) { - int i; +void tdec_iteration(tdec_t *h, llr_t *input, uint32_t long_cb) { + uint32_t i; // Prepare systematic and parity bits for MAP DEC #1 for (i = 0; i < long_cb; i++) { @@ -295,7 +296,7 @@ void tdec_iteration(tdec_t *h, llr_t *input, int long_cb) { } -int tdec_reset(tdec_t *h, int long_cb) { +int tdec_reset(tdec_t *h, uint32_t long_cb) { memset(h->w, 0, sizeof(llr_t) * long_cb); if (long_cb > h->max_long_cb) { fprintf(stderr, "TDEC was initialized for max_long_cb=%d\n", @@ -305,16 +306,16 @@ int tdec_reset(tdec_t *h, int long_cb) { return tc_interl_LTE_gen(&h->interleaver, long_cb); } -void tdec_decision(tdec_t *h, char *output, int long_cb) { - int i; +void tdec_decision(tdec_t *h, char *output, uint32_t long_cb) { + uint32_t i; for (i = 0; i < long_cb; i++) { output[i] = (h->llr2[h->interleaver.reverse[i]] > 0) ? 1 : 0; } } -void tdec_run_all(tdec_t *h, llr_t *input, char *output, int nof_iterations, - int long_cb) { - int iter = 0; +void tdec_run_all(tdec_t *h, llr_t *input, char *output, uint32_t nof_iterations, + uint32_t long_cb) { + uint32_t iter = 0; tdec_reset(h, long_cb); diff --git a/lte/phy/lib/fec/src/viterbi.c b/lte/phy/lib/fec/src/viterbi.c index aa17e176a..b9fb2b0ec 100644 --- a/lte/phy/lib/fec/src/viterbi.c +++ b/lte/phy/lib/fec/src/viterbi.c @@ -27,6 +27,8 @@ #include #include +#include + #include #include @@ -38,11 +40,11 @@ #define DEB 0 -int decode37(void *o, unsigned char *symbols, char *data, int frame_length) { +int decode37(void *o, uint8_t *symbols, char *data, uint32_t frame_length) { viterbi_t *q = o; - int i; + uint32_t i; - int best_state; + uint32_t best_state; if (frame_length > q->framebits) { fprintf(stderr, "Initialized decoder for max frame length %d bits\n", @@ -73,7 +75,7 @@ int decode37(void *o, unsigned char *symbols, char *data, int frame_length) { return q->framebits; } -int decode39(void *o, unsigned char *symbols, char *data, int frame_length) { +int decode39(void *o, uint8_t *symbols, char *data, uint32_t frame_length) { viterbi_t *q = o; if (frame_length > q->framebits) { @@ -113,7 +115,7 @@ void free39(void *o) { delete_viterbi39_port(q->ptr); } -int init37(viterbi_t *q, int poly[3], int framebits, bool tail_biting) { +int init37(viterbi_t *q, uint32_t poly[3], uint32_t framebits, bool tail_biting) { q->K = 7; q->R = 3; q->framebits = framebits; @@ -145,7 +147,7 @@ int init37(viterbi_t *q, int poly[3], int framebits, bool tail_biting) { } } -int init39(viterbi_t *q, int poly[3], int framebits, bool tail_biting) { +int init39(viterbi_t *q, uint32_t poly[3], uint32_t framebits, bool tail_biting) { q->K = 9; q->R = 3; q->framebits = framebits; @@ -171,8 +173,8 @@ int init39(viterbi_t *q, int poly[3], int framebits, bool tail_biting) { } } -int viterbi_init(viterbi_t *q, viterbi_type_t type, int poly[3], - int max_frame_length, bool tail_bitting) { +int viterbi_init(viterbi_t *q, viterbi_type_t type, uint32_t poly[3], + uint32_t max_frame_length, bool tail_bitting) { switch (type) { case viterbi_37: return init37(q, poly, max_frame_length, tail_bitting); @@ -191,8 +193,8 @@ void viterbi_free(viterbi_t *q) { } /* symbols are real-valued */ -int viterbi_decode_f(viterbi_t *q, float *symbols, char *data, int frame_length) { - int len; +int viterbi_decode_f(viterbi_t *q, float *symbols, char *data, uint32_t frame_length) { + uint32_t len; if (frame_length > q->framebits) { fprintf(stderr, "Initialized decoder for max frame length %d bits\n", q->framebits); @@ -207,13 +209,13 @@ int viterbi_decode_f(viterbi_t *q, float *symbols, char *data, int frame_length) return q->decode(q, q->symbols_uc, data, frame_length); } -int viterbi_decode_uc(viterbi_t *q, unsigned char *symbols, char *data, - int frame_length) { +int viterbi_decode_uc(viterbi_t *q, uint8_t *symbols, char *data, + uint32_t frame_length) { return q->decode(q, symbols, data, frame_length); } int viterbi_initialize(viterbi_hl* h) { - int poly[3]; + uint32_t poly[3]; viterbi_type_t type; if (h->init.rate == 2) { if (h->init.constraint_length == 7) { @@ -243,7 +245,7 @@ int viterbi_initialize(viterbi_hl* h) { poly[0] = h->init.generator_0; poly[1] = h->init.generator_1; poly[2] = h->init.generator_2; - return viterbi_init(&h->obj, type, poly, h->init.frame_length, + return viterbi_init(&h->obj, type, poly, (uint32_t) h->init.frame_length, h->init.tail_bitting ? true : false); } diff --git a/lte/phy/lib/fec/src/viterbi37.h b/lte/phy/lib/fec/src/viterbi37.h index 6afc563e8..7bacca2c8 100644 --- a/lte/phy/lib/fec/src/viterbi37.h +++ b/lte/phy/lib/fec/src/viterbi37.h @@ -27,8 +27,20 @@ #include -void *create_viterbi37_port(int polys[3], int len); -int init_viterbi37_port(void *p, int starting_state); -int chainback_viterbi37_port(void *p, char *data, unsigned int nbits, unsigned int endstate); +void *create_viterbi37_port(uint32_t polys[3], + uint32_t len); + +int init_viterbi37_port(void *p, + uint32_t starting_state); + +int chainback_viterbi37_port(void *p, + char *data, + uint32_t nbits, + uint32_t endstate); + void delete_viterbi37_port(void *p); -int update_viterbi37_blk_port(void *p, unsigned char *syms, int nbits, int *best_state); + +int update_viterbi37_blk_port(void *p, + unsigned char *syms, + uint32_t nbits, + uint32_t *best_state); diff --git a/lte/phy/lib/fec/src/viterbi37_port.c b/lte/phy/lib/fec/src/viterbi37_port.c index 7eb311324..09dfa4bdc 100644 --- a/lte/phy/lib/fec/src/viterbi37_port.c +++ b/lte/phy/lib/fec/src/viterbi37_port.c @@ -4,6 +4,8 @@ */ #include #include +#include + #include #include "viterbi37.h" #include "parity.h" @@ -30,9 +32,9 @@ struct v37 { }; /* Initialize Viterbi decoder for start of new frame */ -int init_viterbi37_port(void *p, int starting_state) { +int init_viterbi37_port(void *p, uint32_t starting_state) { struct v37 *vp = p; - int i; + uint32_t i; if (p == NULL) return -1; @@ -48,8 +50,8 @@ int init_viterbi37_port(void *p, int starting_state) { return 0; } -void set_viterbi37_polynomial_port(int polys[3]) { - int state; +void set_viterbi37_polynomial_port(uint32_t polys[3]) { + uint32_t state; for (state = 0; state < 32; state++) { Branchtab37[0].c[state] = @@ -62,7 +64,7 @@ void set_viterbi37_polynomial_port(int polys[3]) { } /* Create a new instance of a Viterbi decoder */ -void *create_viterbi37_port(int polys[3], int len) { +void *create_viterbi37_port(uint32_t polys[3], uint32_t len) { struct v37 *vp; set_viterbi37_polynomial_port(polys); @@ -82,8 +84,8 @@ void *create_viterbi37_port(int polys[3], int len) { /* Viterbi chainback */ int chainback_viterbi37_port(void *p, char *data, /* Decoded output data */ - unsigned int nbits, /* Number of data bits */ - unsigned int endstate) { /* Terminal encoder state */ + uint32_t nbits, /* Number of data bits */ + uint32_t endstate) { /* Terminal encoder state */ struct v37 *vp = p; decision_t *d; @@ -145,18 +147,18 @@ unsigned int metric,m0,m1,decision;\ * of symbols! */ -int update_viterbi37_blk_port(void *p, unsigned char *syms, int nbits, int *best_state) { +int update_viterbi37_blk_port(void *p, uint8_t *syms, uint32_t nbits, uint32_t *best_state) { struct v37 *vp = p; decision_t *d; if (p == NULL) return -1; - int k=0; + uint32_t k=0; d = (decision_t *) vp->dp; while (nbits--) { void *tmp; - unsigned char sym0, sym1, sym2; - int i; + uint8_t sym0, sym1, sym2; + uint32_t i; d->w[0] = d->w[1] = 0; @@ -174,8 +176,8 @@ int update_viterbi37_blk_port(void *p, unsigned char *syms, int nbits, int *best vp->new_metrics = tmp; } if (best_state) { - int i, bst=0; - unsigned int minmetric=UINT_MAX; + uint32_t i, bst=0; + uint32_t minmetric=UINT_MAX; for (i=0;i<64;i++) { if (vp->old_metrics->w[i] < minmetric) { bst = i; diff --git a/lte/phy/lib/fec/src/viterbi39.h b/lte/phy/lib/fec/src/viterbi39.h index a5830d145..09a3280cf 100644 --- a/lte/phy/lib/fec/src/viterbi39.h +++ b/lte/phy/lib/fec/src/viterbi39.h @@ -27,10 +27,19 @@ #include -void *create_viterbi39_port(int polys[3], int len); -int init_viterbi39_port(void *p, int starting_state); -int chainback_viterbi39_port(void *p, char *data, /* Decoded output data */ - unsigned int nbits, /* Number of data bits */ - unsigned int endstate); +void *create_viterbi39_port(uint32_t polys[3], + uint32_t len); + +int init_viterbi39_port(void *p, + uint32_t starting_state); + +int chainback_viterbi39_port(void *p, + char *data, /* Decoded output data */ + uint32_t nbits, /* Number of data bits */ + uint32_t endstate); + void delete_viterbi39_port(void *p); -int update_viterbi39_blk_port(void *p, unsigned char *syms, int nbits); + +int update_viterbi39_blk_port(void *p, + uint8_t *syms, + uint32_t nbits); diff --git a/lte/phy/lib/fec/src/viterbi39_port.c b/lte/phy/lib/fec/src/viterbi39_port.c index fe57297c7..1d87b2c4a 100644 --- a/lte/phy/lib/fec/src/viterbi39_port.c +++ b/lte/phy/lib/fec/src/viterbi39_port.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include "viterbi39.h" #include "parity.h" @@ -29,9 +30,9 @@ struct v39 { }; /* Initialize Viterbi decoder for start of new frame */ -int init_viterbi39_port(void *p, int starting_state) { +int init_viterbi39_port(void *p, uint32_t starting_state) { struct v39 *vp = p; - int i; + uint32_t i; if (p == NULL) return -1; @@ -45,8 +46,8 @@ int init_viterbi39_port(void *p, int starting_state) { return 0; } -void set_viterbi39_polynomial_port(int polys[3]) { - int state; +void set_viterbi39_polynomial_port(uint32_t polys[3]) { + uint32_t state; for (state = 0; state < 128; state++) { Branchtab39[0].c[state] = @@ -59,7 +60,7 @@ void set_viterbi39_polynomial_port(int polys[3]) { } /* Create a new instance of a Viterbi decoder */ -void *create_viterbi39_port(int polys[3], int len) { +void *create_viterbi39_port(uint32_t polys[3], uint32_t len) { struct v39 *vp; set_viterbi39_polynomial_port(polys); @@ -79,8 +80,8 @@ void *create_viterbi39_port(int polys[3], int len) { /* Viterbi chainback */ int chainback_viterbi39_port(void *p, char *data, /* Decoded output data */ - unsigned int nbits, /* Number of data bits */ - unsigned int endstate) { /* Terminal encoder state */ + uint32_t nbits, /* Number of data bits */ + uint32_t endstate) { /* Terminal encoder state */ struct v39 *vp = p; decision_t *d; @@ -140,7 +141,7 @@ unsigned int metric,m0,m1,decision;\ * of symbols! */ -int update_viterbi39_blk_port(void *p, unsigned char *syms, int nbits) { +int update_viterbi39_blk_port(void *p, uint8_t *syms, uint32_t nbits) { struct v39 *vp = p; decision_t *d; @@ -150,8 +151,8 @@ int update_viterbi39_blk_port(void *p, unsigned char *syms, int nbits) { d = (decision_t *) vp->dp; while (nbits--) { void *tmp; - unsigned char sym0, sym1, sym2; - int i; + uint8_t sym0, sym1, sym2; + uint32_t i; for (i = 0; i < 8; i++) d->w[i] = 0; diff --git a/lte/phy/lib/fec/test/turbocoder_test.c b/lte/phy/lib/fec/test/turbocoder_test.c index a222b9750..fb0fabc85 100644 --- a/lte/phy/lib/fec/test/turbocoder_test.c +++ b/lte/phy/lib/fec/test/turbocoder_test.c @@ -41,9 +41,9 @@ typedef _Complex float cf_t; -int frame_length = 1000, nof_frames = 100; +uint32_t frame_length = 1000, nof_frames = 100; float ebno_db = 100.0; -unsigned int seed = 0; +uint32_t seed = 0; int K = -1; #define MAX_ITERATIONS 4 @@ -51,9 +51,9 @@ int nof_iterations = MAX_ITERATIONS; int test_known_data = 0; int test_errors = 0; -#define SNR_POINTS 8 -#define SNR_MIN 0.0 -#define SNR_MAX 4.0 +#define SNR_POINTS 8 +#define SNR_MIN 0.0 +#define SNR_MAX 4.0 void usage(char *prog) { printf("Usage: %s [nlesv]\n", prog); @@ -127,16 +127,16 @@ void output_matlab(float ber[MAX_ITERATIONS][SNR_POINTS], int snr_points) { } int main(int argc, char **argv) { - int frame_cnt; + uint32_t frame_cnt; float *llr; unsigned char *llr_c; char *data_tx, *data_rx, *symbols; - int i, j; + uint32_t i, j; float var[SNR_POINTS]; - int snr_points; + uint32_t snr_points; float ber[MAX_ITERATIONS][SNR_POINTS]; - unsigned int errors[100]; - int coded_length; + uint32_t errors[100]; + uint32_t coded_length; struct timeval tdata[3]; float mean_usec; tdec_t tdec; @@ -247,7 +247,7 @@ int main(int argc, char **argv) { /* decoder */ tdec_reset(&tdec, frame_length); - int t; + uint32_t t; if (nof_iterations == -1) { t = MAX_ITERATIONS; } else { diff --git a/lte/phy/lib/phch/src/dci.c b/lte/phy/lib/phch/src/dci.c index 0e38b0ffd..05e0fc35b 100644 --- a/lte/phy/lib/phch/src/dci.c +++ b/lte/phy/lib/phch/src/dci.c @@ -40,42 +40,20 @@ #include "liblte/phy/utils/vector.h" #include "liblte/phy/utils/debug.h" -int dci_init(dci_t *q, uint32_t max_dcis) { - q->msg = calloc(sizeof(dci_msg_t), max_dcis); - if (!q->msg) { - perror("malloc"); - return LIBLTE_ERROR; - } - q->nof_dcis = 0; - q->max_dcis = max_dcis; - return LIBLTE_SUCCESS; -} - -void dci_free(dci_t *q) { - if (q->msg) { - free(q->msg); - } -} - -void dci_candidate_fprint(FILE *f, dci_candidate_t *q) { - fprintf(f, "L: %d, nCCE: %d, RNTI: 0x%x, nBits: %d\n", q->L, q->ncce, q->rnti, - q->nof_bits); -} -int dci_msg_candidate_set(dci_msg_t *msg, uint32_t L, uint32_t nCCE, uint16_t rnti) { - if (L >= 0 && L <= 3) { - msg->location.L = L; +int dci_location_set(dci_location_t *c, uint32_t L, uint32_t nCCE) { + if (L <= 3) { + c->L = L; } else { fprintf(stderr, "Invalid L %d\n", L); return LIBLTE_ERROR; } - if (nCCE >= 0 && nCCE <= 87) { - msg->location.ncce = nCCE; + if (nCCE <= 87) { + c->ncce = nCCE; } else { fprintf(stderr, "Invalid nCCE %d\n", nCCE); return LIBLTE_ERROR; } - msg->location.rnti = rnti; return LIBLTE_SUCCESS; } @@ -245,7 +223,7 @@ int dci_format0_pack(ra_pusch_t *data, dci_msg_t *msg, uint32_t nof_prb) { while (y - msg->data < n) { *y++ = 0; } - msg->location.nof_bits = (y - msg->data); + msg->nof_bits = (y - msg->data); return LIBLTE_SUCCESS; } /* Unpacks DCI format 0 data and store result in msg according @@ -260,7 +238,7 @@ int dci_format0_unpack(dci_msg_t *msg, ra_pusch_t *data, uint32_t nof_prb) { uint32_t n_ul_hop; /* Make sure it's a Format0 message */ - if (msg->location.nof_bits != dci_format_sizeof(Format0, nof_prb)) { + if (msg->nof_bits != dci_format_sizeof(Format0, nof_prb)) { fprintf(stderr, "Invalid message length for format 0\n"); return LIBLTE_ERROR; } @@ -385,7 +363,7 @@ int dci_format1_pack(ra_pdsch_t *data, dci_msg_t *msg, uint32_t nof_prb) { while (y - msg->data < n) { *y++ = 0; } - msg->location.nof_bits = (y - msg->data); + msg->nof_bits = (y - msg->data); return LIBLTE_SUCCESS; } @@ -396,7 +374,7 @@ int dci_format1_unpack(dci_msg_t *msg, ra_pdsch_t *data, uint32_t nof_prb) { char *y = msg->data; /* Make sure it's a Format1 message */ - if (msg->location.nof_bits != dci_format_sizeof(Format1, nof_prb)) { + if (msg->nof_bits != dci_format_sizeof(Format1, nof_prb)) { fprintf(stderr, "Invalid message length for format 1\n"); return LIBLTE_ERROR; } @@ -551,7 +529,7 @@ int dci_format1As_pack(ra_pdsch_t *data, dci_msg_t *msg, uint32_t nof_prb, while (y - msg->data < n) { *y++ = 0; } - msg->location.nof_bits = (y - msg->data); + msg->nof_bits = (y - msg->data); return LIBLTE_SUCCESS; } @@ -566,7 +544,7 @@ int dci_format1As_unpack(dci_msg_t *msg, ra_pdsch_t *data, uint32_t nof_prb, char *y = msg->data; /* Make sure it's a Format0 message */ - if (msg->location.nof_bits != dci_format_sizeof(Format1A, nof_prb)) { + if (msg->nof_bits != dci_format_sizeof(Format1A, nof_prb)) { fprintf(stderr, "Invalid message length for format 1A\n"); return LIBLTE_ERROR; } @@ -692,7 +670,7 @@ int dci_format1Cs_pack(ra_pdsch_t *data, dci_msg_t *msg, uint32_t nof_prb) { } bit_pack((uint32_t) mcs, &y, 5); - msg->location.nof_bits = (y - msg->data); + msg->nof_bits = (y - msg->data); return LIBLTE_SUCCESS; } @@ -703,7 +681,7 @@ int dci_format1Cs_unpack(dci_msg_t *msg, ra_pdsch_t *data, uint32_t nof_prb) { /* pack bits */ char *y = msg->data; - if (msg->location.nof_bits != dci_format_sizeof(Format1C, nof_prb)) { + if (msg->nof_bits != dci_format_sizeof(Format1C, nof_prb)) { fprintf(stderr, "Invalid message length for format 1C\n"); return LIBLTE_ERROR; } @@ -728,7 +706,7 @@ int dci_format1Cs_unpack(dci_msg_t *msg, ra_pdsch_t *data, uint32_t nof_prb) { data->mcs.tbs = ra_tbs_from_idx_format1c(data->mcs.tbs_idx); data->mcs.mod = QPSK; - msg->location.nof_bits = (y - msg->data); + msg->nof_bits = (y - msg->data); return LIBLTE_SUCCESS; } @@ -751,11 +729,11 @@ int dci_msg_pack_pdsch(ra_pdsch_t *data, dci_msg_t *msg, dci_format_t format, int dci_msg_unpack_pdsch(dci_msg_t *msg, ra_pdsch_t *data, uint32_t nof_prb, bool crc_is_crnti) { - if (msg->location.nof_bits == dci_format_sizeof(Format1, nof_prb)) { + if (msg->nof_bits == dci_format_sizeof(Format1, nof_prb)) { return dci_format1_unpack(msg, data, nof_prb); - } else if (msg->location.nof_bits == dci_format_sizeof(Format1A, nof_prb)) { + } else if (msg->nof_bits == dci_format_sizeof(Format1A, nof_prb)) { return dci_format1As_unpack(msg, data, nof_prb, crc_is_crnti); - } else if (msg->location.nof_bits == dci_format_sizeof(Format1C, nof_prb)) { + } else if (msg->nof_bits == dci_format_sizeof(Format1C, nof_prb)) { return dci_format1Cs_unpack(msg, data, nof_prb); } else { return LIBLTE_ERROR; @@ -807,18 +785,18 @@ void dci_msg_type_fprint(FILE *f, dci_msg_type_t type) { } int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, - uint16_t crnti) { - if (msg->location.nof_bits == dci_format_sizeof(Format0, nof_prb) + uint16_t msg_rnti, uint16_t crnti) { + if (msg->nof_bits == dci_format_sizeof(Format0, nof_prb) && !msg->data[0]) { type->type = PUSCH_SCHED; type->format = Format0; return LIBLTE_SUCCESS; - } else if (msg->location.nof_bits == dci_format_sizeof(Format1, nof_prb)) { + } else if (msg->nof_bits == dci_format_sizeof(Format1, nof_prb)) { type->type = PDSCH_SCHED; // only these 2 types supported type->format = Format1; return LIBLTE_SUCCESS; - } else if (msg->location.nof_bits == dci_format_sizeof(Format1A, nof_prb)) { - if (msg->location.rnti == crnti) { + } else if (msg->nof_bits == dci_format_sizeof(Format1A, nof_prb)) { + if (msg_rnti == crnti) { type->type = RA_PROC_PDCCH; type->format = Format1A; } else { @@ -826,8 +804,8 @@ int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, type->format = Format1A; } return LIBLTE_SUCCESS; - } else if (msg->location.nof_bits == dci_format_sizeof(Format1C, nof_prb)) { - if (msg->location.rnti == MRNTI) { + } else if (msg->nof_bits == dci_format_sizeof(Format1C, nof_prb)) { + if (msg_rnti == MRNTI) { type->type = MCCH_CHANGE; type->format = Format1C; } else { diff --git a/lte/phy/lib/phch/src/pbch.c b/lte/phy/lib/phch/src/pbch.c index dce32ad12..05d8e8cf5 100644 --- a/lte/phy/lib/phch/src/pbch.c +++ b/lte/phy/lib/phch/src/pbch.c @@ -144,7 +144,7 @@ int pbch_init(pbch_t *q, lte_cell_t cell) { goto clean; } - int poly[3] = { 0x6D, 0x4F, 0x57 }; + uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; if (viterbi_init(&q->decoder, viterbi_37, poly, 40, true)) { goto clean; } diff --git a/lte/phy/lib/phch/src/pdcch.c b/lte/phy/lib/phch/src/pdcch.c index 95f9ad6df..0c719671b 100644 --- a/lte/phy/lib/phch/src/pdcch.c +++ b/lte/phy/lib/phch/src/pdcch.c @@ -46,173 +46,11 @@ #define PDCCH_FORMAT_NOF_REGS(i) ((1<b)?b:a) -void set_cfi(pdcch_t *q, uint32_t cfi); - -/** - * 36.213 9.1 - */ -int gen_common_search(dci_candidate_t *c, uint32_t nof_cce, uint32_t nof_bits, - uint16_t rnti) { - int i, l, L, k; - k = 0; - for (l = 3; l > 1; l--) { - L = (1 << l); - for (i = 0; i < MIN(nof_cce,16) / (L); i++) { - c[k].L = l; - c[k].nof_bits = nof_bits; - c[k].rnti = rnti; - c[k].ncce = (L) * (i % (nof_cce / (L))); - INFO("Common SS Candidate %d: RNTI: 0x%x, nCCE: %d, Nbits: %d, L: %d\n", - k, c[k].rnti, c[k].ncce, c[k].nof_bits, c[k].L); - k++; - } - } - return k; -} - -/** - * 36.213 9.1 - */ -int gen_ue_search(dci_candidate_t *c, uint32_t nof_cce, uint32_t nof_bits, - uint16_t rnti, uint32_t subframe) { - int i, l, L, k, m; - unsigned int Yk; - const int S[4] = { 6, 12, 8, 16 }; - k = 0; - - if (VERBOSE_ISDEBUG()) { - printf("NofBits=%d, RNTI: 0x%x, SF=%d (n, L): ", nof_bits, rnti, subframe); - } - for (l = 3; l >= 0; l--) { - L = (1 << l); - for (i = 0; i < MIN(nof_cce / L, 16 / S[l]); i++) { - c[k].L = l; - c[k].nof_bits = nof_bits; - c[k].rnti = rnti; - Yk = rnti; - for (m = 0; m < subframe; m++) { - Yk = (39827 * Yk) % 65537; - } - c[k].ncce = L * ((Yk + i) % (nof_cce / L)); - if (VERBOSE_ISDEBUG()) { - printf("(%d, %d), ", c[k].ncce, c[k].L); - } - if (c[k].ncce + PDCCH_FORMAT_NOF_CCE(c[k].L) > nof_cce || - nof_bits > DCI_MAX_BITS) { - fprintf(stderr, "Illegal DCI message\n"); - return LIBLTE_ERROR; - } - k++; - } - } - if (VERBOSE_ISDEBUG()) { - printf("\n"); - } - return k; -} - - -/** 36.213 v9.3 Table 7.1-5 - * user-specific search space. Currently supported transmission Mode 1: - * DCI Format 1A and 1 + PUSCH scheduling format 0 - */ -int pdcch_init_search_ue(pdcch_t *q, uint16_t c_rnti, uint32_t cfi) { - int k, i, r; - uint32_t n; - - set_cfi(q, cfi); - - pdcch_search_t *s = &q->search_mode[SEARCH_UE]; - for (n = 0; n < NSUBFRAMES_X_FRAME; n++) { - dci_candidate_t *c = s->candidates[n]; - - if (!n) s->nof_candidates = 0; - - // Expect Formats 1, 1A, 0 - k = 0; - for (i = 0; i < NOF_UE_FORMATS && k < MAX_CANDIDATES; i++) { - r = gen_ue_search(&c[k], q->nof_cce, - dci_format_sizeof(ue_formats[i], q->cell.nof_prb), c_rnti, n); - if (r < 0) { - fprintf(stderr, "Error generating UE-specific search space\n"); - return r; - } - k += r; - } - s->nof_candidates = k; - } - INFO("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x\n", - s->nof_candidates, c_rnti); - q->current_search_mode = SEARCH_UE; - - return LIBLTE_SUCCESS; -} - - -int pdcch_init_common(pdcch_t *q, pdcch_search_t *s, uint16_t rnti) { - int k, r, i; - dci_candidate_t *c = s->candidates[0]; - s->nof_candidates = 0; - // Format 1A and 1C L=4 and L=8, 4 and 2 candidates, only if nof_cce > 16 - k = 0; - for (i = 0; i < NOF_COMMON_FORMATS && k < MAX_CANDIDATES; i++) { - r = gen_common_search(&c[k], q->nof_cce, - dci_format_sizeof(common_formats[i], q->cell.nof_prb), SIRNTI); - if (r < 0) { - return r; - } - k += r; - } - s->nof_candidates=k; - INFO("Initiated %d candidate(s) in the Common search space for RNTI: 0x%x\n", - s->nof_candidates, rnti); - - return LIBLTE_SUCCESS; -} - -/** 36.213 v9.3 Table 7.1-1: System Information DCI messages - * Expect DCI formats 1C and 1A in the common search space - */ -int pdcch_init_search_si(pdcch_t *q, uint32_t cfi) { - set_cfi(q, cfi); - int r = pdcch_init_common(q, &q->search_mode[SEARCH_SI], SIRNTI); - if (r >= 0) { - q->current_search_mode = SEARCH_SI; - } - return r; -} -/** 36.213 v9.3 Table 7.1-3 - * Expect DCI formats 1C and 1A in the common search space - */ -int pdcch_init_search_ra(pdcch_t *q, uint16_t ra_rnti, uint32_t cfi) { - set_cfi(q, cfi); - int r = pdcch_init_common(q, &q->search_mode[SEARCH_RA], ra_rnti); - if (r >= 0) { - q->current_search_mode = SEARCH_RA; - } - return r; -} - -void pdcch_set_search_si(pdcch_t *q) { - q->current_search_mode = SEARCH_SI; -} -void pdcch_set_search_ue(pdcch_t *q) { - q->current_search_mode = SEARCH_UE; -} -void pdcch_set_search_ra(pdcch_t *q) { - q->current_search_mode = SEARCH_RA; -} - -void set_cfi(pdcch_t *q, uint32_t cfi) { +static void set_cfi(pdcch_t *q, uint32_t cfi) { if (cfi > 0 && cfi < 4) { q->nof_regs = (regs_pdcch_nregs(q->regs, cfi) / 9) * 9; q->nof_cce = q->nof_regs / 9; @@ -221,6 +59,7 @@ void set_cfi(pdcch_t *q, uint32_t cfi) { } } + /** Initializes the PDCCH transmitter and receiver */ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { int ret = LIBLTE_ERROR_INVALID_INPUTS; @@ -234,7 +73,6 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { bzero(q, sizeof(pdcch_t)); q->cell = cell; q->regs = regs; - q->current_search_mode = SEARCH_NONE; /* Now allocate memory for the maximum number of REGs (CFI=3) */ @@ -261,7 +99,7 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { } } - int poly[3] = { 0x6D, 0x4F, 0x57 }; + uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; if (viterbi_init(&q->decoder, viterbi_37, poly, DCI_MAX_BITS + 16, true)) { goto clean; } @@ -337,13 +175,97 @@ void pdcch_free(pdcch_t *q) { viterbi_free(&q->decoder); } +/** 36.213 v9.1.1 + * Computes up to max_candidates UE-specific candidates for DCI messages and saves them + * in the structure pointed by c. + * Returns the number of candidates saved in the array c. + */ +uint32_t pdcch_ue_locations(pdcch_t *q, dci_location_t *c, uint32_t max_candidates, + uint32_t nsubframe, uint32_t cfi, uint16_t rnti) { + + uint32_t i, k, l, L, m; + uint32_t Yk, ncce; + const int S[4] = { 6, 12, 8, 16 }; + + set_cfi(q, cfi); + + // Compute Yk for this subframe + Yk = rnti; + for (m = 0; m < nsubframe; m++) { + Yk = (39827 * Yk) % 65537; + } + + k = 0; + // All aggregation levels from 8 to 1 + for (l = 3; l >= 0; l--) { + L = (1 << l); + // For all possible ncce offset + for (i = 0; i < MIN(q->nof_cce / L, 16 / S[l]); i++) { + ncce = L * ((Yk + i) % (q->nof_cce / L)); + if (k < max_candidates && + ncce + PDCCH_FORMAT_NOF_CCE(L) < q->nof_cce) + { + c[k].L = l; + c[k].ncce = ncce; + + DEBUG("UE-specific SS Candidate %d: nCCE: %d, L: %d\n", + k, c[k].ncce, c[k].L); + + k++; + } + } + } + + INFO("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x\n", k, rnti); + + return k; +} + + + +/** + * 36.213 9.1.1 + * Computes up to max_candidates candidates in the common search space + * for DCI messages and saves them in the structure pointed by c. + * Returns the number of candidates saved in the array c. + */ +uint32_t pdcch_common_locations(pdcch_t *q, dci_location_t *c, uint32_t max_candidates, + uint32_t cfi) { + uint32_t i, l, L, k; + + set_cfi(q, cfi); + + k = 0; + for (l = 3; l > 1; l--) { + L = (1 << l); + for (i = 0; i < MIN(q->nof_cce, 16) / (L); i++) { + if (k < max_candidates) { + c[k].L = l; + c[k].ncce = (L) * (i % (q->nof_cce / (L))); + DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n", + k, c[k].ncce, c[k].L); + k++; + } + } + } + + INFO("Initiated %d candidate(s) in the Common search space\n", k); + + return k; +} + + + + + + /** 36.212 5.3.3.2 to 5.3.3.4 * * Returns XOR between parity and remainder bits * * TODO: UE transmit antenna selection CRC mask */ -int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof_bits, uint16_t *crc) { +static int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof_bits, uint16_t *crc) { float tmp[3 * (DCI_MAX_BITS + 16)]; uint16_t p_bits, crc_res; @@ -355,6 +277,10 @@ int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof_bits, nof_bits < DCI_MAX_BITS) { + if (VERBOSE_ISDEBUG()) { + vec_fprint_f(stdout, e, E); + } + /* unrate matching */ rm_conv_rx(e, E, tmp, 3 * (nof_bits + 16)); @@ -385,36 +311,63 @@ int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof_bits, } } -int pdcch_decode_candidate(pdcch_t *q, float *llr, dci_candidate_t *c, - dci_msg_t *msg) { - uint16_t crc_res; - INFO("Trying Candidate: Nbits: %d, E: %3d, nCCE: %d, L: %d, RNTI: 0x%x\n", - c->nof_bits, PDCCH_FORMAT_NOF_BITS(c->L), c->ncce, c->L, c->rnti); - - if (dci_decode(q, &llr[72 * c->ncce], msg->data, - PDCCH_FORMAT_NOF_BITS(c->L), c->nof_bits, &crc_res)) { - return LIBLTE_ERROR; - } - - if (c->rnti == crc_res) { - memcpy(&msg->location, c, sizeof(dci_candidate_t)); - INFO("FOUND Candidate: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", - c->nof_bits, PDCCH_FORMAT_NOF_BITS(c->L), c->ncce, c->L, c->rnti); - return 1; +/** Tries to decode a DCI message from the LLRs stored in the pdcch_t structure by the function + * pdcch_extract_llr(). This function can be called multiple times. + * The decoded message is stored in msg. Up to nof_locations are tried from the array of dci_locations_t + * pointed by locations. The CRC is checked agains the RNTI parameter. + * + * Returns 1 if the message is correctly decoded, 0 if not and -1 on error. + */ +int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, + dci_location_t *locations, uint32_t nof_locations, + dci_format_t format, uint16_t rnti) +{ + if (q != NULL && + msg != NULL && + locations != NULL && + nof_locations > 0) + { + uint16_t crc_res; + uint32_t nof_bits = dci_format_sizeof(format, q->cell.nof_prb); + uint32_t i; + + i = 0; + do { + INFO("Trying Candidate: Nbits: %d, E: %3d, nCCE: %d, L: %d, RNTI: 0x%x\n", + nof_bits, PDCCH_FORMAT_NOF_BITS(locations[i].L), locations[i].ncce, locations[i].L, rnti); + + if (dci_decode(q, &q->pdcch_llr[72 * locations[i].ncce], msg->data, + PDCCH_FORMAT_NOF_BITS(locations[i].L), nof_bits, &crc_res) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR; + } + if (crc_res != rnti) { + i++; + } + } while(i < nof_locations && crc_res != rnti); + + if (rnti == crc_res) { + msg->nof_bits = nof_bits; + INFO("FOUND Candidate: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", + nof_bits, PDCCH_FORMAT_NOF_BITS(locations[i].L), locations[i].ncce, locations[i].L, rnti); + return 1; + } else { + return LIBLTE_SUCCESS; + } } - return LIBLTE_SUCCESS; + return LIBLTE_ERROR_INVALID_INPUTS; } -int pdcch_extract_llr(pdcch_t *q, cf_t *slot_symbols, cf_t *ce[MAX_PORTS], - float *llr, uint32_t nsubframe, uint32_t cfi) { +/** Extracts the LLRs from the subframe symbols (demodulation) and stores them in the pdcch_t structure. + * DCI messages can be extracted calling the function pdcch_decode_msg(). + * Every time this function is called, the last demodulated symbols are overwritten. + */ +int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], uint32_t nsubframe, uint32_t cfi) { /* Set pointers for layermapping & precoding */ - int i; + uint32_t i; cf_t *x[MAX_LAYERS]; if (q != NULL && - llr != NULL && - slot_symbols != NULL && nsubframe < 10 && cfi > 0 && cfi < 4) @@ -428,7 +381,7 @@ int pdcch_extract_llr(pdcch_t *q, cf_t *slot_symbols, cf_t *ce[MAX_PORTS], memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); /* extract symbols */ - int n = regs_pdcch_get(q->regs, slot_symbols, q->pdcch_symbols[0]); + int n = regs_pdcch_get(q->regs, sf_symbols, q->pdcch_symbols[0]); if (q->nof_symbols != n) { fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", q->nof_symbols, n); @@ -472,84 +425,18 @@ int pdcch_extract_llr(pdcch_t *q, cf_t *slot_symbols, cf_t *ce[MAX_PORTS], } /* descramble */ - scrambling_f_offset(&q->seq_pdcch[nsubframe], llr, 0, q->nof_bits); + scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 0, q->nof_bits); return LIBLTE_SUCCESS; - } else { - return LIBLTE_ERROR_INVALID_INPUTS; - } -} - -int pdcch_decode_current_mode(pdcch_t *q, float *llr, dci_t *dci, uint32_t subframe) { - int k, i; - int ret; - - if (q->current_search_mode == SEARCH_UE) { - k = subframe; - } else { - k = 0; - } - - for (i = 0; - i < q->search_mode[q->current_search_mode].nof_candidates - && dci->nof_dcis < dci->max_dcis; i++) { - ret = pdcch_decode_candidate(q, q->pdcch_llr, - &q->search_mode[q->current_search_mode].candidates[k][i], - &dci->msg[dci->nof_dcis]); - if (ret == 1) { - dci->nof_dcis++; - } else if (ret == -1) { - return LIBLTE_ERROR; - } - } - return dci->nof_dcis; -} - -int pdcch_decode_si(pdcch_t *q, float *llr, dci_t *dci) { - pdcch_set_search_si(q); - return pdcch_decode_current_mode(q, llr, dci, 0); -} -int pdcch_decode_ra(pdcch_t *q, float *llr, dci_t *dci) { - pdcch_set_search_ra(q); - return pdcch_decode_current_mode(q, llr, dci, 0); -} -int pdcch_decode_ue(pdcch_t *q, float *llr, dci_t *dci, uint32_t nsubframe) { - pdcch_set_search_ue(q); - return pdcch_decode_current_mode(q, llr, dci, nsubframe); + } + return LIBLTE_ERROR_INVALID_INPUTS; } -/* Decodes PDCCH channels - * - * dci->nof_dcis is the size of the dci->msg buffer (ie max number of messages) - * - * Returns number of messages stored in dci - */ -int pdcch_decode(pdcch_t *q, cf_t *slot_symbols, cf_t *ce[MAX_PORTS], - dci_t *dci, uint32_t subframe, uint32_t cfi) { - - if (q != NULL && - dci != NULL && - slot_symbols != NULL && - subframe < 10 && - cfi > 0 && - cfi < 4) - { - if (pdcch_extract_llr(q, slot_symbols, ce, q->pdcch_llr, subframe, cfi)) { - return LIBLTE_ERROR; - } - if (q->current_search_mode != SEARCH_NONE) { - return pdcch_decode_current_mode(q, q->pdcch_llr, dci, subframe); - } - return LIBLTE_SUCCESS; - } else { - return LIBLTE_ERROR_INVALID_INPUTS; - } -} -void crc_set_mask_rnti(char *crc, uint16_t rnti) { - int i; +static void crc_set_mask_rnti(char *crc, uint16_t rnti) { + uint32_t i; char mask[16]; char *r = mask; @@ -564,7 +451,7 @@ void crc_set_mask_rnti(char *crc, uint16_t rnti) { /** 36.212 5.3.3.2 to 5.3.3.4 * TODO: UE transmit antenna selection CRC mask */ -int dci_encode(pdcch_t *q, char *data, char *e, uint32_t nof_bits, uint32_t E, +static int dci_encode(pdcch_t *q, char *data, char *e, uint32_t nof_bits, uint32_t E, uint16_t rnti) { convcoder_t encoder; char tmp[3 * (DCI_MAX_BITS + 16)]; @@ -600,16 +487,57 @@ int dci_encode(pdcch_t *q, char *data, char *e, uint32_t nof_bits, uint32_t E, } } -/** Converts the set of DCI messages to symbols mapped to the slot ready for transmission +void pdcch_reset(pdcch_t *q) { + /* should add elements? Or maybe random bits to facilitate power estimation */ + bzero(q->pdcch_e, q->nof_bits); +} + +/** Encodes ONE DCI message and allocates the encoded bits to the dci_location_t indicated by + * the parameter location. The CRC is scrambled with the RNTI parameter. + * This function can be called multiple times and encoded DCI messages will be stored in the + * pdcch_t structure. A final call to the function pdcch_gen_symbols() will generate and map the + * symbols to the subframe for transmission. + * If the same location is provided in multiple messages, the encoded bits will be overwritten. + * + * @TODO: Use a bitmask and CFI to ensure message locations are valid and old messages are not overwritten. */ -int pdcch_encode(pdcch_t *q, dci_t *dci, cf_t *slot_symbols[MAX_PORTS], - uint32_t nsubframe, uint32_t cfi) { +int pdcch_encode_msg(pdcch_t *q, dci_msg_t *msg, dci_location_t location, uint16_t rnti) { + + int ret = LIBLTE_ERROR_INVALID_INPUTS; + + if (q != NULL) { + ret = LIBLTE_ERROR; + + if (location.L < 4 && + msg->nof_bits < DCI_MAX_BITS) + { + INFO("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", + msg->nof_bits, + PDCCH_FORMAT_NOF_BITS(location.L), + location.ncce, location.L, rnti); + + dci_encode(q, msg->data, &q->pdcch_e[72 * location.ncce], msg->nof_bits, + PDCCH_FORMAT_NOF_BITS(location.L), rnti); + + ret = LIBLTE_SUCCESS; + + } else { + fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", + location.ncce, location.L, q->nof_cce); + } + } + return ret; +} + +/** Converts the set of DCI messages encoded using the function pdcch_encode_msg() + * to symbols mapped to the subframe ready for transmission + */ +int pdcch_gen_symbols(pdcch_t *q, cf_t *slot_symbols[MAX_PORTS], uint32_t nsubframe, uint32_t cfi) { int i; /* Set pointers for layermapping & precoding */ cf_t *x[MAX_LAYERS]; if (q != NULL && - dci != NULL && slot_symbols != NULL && nsubframe < 10 && cfi > 0 && @@ -623,31 +551,6 @@ int pdcch_encode(pdcch_t *q, dci_t *dci, cf_t *slot_symbols[MAX_PORTS], } memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - /* should add elements? Or maybe random bits to facilitate power estimation */ - bzero(q->pdcch_e, q->nof_bits); - - /* Encode DCIs */ - for (i = 0; i < dci->nof_dcis; i++) { - /* do some checks */ - if (dci->msg[i].location.ncce + PDCCH_FORMAT_NOF_CCE(dci->msg[i].location.L) - > q->nof_cce || dci->msg[i].location.L > 3 - || dci->msg[i].location.nof_bits > DCI_MAX_BITS) { - fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", - dci->msg[i].location.ncce, dci->msg[i].location.L, q->nof_cce); - return LIBLTE_ERROR; - } - INFO("Encoding DCI %d: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", i, - dci->msg[i].location.nof_bits, - PDCCH_FORMAT_NOF_BITS(dci->msg[i].location.L), - dci->msg[i].location.ncce, dci->msg[i].location.L, - dci->msg[i].location.rnti); - - dci_encode(q, dci->msg[i].data, &q->pdcch_e[72 * dci->msg[i].location.ncce], - dci->msg[i].location.nof_bits, - PDCCH_FORMAT_NOF_BITS(dci->msg[i].location.L), - dci->msg[i].location.rnti); - } - scrambling_b_offset(&q->seq_pdcch[nsubframe], q->pdcch_e, 0, q->nof_bits); mod_modulate(&q->mod, q->pdcch_e, q->pdcch_d, q->nof_bits); @@ -671,3 +574,4 @@ int pdcch_encode(pdcch_t *q, dci_t *dci, cf_t *slot_symbols[MAX_PORTS], } } + diff --git a/lte/phy/lib/phch/test/dci_unpacking.c b/lte/phy/lib/phch/test/dci_unpacking.c index b2e377b2e..6a1087d11 100644 --- a/lte/phy/lib/phch/test/dci_unpacking.c +++ b/lte/phy/lib/phch/test/dci_unpacking.c @@ -81,9 +81,8 @@ int main(int argc, char **argv) { printf("\n"); dci_msg_type_t dci_type; - msg.location.rnti = SIRNTI; - msg.location.nof_bits = len; - if (dci_msg_get_type(&msg, &dci_type, nof_prb, 1234)) { + msg.nof_bits = len; + if (dci_msg_get_type(&msg, &dci_type, nof_prb, SIRNTI, 1234)) { fprintf(stderr, "Can't obtain DCI message type\n"); exit(-1); } diff --git a/lte/phy/lib/phch/test/pdcch_file_test.c b/lte/phy/lib/phch/test/pdcch_file_test.c index 874853f48..f583a26b9 100644 --- a/lte/phy/lib/phch/test/pdcch_file_test.c +++ b/lte/phy/lib/phch/test/pdcch_file_test.c @@ -56,7 +56,6 @@ cf_t *input_buffer, *fft_buffer, *ce[MAX_PORTS]; regs_t regs; lte_fft_t fft; chest_t chest; -dci_t dci_rx; void usage(char *prog) { printf("Usage: %s [vcfoe] -i input_file\n", prog); @@ -179,9 +178,7 @@ int base_init() { fprintf(stderr, "Error creating PDCCH object\n"); exit(-1); } - - dci_init(&dci_rx, 10); - + DEBUG("Memory init OK\n",0); return 0; } @@ -204,7 +201,6 @@ void base_free() { chest_free(&chest); lte_fft_free(&fft); - dci_free(&dci_rx); pdcch_free(&pdcch); regs_free(®s); } @@ -215,6 +211,9 @@ int main(int argc, char **argv) { int nof_dcis; int nof_frames; int ret; + dci_location_t locations[10]; + uint32_t nof_locations; + dci_msg_t dci_msg; if (argc < 3) { usage(argv[0]); @@ -230,10 +229,11 @@ int main(int argc, char **argv) { if (rnti == SIRNTI) { INFO("Initializing common search space for SI-RNTI\n",0); - pdcch_init_search_si(&pdcch, cfi); + nof_locations = pdcch_common_locations(&pdcch, locations, 10, cfi); } else { + // For ue-specific, generate locations for subframe 5 INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti); - pdcch_init_search_ue(&pdcch, rnti, cfi); + nof_locations = pdcch_ue_locations(&pdcch, locations, 10, 5, cfi, rnti); } ret = -1; nof_frames = 0; @@ -263,14 +263,23 @@ int main(int argc, char **argv) { chest_fprint(&chest, fmatlab, 2*nof_frames, i); } } - - nof_dcis = pdcch_decode(&pdcch, fft_buffer, ce, &dci_rx, nof_frames%10, cfi); + + if (pdcch_extract_llr(&pdcch, fft_buffer, ce, nof_frames, cfi)) { + fprintf(stderr, "Error extracting LLRs\n"); + return -1; + } + + nof_dcis = pdcch_decode_msg(&pdcch, &dci_msg, locations, nof_locations, Format1A, rnti); + if (nof_dcis < 0) { + fprintf(stderr, "Error decoding DCI messages\n"); + return -1; + } INFO("Received %d DCI messages\n", nof_dcis); - for (i=0;i