From 75fea4a04b1823cbdc64d27030868f66f1ae79ba Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 19 Aug 2016 19:19:43 +0200 Subject: [PATCH 001/111] testing new blind search --- srslte/lib/phch/dci.c | 2 +- srslte/lib/phch/sch.c | 2 +- srslte/lib/sync/test/CMakeLists.txt | 23 ++-- srslte/lib/ue/ue_dl.c | 166 ++++++++++++++++------------ 4 files changed, 108 insertions(+), 85 deletions(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 57dc9862a..4e8a8c17d 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -944,7 +944,7 @@ int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 data->mcs_idx = srslte_bit_pack(&y, 5); - data->rv_idx = -1; // For SI-RNTI, get RV from TTI + data->rv_idx = -1; // Get RV later msg->nof_bits = (y - msg->data); diff --git a/srslte/lib/phch/sch.c b/srslte/lib/phch/sch.c index 0550a492f..283b2cf80 100644 --- a/srslte/lib/phch/sch.c +++ b/srslte/lib/phch/sch.c @@ -463,7 +463,7 @@ static int decode_tb(srslte_sch_t *q, par_tx = ((uint32_t) parity[0])<<16 | ((uint32_t) parity[1])<<8 | ((uint32_t) parity[2]); if (!par_rx) { - printf("Warning: Received all-zero transport block\n\n", 0); + INFO("Warning: Received all-zero transport block\n\n", 0); } if (par_rx == par_tx && par_rx) { diff --git a/srslte/lib/sync/test/CMakeLists.txt b/srslte/lib/sync/test/CMakeLists.txt index b6239124f..364421114 100644 --- a/srslte/lib/sync/test/CMakeLists.txt +++ b/srslte/lib/sync/test/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +find_package(SRSGUI) + ######################################################################## # PROGRAM TO DEBUG PSS FROM USRP ######################################################################## @@ -25,21 +27,22 @@ add_executable(pss_file pss_file.c) target_link_libraries(pss_file srslte) +if(UHD_FOUND) + add_executable(pss_usrp pss_usrp.c) + target_link_libraries(pss_usrp srslte) +endif(UHD_FOUND) + + if(SRSGUI_FOUND) + include_directories(${SRSGUI_INCLUDE_DIRS}) target_link_libraries(pss_file ${SRSGUI_LIBRARIES}) + if(UHD_FOUND) + target_link_libraries(pss_usrp ${SRSGUI_LIBRARIES}) + endif(UHD_FOUND) else(SRSGUI_FOUND) - set_target_properties(pss_file PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") + add_definitions(-DDISABLE_GRAPHICS) endif(SRSGUI_FOUND) -if(UHD_FOUND) - add_executable(pss_usrp pss_usrp.c) - target_link_libraries(pss_usrp srslte) - if(SRSGUI_FOUND) - target_link_libraries(pss_usrp ${SRSGUI_LIBRARIES}) - else(SRSGUI_FOUND) - set_target_properties(pss_usrp PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") - endif(SRSGUI_FOUND) -endif(UHD_FOUND) BuildMex(MEXNAME pss SOURCES pss_mex.c LIBRARIES srslte_static srslte_mex) BuildMex(MEXNAME sss SOURCES sss_mex.c LIBRARIES srslte_static srslte_mex) diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index d6f9fc33f..7e1b97bef 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -37,9 +37,9 @@ #define CURRENT_SLOTLEN_RE SRSLTE_SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp) #define CURRENT_SFLEN_RE SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp) -#define MAX_CANDIDATES 64 +#define MAX_LOCATIONS 64 -static srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1}; // SRSLTE_DCI_FORMAT1B should go here also +static srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1}; // Only TM1 and TM2 are currently supported const uint32_t nof_ue_formats = 2; static srslte_dci_format_t common_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FORMAT1C}; @@ -282,49 +282,74 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_ra_dl_grant_t * return ret; } -int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) + +uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { + return q->last_n_cce; +} + +#define MAX_CANDIDATES_UE 6 // From 36.213 Table 9.1.1-1 +#define MAX_CANDIDATES_COM 4 // From 36.213 Table 9.1.1-1 +#define MAX_CANDIDATES (MAX_CANDIDATES_UE + MAX_CANDIDATES_COM) +typedef struct { + srslte_dci_format_t format; + srslte_dci_location_t loc[MAX_CANDIDATES]; + uint32_t nof_locations; +} dci_blind_search_t; + +static int dci_blind_search(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, dci_blind_search_t *search_space, uint16_t rnti) { - srslte_dci_location_t locations[MAX_CANDIDATES]; - uint32_t nof_locations = srslte_pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, rnti); + int ret = SRSLTE_ERROR; uint16_t crc_rem = 0; - if (rnti) { - /* Do not search if an UL DCI is already pending */ - - if (q->pending_ul_dci_rnti == rnti) { - q->pending_ul_dci_rnti = 0; - memcpy(dci_msg, &q->pending_ul_dci_msg, sizeof(srslte_dci_msg_t)); - return 1; - } - - for (uint32_t i=0;ipdcch, dci_msg, &locations[i], SRSLTE_DCI_FORMAT0, &crc_rem)) { + ret = 0; + int i=0; + do { + if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &search_space->loc[i], search_space->format, &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } - // Check format differentiation - if (dci_msg->format != SRSLTE_DCI_FORMAT0) { - crc_rem = 0; + if (crc_rem == rnti) { + + // If searching for Format1A but found Format0 save it for later + if (dci_msg->format == SRSLTE_DCI_FORMAT0 && search_space->format == SRSLTE_DCI_FORMAT1A) + { + q->pending_ul_dci_rnti = crc_rem; + memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); + + // Else if we found it, save location and leave + } else if (dci_msg->format != search_space->format) + { + ret = 1; + memcpy(&q->last_location, &search_space->loc[i], sizeof(srslte_dci_location_t)); + } } - DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem); - if (crc_rem == rnti) { - memcpy(&q->last_location, &locations[i], sizeof(srslte_dci_location_t)); - } - } - if (crc_rem == rnti) { + i++; + } while (!ret && i < search_space->nof_locations); + } + return ret; +} + +int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) +{ + if (rnti) { + /* Do not search if an UL DCI is already pending */ + if (q->pending_ul_dci_rnti == rnti) { + q->pending_ul_dci_rnti = 0; + memcpy(dci_msg, &q->pending_ul_dci_msg, sizeof(srslte_dci_msg_t)); return 1; - } else { - return 0; } + + // Configure and run DCI blind search + dci_blind_search_t search_space; + search_space.format = SRSLTE_DCI_FORMAT0; + search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + return dci_blind_search(q, dci_msg, &search_space, rnti); + } else { return 0; } } -uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { - return q->last_n_cce; -} - int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) { srslte_rnti_type_t rnti_type; @@ -340,53 +365,48 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 return srslte_ue_dl_find_dl_dci_type(q, dci_msg, cfi, sf_idx, rnti, rnti_type); } -int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, - uint16_t rnti, srslte_rnti_type_t rnti_type) +// Blind search for SI/P/RA-RNTI +static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint16_t rnti) { - srslte_dci_location_t locations[MAX_CANDIDATES]; - uint32_t nof_locations; - uint32_t nof_formats; - srslte_dci_format_t *formats = NULL; - - /* Generate PDCCH candidates */ - if (rnti_type == SRSLTE_RNTI_SI || rnti_type == SRSLTE_RNTI_PCH || rnti_type == SRSLTE_RNTI_RAR) { - nof_locations = srslte_pdcch_common_locations(&q->pdcch, locations, MAX_CANDIDATES, q->cfi); - formats = common_formats; - nof_formats = nof_common_formats; - } else { - nof_locations = srslte_pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, q->cfi, rnti); - formats = ue_formats; - nof_formats = nof_ue_formats; + int ret = 0; + // Configure and run DCI blind search + dci_blind_search_t search_space; + search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); + for (int f=0;fcell.nof_prb), locations[i].L, locations[i].ncce); - q->last_n_cce = locations[i].ncce; - if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &locations[i], formats[f], &crc_rem)) { - fprintf(stderr, "Error decoding DCI msg\n"); - return SRSLTE_ERROR; - } - if (crc_rem == rnti) { - INFO("Found DCI nCCE: %d, L: %d, n_bits=%d\n", locations[i].ncce, locations[i].L, srslte_dci_format_sizeof_lut(formats[f], q->cell.nof_prb)); - memcpy(&q->last_location, &locations[i], sizeof(srslte_dci_location_t)); - } - if (crc_rem == rnti && dci_msg->format == SRSLTE_DCI_FORMAT0) { - /* Save Format 0 msg. Recovered next call to srslte_ue_dl_find_ul_dci() */ - q->pending_ul_dci_rnti = crc_rem; - memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); - crc_rem = 0; - } - DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem); +// Blind search for C-RNTI +static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) +{ + int ret = 0; + // Search UE-specific search space + dci_blind_search_t search_space; + search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, q->cfi, rnti); + for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); + return dci_blind_search(q, dci_msg, &search_space, rnti); +} + +int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, + uint16_t rnti, srslte_rnti_type_t rnti_type) +{ + if (rnti_type == SRSLTE_RNTI_SI || rnti_type == SRSLTE_RNTI_PCH || rnti_type == SRSLTE_RNTI_RAR) { + return find_dl_dci_type_siprarnti(q, dci_msg, cfi, rnti); } else { - INFO("Couldn't find any DCI for RNTI=0x%x\n", rnti); - return 0; + return find_dl_dci_type_crnti(q, dci_msg, cfi, sf_idx, rnti); } } From 9c18c03b97575b1676f062184037892cdb285441 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 25 Aug 2016 17:05:17 -0700 Subject: [PATCH 002/111] Inreased DCI buffer because CRC is appended there --- srslte/include/srslte/phch/dci.h | 2 +- srslte/lib/phch/dci.c | 5 +- srslte/lib/phch/test/CMakeLists.txt | 3 - srslte/lib/phch/test/dci_unpacking.c | 102 --------------------------- srslte/lib/phch/test/pucch_test.c | 4 +- srslte/lib/phch/test/pusch_test.c | 4 +- 6 files changed, 8 insertions(+), 112 deletions(-) delete mode 100644 srslte/lib/phch/test/dci_unpacking.c diff --git a/srslte/include/srslte/phch/dci.h b/srslte/include/srslte/phch/dci.h index c3fe268e1..b8e590516 100644 --- a/srslte/include/srslte/phch/dci.h +++ b/srslte/include/srslte/phch/dci.h @@ -43,7 +43,7 @@ #include "srslte/common/phy_common.h" #include "srslte/phch/ra.h" -#define SRSLTE_DCI_MAX_BITS 57 +#define SRSLTE_DCI_MAX_BITS 128 #define SRSLTE_RAR_GRANT_LEN 20 diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 57dc9862a..b4262f857 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -65,7 +65,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { - fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), ret); + fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); return ret; } @@ -386,7 +386,8 @@ uint32_t srslte_dci_format_sizeof(srslte_dci_format_t format, uint32_t nof_prb, return dci_format3A_sizeof(nof_prb); */ default: - return SRSLTE_ERROR; + printf("Error computing DCI bits: Unknown format %d\n", format); + return 0; } } diff --git a/srslte/lib/phch/test/CMakeLists.txt b/srslte/lib/phch/test/CMakeLists.txt index 9789a605d..90c658e66 100644 --- a/srslte/lib/phch/test/CMakeLists.txt +++ b/srslte/lib/phch/test/CMakeLists.txt @@ -81,9 +81,6 @@ target_link_libraries(pdcch_test srslte) add_test(pdcch_test pdcch_test) -add_executable(dci_unpacking dci_unpacking.c) -target_link_libraries(dci_unpacking srslte) - BuildMex(MEXNAME pdcch SOURCES pdcch_test_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## diff --git a/srslte/lib/phch/test/dci_unpacking.c b/srslte/lib/phch/test/dci_unpacking.c deleted file mode 100644 index 7e65b433f..000000000 --- a/srslte/lib/phch/test/dci_unpacking.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include - -#include "srslte/srslte.h" - -void usage(char *prog) { - printf("Usage: %s nof_prb length_bits Word0 Word1 ...\n", prog); -} - -int main(int argc, char **argv) { - srslte_dci_msg_t msg; - srslte_ra_dl_dci_t ra_dl; - int len, rlen; - int nof_prb; - int nwords; - int i; - uint8_t *y; - - if (argc < 3) { - usage(argv[0]); - exit(-1); - } - - nof_prb = atoi(argv[1]); - len = atoi(argv[2]); - - nwords = (len - 1) / 32 + 1; - - if (argc < 3 + nwords) { - usage(argv[0]); - exit(-1); - } - - y = msg.data; - rlen = 0; - uint32_t x; - for (i = 0; i < nwords; i++) { - x = strtoul(argv[i + 3], NULL, 16); - if (len - rlen < 32) { - srslte_bit_unpack(x, &y, len - rlen); - } else { - srslte_bit_unpack(x, &y, 32); - } - - } - - printf("DCI message len %d:\n", len); - for (i = 0; i < len; i++) { - printf("%d, ", msg.data[i]); - } - printf("\n"); - - srslte_dci_msg_type_t dci_type; - msg.nof_bits = len; - if (srslte_dci_msg_get_type(&msg, &dci_type, nof_prb, SRSLTE_SIRNTI)) { - fprintf(stderr, "Can't obtain DCI message type\n"); - exit(-1); - } - printf("\n"); - printf("Message type:"); - srslte_dci_msg_type_fprint(stdout, dci_type); - switch (dci_type.type) { - case SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED: - bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t)); - srslte_dci_msg_unpack_pdsch(&msg, &ra_dl, nof_prb, 1, false); - srslte_ra_pdsch_fprint(stdout, &ra_dl, nof_prb); - break; - default: - printf("Error expected PDSCH\n"); - exit(-1); - } - printf("\n"); -} diff --git a/srslte/lib/phch/test/pucch_test.c b/srslte/lib/phch/test/pucch_test.c index aeec68a41..77fa75e62 100644 --- a/srslte/lib/phch/test/pucch_test.c +++ b/srslte/lib/phch/test/pucch_test.c @@ -90,11 +90,11 @@ int main(int argc, char **argv) { if (srslte_pucch_init(&pucch, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); - goto quit; + exit(-1); } if (srslte_refsignal_ul_init(&dmrs, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); - goto quit; + exit(-1; } bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); diff --git a/srslte/lib/phch/test/pusch_test.c b/srslte/lib/phch/test/pusch_test.c index 8752cc734..def6b5982 100644 --- a/srslte/lib/phch/test/pusch_test.c +++ b/srslte/lib/phch/test/pusch_test.c @@ -184,13 +184,13 @@ int main(int argc, char **argv) { sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re); if (!sf_symbols) { perror("malloc"); - goto quit; + exit(-1); } data = srslte_vec_malloc(sizeof(uint8_t) * cfg.grant.mcs.tbs); if (!data) { perror("malloc"); - goto quit; + exit(-1); } for (uint32_t i=0;i Date: Thu, 25 Aug 2016 17:14:10 -0700 Subject: [PATCH 003/111] compilation issue in pucch_test --- srslte/lib/phch/test/pucch_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/test/pucch_test.c b/srslte/lib/phch/test/pucch_test.c index 77fa75e62..a2a9b8958 100644 --- a/srslte/lib/phch/test/pucch_test.c +++ b/srslte/lib/phch/test/pucch_test.c @@ -94,7 +94,7 @@ int main(int argc, char **argv) { } if (srslte_refsignal_ul_init(&dmrs, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); - exit(-1; + exit(-1); } bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); From 10cbb9ad920191f9c74e44123e059e92747e9f55 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 25 Aug 2016 19:01:47 -0700 Subject: [PATCH 004/111] ue_sync: set default offset correction interval to 0. chest_dl: added option to average estimates per subframe --- matlab/tests/equalizer_test.m | 21 +++++------- matlab/tests/pdsch_equal.m | 3 +- srslte/examples/pdsch_ue.c | 2 ++ srslte/lib/ch_estimation/chest_dl.c | 52 +++++++++++++++++++++-------- srslte/lib/ue/ue_sync.c | 22 ++++++------ 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m index 1391d5e53..5cd7e3353 100644 --- a/matlab/tests/equalizer_test.m +++ b/matlab/tests/equalizer_test.m @@ -6,13 +6,13 @@ clear plot_noise_estimation_only=false; -SNR_values_db=100;%linspace(20,35,8); -Nrealizations=1; +SNR_values_db=linspace(0,20,8); +Nrealizations=10; w1=0.1; w2=0.3; -enb.NDLRB = 6; % Number of resource blocks +enb.NDLRB = 25; % Number of resource blocks enb.CellRefP = 1; % One transmit antenna port enb.NCellID = 0; % Cell ID @@ -181,8 +181,8 @@ for i=1:10 rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14); %% Channel Estimation with Matlab - [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i), hls(:,(1:4*P)+(i-1)*4*P)] = ... - lteDLChannelEstimate2(enb,cec,rxGrid_sf); + [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i)] = ... + lteDLChannelEstimate(enb,cec,rxGrid_sf); tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP; %% LS-Linear estimation with srsLTE @@ -227,17 +227,12 @@ if (length(SNR_values_db) == 1) tmp{Ntests+1}='Real'; legend(tmp) - xlabel('SNR (dB)') + xlabel('Sample') ylabel('Channel Gain') grid on; - fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx))) - fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx))) -<<<<<<< HEAD - -======= - ->>>>>>> master +% fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx))) +% fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx))) end end diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index 665ff8047..08722b3bd 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -116,7 +116,7 @@ for snr_idx=1:length(SNR_values) rmccFgOut.TotSubframes=1; % Perform channel estimation - [hest, nest,estimates] = lteDLChannelEstimate2(rmccFgOut, cec, subframe_rx); + [hest, nest] = lteDLChannelEstimate(rmccFgOut, cec, subframe_rx); [cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest); [trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ... @@ -156,6 +156,7 @@ if (length(SNR_values)>1) axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1]) else scatter(real(symbols{1}),imag(symbols{1})) + plot( fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index b0a9c5fd6..8c986ab75 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -583,11 +583,13 @@ int main(int argc, char **argv) { sfn++; if (sfn == 1024) { sfn = 0; + /* printf("\n"); ue_dl.pkt_errors = 0; ue_dl.pkts_total = 0; ue_dl.nof_detected = 0; nof_trials = 0; + */ } } diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index beb7518d2..7ac4444a0 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -39,6 +39,8 @@ #include "srslte/utils/vector.h" #include "srslte/utils/convolution.h" +#define AVERAGE_SUBFRAME + //#define DEFAULT_FILTER_LEN 3 #ifdef DEFAULT_FILTER_LEN @@ -165,7 +167,18 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) /* Uses the difference between the averaged and non-averaged pilot estimates */ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) { + float norm = sqrt(2); +#ifdef AVERAGE_SUBFRAME + int nref=2*q->cell.nof_prb; +#else int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); + if (q->smooth_filter_len == 3) { + float a = q->smooth_filter[0]; + float norm3 = 6.143*a*a+0.04859*a-0.002774; + norm /= norm3; + } +#endif + /* Substract noisy pilot estimates */ srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref); @@ -179,12 +192,6 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) #endif /* Compute average power. Normalized for filter len 3 using matlab */ - float norm = 1; - if (q->smooth_filter_len == 3) { - float a = q->smooth_filter[0]; - float norm3 = 6.143*a*a+0.04859*a-0.002774; - norm /= norm3; - } float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); return power; } @@ -225,19 +232,29 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id) { - /* interpolate the symbols with references in the freq domain */ - uint32_t l; + +#ifdef AVERAGE_SUBFRAME + // Interpolate symbol 0 in the frequency domain + uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); + srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, + &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], + fidx_offset, SRSLTE_NRE/2-fidx_offset); + // All channel estimates in the subframe are the same + for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { + memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); + } +#else + uint32_t l=0; uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); - - /* Interpolate in the frequency domain */ + + // Interpolate in the frequency domain for (l=0;lcell, l, port_id, 0); srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l], &ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], fidx_offset, SRSLTE_NRE/2-fidx_offset); } - - /* Now interpolate in the time domain between symbols */ + // Interpolate in the time domain between symbols if (SRSLTE_CP_ISNORM(q->cell.cp)) { if (nsymbols == 4) { srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); @@ -261,6 +278,7 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); } } +#endif } void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { @@ -293,9 +311,17 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; - for (int l=0;lsmooth_filter, &output[l*nref], nref, q->smooth_filter_len); +#endif } +#ifdef AVERAGE_SUBFRAME + srslte_vec_sc_prod_cfc(output, (float) 1.0/nsymbols, output, nref); +#endif } float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) { diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index d04c5c303..a81004ef0 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -44,7 +44,7 @@ cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_MAX_LOST 4 #define TRACK_FRAME_SIZE 32 #define FIND_NOF_AVG_FRAMES 4 -#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 5 +#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 #define DEFAULT_SFO_EMA_COEFF 0.1 cf_t dummy_offset_buffer[1024*1024]; @@ -358,7 +358,6 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { { INFO("Warning: Expected SF idx %d but got %d! (%d frames)\n", q->sf_idx, srslte_sync_get_sf_idx(&q->strack), q->frame_no_cnt); - q->sf_idx = srslte_sync_get_sf_idx(&q->strack); q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); @@ -382,18 +381,19 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { // Compute cumulative moving average time offset */ if (!frame_idx) { - // Adjust RF sampling time based on the mean sampling offset - q->next_rf_sample_offset = (int) round(q->mean_sample_offset); - - // Reset PSS averaging if correcting every a period longer than 1 - if (q->sample_offset_correct_period > 1) { - srslte_sync_reset(&q->strack); - } - - // Compute SFO based on mean sample offset if (q->sample_offset_correct_period) { + // Adjust RF sampling time based on the mean sampling offset + q->next_rf_sample_offset = (int) round(q->mean_sample_offset); + // Reset PSS averaging if correcting every a period longer than 1 + if (q->sample_offset_correct_period > 1) { + srslte_sync_reset(&q->strack); + } + // Compute SFO based on mean sample offset q->mean_sample_offset /= q->sample_offset_correct_period; + } else { + q->next_rf_sample_offset = q->last_sample_offset; } + q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema); INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/5-sf, ema=%f, length=%d\n", From 58d955ea10d67e0407cdd01def3aef65a34d2944 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 25 Aug 2016 19:04:36 -0700 Subject: [PATCH 005/111] psdch_ue: disabled agc by default. Set default gain to 70 dB --- srslte/examples/pdsch_ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 8c986ab75..e347f0e71 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -39,7 +39,7 @@ #include "srslte/srslte.h" -#define ENABLE_AGC_DEFAULT +//#define ENABLE_AGC_DEFAULT #ifndef DISABLE_RF #include "srslte/rf/rf.h" @@ -116,7 +116,7 @@ void args_default(prog_args_t *args) { #ifdef ENABLE_AGC_DEFAULT args->rf_gain = -1.0; #else - args->rf_gain = 50.0; + args->rf_gain = 70.0; #endif args->net_port = -1; args->net_address = "127.0.0.1"; From 82cfa014684d452e71e29936d84a7869a282bc10 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 27 Aug 2016 17:24:55 +0000 Subject: [PATCH 006/111] chest_dl: subframe averaging with previous --- .../include/srslte/ch_estimation/chest_dl.h | 10 ++ srslte/lib/ch_estimation/chest_dl.c | 162 +++++++++--------- 2 files changed, 94 insertions(+), 78 deletions(-) diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index a4afa1d84..3aabd2595 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -63,6 +63,7 @@ typedef struct { srslte_refsignal_cs_t csr_signal; cf_t *pilot_estimates; cf_t *pilot_estimates_average; + cf_t *pilot_average_last; cf_t *pilot_recv_signal; cf_t *tmp_noise; @@ -73,6 +74,9 @@ typedef struct { uint32_t smooth_filter_len; float smooth_filter[SRSLTE_CHEST_MAX_SMOOTH_FIL_LEN]; + float time_ema_coeff; + bool average_subframe; + srslte_interp_linsrslte_vec_t srslte_interp_linvec; srslte_interp_lin_t srslte_interp_lin; @@ -102,6 +106,12 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w); +SRSLTE_API void srslte_chest_dl_set_time_ema_coeff(srslte_chest_dl_t *q, + float t); + +SRSLTE_API void srslte_chest_dl_set_average_subframe(srslte_chest_dl_t *q, + bool enable); + SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, srslte_chest_dl_noise_alg_t noise_estimation_alg); diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index 7ac4444a0..e550a5305 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -39,32 +39,8 @@ #include "srslte/utils/vector.h" #include "srslte/utils/convolution.h" -#define AVERAGE_SUBFRAME - -//#define DEFAULT_FILTER_LEN 3 - -#ifdef DEFAULT_FILTER_LEN -static void set_default_filter(srslte_chest_dl_t *q, int filter_len) { - - float fil[SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN]; - - for (int i=0;ipilot_average_last = srslte_vec_malloc(sizeof(cf_t) * 2 * cell.nof_prb); + if (!q->pilot_average_last) { + perror("malloc"); + goto clean_exit; + } q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb)); if (!q->pilot_recv_signal) { perror("malloc"); @@ -127,7 +108,14 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell) q->noise_alg = SRSLTE_NOISE_ALG_REFS; - q->smooth_filter_len = 3; + q->time_ema_coeff = 1.0; +#ifdef DEFAULT_TIME_EMA_COEFF + q->time_ema_coeff = DEFAULT_TIME_EMA_COEFF; +#endif + + q->average_subframe = true; + + q->smooth_filter_len = DEFAULT_FILTER_LEN; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); q->cell = cell; @@ -158,6 +146,9 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) if (q->pilot_estimates_average) { free(q->pilot_estimates_average); } + if (q->pilot_average_last) { + free(q->pilot_average_last); + } if (q->pilot_recv_signal) { free(q->pilot_recv_signal); } @@ -233,52 +224,52 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id) { -#ifdef AVERAGE_SUBFRAME - // Interpolate symbol 0 in the frequency domain - uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); - srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, - &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], - fidx_offset, SRSLTE_NRE/2-fidx_offset); - // All channel estimates in the subframe are the same - for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { - memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); - } -#else - uint32_t l=0; - uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); - - // Interpolate in the frequency domain - for (l=0;lcell, l, port_id, 0); - srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l], - &ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], - fidx_offset, SRSLTE_NRE/2-fidx_offset); - } - // Interpolate in the time domain between symbols - if (SRSLTE_CP_ISNORM(q->cell.cp)) { - if (nsymbols == 4) { - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3); - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2); - } else { - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5); - } + if (q->average_subframe) { + // Interpolate symbol 0 in the frequency domain + uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); + srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, + &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], + fidx_offset, SRSLTE_NRE/2-fidx_offset); + // All channel estimates in the subframe are the same + for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { + memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); + } } else { - if (nsymbols == 4) { - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2); - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2); + uint32_t l=0; + uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); + + // Interpolate in the frequency domain + for (l=0;lcell, l, port_id, 0); + srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l], + &ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], + fidx_offset, SRSLTE_NRE/2-fidx_offset); + } + // Interpolate in the time domain between symbols + if (SRSLTE_CP_ISNORM(q->cell.cp)) { + if (nsymbols == 4) { + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3); + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2); + } else { + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5); + } } else { - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); - } + if (nsymbols == 4) { + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2); + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2); + } else { + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); + } + } } -#endif } void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { @@ -307,21 +298,36 @@ void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w) q->smooth_filter[1] = 1-2*w; } +void srslte_chest_dl_set_time_ema_coeff(srslte_chest_dl_t *q, float t) { + if (t > 0.0 && t <= 1.0) { + q->time_ema_coeff = t; + } +} + +void srslte_chest_dl_set_average_subframe(srslte_chest_dl_t *q, bool enable) { + q->average_subframe = enable; +} + static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) { uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; memcpy(output, input, nref*sizeof(cf_t)); for (int l=1;lsmooth_filter, &output[l*nref], nref, q->smooth_filter_len); -#endif + if (q->average_subframe) { + srslte_vec_sum_ccc(output, &input[l*nref], output, nref); + } else { + srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len); + } + } + if (q->average_subframe) { + srslte_vec_sc_prod_cfc(output, (float) q->time_ema_coeff/nsymbols, output, nref); + if (q->time_ema_coeff < 1.0) { + srslte_vec_sc_prod_cfc(q->pilot_average_last, 1-q->time_ema_coeff, q->pilot_average_last, nref); + srslte_vec_sum_ccc(q->pilot_average_last, output, output, nref); + memcpy(q->pilot_average_last, output, nref*sizeof(cf_t)); + } } -#ifdef AVERAGE_SUBFRAME - srslte_vec_sc_prod_cfc(output, (float) 1.0/nsymbols, output, nref); -#endif } float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) { From 9d68d0adb42f5fa71ea955b4c9b7e10343ada7b9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 29 Aug 2016 17:42:46 +0200 Subject: [PATCH 007/111] Revert "chest_dl: subframe averaging with previous" This reverts commit 82cfa014684d452e71e29936d84a7869a282bc10. --- .../include/srslte/ch_estimation/chest_dl.h | 10 -- srslte/lib/ch_estimation/chest_dl.c | 162 +++++++++--------- 2 files changed, 78 insertions(+), 94 deletions(-) diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index 3aabd2595..a4afa1d84 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -63,7 +63,6 @@ typedef struct { srslte_refsignal_cs_t csr_signal; cf_t *pilot_estimates; cf_t *pilot_estimates_average; - cf_t *pilot_average_last; cf_t *pilot_recv_signal; cf_t *tmp_noise; @@ -74,9 +73,6 @@ typedef struct { uint32_t smooth_filter_len; float smooth_filter[SRSLTE_CHEST_MAX_SMOOTH_FIL_LEN]; - float time_ema_coeff; - bool average_subframe; - srslte_interp_linsrslte_vec_t srslte_interp_linvec; srslte_interp_lin_t srslte_interp_lin; @@ -106,12 +102,6 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w); -SRSLTE_API void srslte_chest_dl_set_time_ema_coeff(srslte_chest_dl_t *q, - float t); - -SRSLTE_API void srslte_chest_dl_set_average_subframe(srslte_chest_dl_t *q, - bool enable); - SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, srslte_chest_dl_noise_alg_t noise_estimation_alg); diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index e550a5305..7ac4444a0 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -39,8 +39,32 @@ #include "srslte/utils/vector.h" #include "srslte/utils/convolution.h" -#define DEFAULT_FILTER_LEN 3 -#define DEFAULT_TIME_EMA_COEFF 0.9 +#define AVERAGE_SUBFRAME + +//#define DEFAULT_FILTER_LEN 3 + +#ifdef DEFAULT_FILTER_LEN +static void set_default_filter(srslte_chest_dl_t *q, int filter_len) { + + float fil[SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN]; + + for (int i=0;ipilot_average_last = srslte_vec_malloc(sizeof(cf_t) * 2 * cell.nof_prb); - if (!q->pilot_average_last) { - perror("malloc"); - goto clean_exit; - } q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb)); if (!q->pilot_recv_signal) { perror("malloc"); @@ -108,14 +127,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell) q->noise_alg = SRSLTE_NOISE_ALG_REFS; - q->time_ema_coeff = 1.0; -#ifdef DEFAULT_TIME_EMA_COEFF - q->time_ema_coeff = DEFAULT_TIME_EMA_COEFF; -#endif - - q->average_subframe = true; - - q->smooth_filter_len = DEFAULT_FILTER_LEN; + q->smooth_filter_len = 3; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); q->cell = cell; @@ -146,9 +158,6 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) if (q->pilot_estimates_average) { free(q->pilot_estimates_average); } - if (q->pilot_average_last) { - free(q->pilot_average_last); - } if (q->pilot_recv_signal) { free(q->pilot_recv_signal); } @@ -224,52 +233,52 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id) { - if (q->average_subframe) { - // Interpolate symbol 0 in the frequency domain - uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); - srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, - &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], - fidx_offset, SRSLTE_NRE/2-fidx_offset); - // All channel estimates in the subframe are the same - for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { - memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); - } +#ifdef AVERAGE_SUBFRAME + // Interpolate symbol 0 in the frequency domain + uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); + srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, + &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], + fidx_offset, SRSLTE_NRE/2-fidx_offset); + // All channel estimates in the subframe are the same + for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { + memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); + } +#else + uint32_t l=0; + uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); + + // Interpolate in the frequency domain + for (l=0;lcell, l, port_id, 0); + srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l], + &ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], + fidx_offset, SRSLTE_NRE/2-fidx_offset); + } + // Interpolate in the time domain between symbols + if (SRSLTE_CP_ISNORM(q->cell.cp)) { + if (nsymbols == 4) { + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3); + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2); + } else { + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5); + } } else { - uint32_t l=0; - uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); - - // Interpolate in the frequency domain - for (l=0;lcell, l, port_id, 0); - srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l], - &ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], - fidx_offset, SRSLTE_NRE/2-fidx_offset); - } - // Interpolate in the time domain between symbols - if (SRSLTE_CP_ISNORM(q->cell.cp)) { - if (nsymbols == 4) { - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3); - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2); - } else { - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5); - } + if (nsymbols == 4) { + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2); + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2); } else { - if (nsymbols == 4) { - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2); - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2); - } else { - srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5); - srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); - } - } + srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5); + srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); + } } +#endif } void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { @@ -298,36 +307,21 @@ void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w) q->smooth_filter[1] = 1-2*w; } -void srslte_chest_dl_set_time_ema_coeff(srslte_chest_dl_t *q, float t) { - if (t > 0.0 && t <= 1.0) { - q->time_ema_coeff = t; - } -} - -void srslte_chest_dl_set_average_subframe(srslte_chest_dl_t *q, bool enable) { - q->average_subframe = enable; -} - static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) { uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; memcpy(output, input, nref*sizeof(cf_t)); for (int l=1;laverage_subframe) { - srslte_vec_sum_ccc(output, &input[l*nref], output, nref); - } else { - srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len); - } - } - if (q->average_subframe) { - srslte_vec_sc_prod_cfc(output, (float) q->time_ema_coeff/nsymbols, output, nref); - if (q->time_ema_coeff < 1.0) { - srslte_vec_sc_prod_cfc(q->pilot_average_last, 1-q->time_ema_coeff, q->pilot_average_last, nref); - srslte_vec_sum_ccc(q->pilot_average_last, output, output, nref); - memcpy(q->pilot_average_last, output, nref*sizeof(cf_t)); - } +#ifdef AVERAGE_SUBFRAME + srslte_vec_sum_ccc(output, &input[l*nref], output, nref); +#else + srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len); +#endif } +#ifdef AVERAGE_SUBFRAME + srslte_vec_sc_prod_cfc(output, (float) 1.0/nsymbols, output, nref); +#endif } float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) { From 4f7b372711f4a31d13bb05cb553b020d9c185463 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 29 Aug 2016 17:43:04 +0200 Subject: [PATCH 008/111] Revert "psdch_ue: disabled agc by default. Set default gain to 70 dB" This reverts commit 58d955ea10d67e0407cdd01def3aef65a34d2944. --- srslte/examples/pdsch_ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index e347f0e71..8c986ab75 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -39,7 +39,7 @@ #include "srslte/srslte.h" -//#define ENABLE_AGC_DEFAULT +#define ENABLE_AGC_DEFAULT #ifndef DISABLE_RF #include "srslte/rf/rf.h" @@ -116,7 +116,7 @@ void args_default(prog_args_t *args) { #ifdef ENABLE_AGC_DEFAULT args->rf_gain = -1.0; #else - args->rf_gain = 70.0; + args->rf_gain = 50.0; #endif args->net_port = -1; args->net_address = "127.0.0.1"; From 850259e2f704a5c9fabb801a69111a9de2409f50 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 29 Aug 2016 17:43:07 +0200 Subject: [PATCH 009/111] Revert "ue_sync: set default offset correction interval to 0. chest_dl: added option to average estimates per subframe" This reverts commit 10cbb9ad920191f9c74e44123e059e92747e9f55. --- matlab/tests/equalizer_test.m | 21 +++++++----- matlab/tests/pdsch_equal.m | 3 +- srslte/examples/pdsch_ue.c | 2 -- srslte/lib/ch_estimation/chest_dl.c | 52 ++++++++--------------------- srslte/lib/ue/ue_sync.c | 22 ++++++------ 5 files changed, 38 insertions(+), 62 deletions(-) diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m index 5cd7e3353..1391d5e53 100644 --- a/matlab/tests/equalizer_test.m +++ b/matlab/tests/equalizer_test.m @@ -6,13 +6,13 @@ clear plot_noise_estimation_only=false; -SNR_values_db=linspace(0,20,8); -Nrealizations=10; +SNR_values_db=100;%linspace(20,35,8); +Nrealizations=1; w1=0.1; w2=0.3; -enb.NDLRB = 25; % Number of resource blocks +enb.NDLRB = 6; % Number of resource blocks enb.CellRefP = 1; % One transmit antenna port enb.NCellID = 0; % Cell ID @@ -181,8 +181,8 @@ for i=1:10 rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14); %% Channel Estimation with Matlab - [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i)] = ... - lteDLChannelEstimate(enb,cec,rxGrid_sf); + [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i), hls(:,(1:4*P)+(i-1)*4*P)] = ... + lteDLChannelEstimate2(enb,cec,rxGrid_sf); tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP; %% LS-Linear estimation with srsLTE @@ -227,12 +227,17 @@ if (length(SNR_values_db) == 1) tmp{Ntests+1}='Real'; legend(tmp) - xlabel('Sample') + xlabel('SNR (dB)') ylabel('Channel Gain') grid on; -% fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx))) -% fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx))) + fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx))) + fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx))) +<<<<<<< HEAD + +======= + +>>>>>>> master end end diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index 08722b3bd..665ff8047 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -116,7 +116,7 @@ for snr_idx=1:length(SNR_values) rmccFgOut.TotSubframes=1; % Perform channel estimation - [hest, nest] = lteDLChannelEstimate(rmccFgOut, cec, subframe_rx); + [hest, nest,estimates] = lteDLChannelEstimate2(rmccFgOut, cec, subframe_rx); [cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest); [trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ... @@ -156,7 +156,6 @@ if (length(SNR_values)>1) axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1]) else scatter(real(symbols{1}),imag(symbols{1})) - plot( fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 8c986ab75..b0a9c5fd6 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -583,13 +583,11 @@ int main(int argc, char **argv) { sfn++; if (sfn == 1024) { sfn = 0; - /* printf("\n"); ue_dl.pkt_errors = 0; ue_dl.pkts_total = 0; ue_dl.nof_detected = 0; nof_trials = 0; - */ } } diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index 7ac4444a0..beb7518d2 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -39,8 +39,6 @@ #include "srslte/utils/vector.h" #include "srslte/utils/convolution.h" -#define AVERAGE_SUBFRAME - //#define DEFAULT_FILTER_LEN 3 #ifdef DEFAULT_FILTER_LEN @@ -167,18 +165,7 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) /* Uses the difference between the averaged and non-averaged pilot estimates */ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) { - float norm = sqrt(2); -#ifdef AVERAGE_SUBFRAME - int nref=2*q->cell.nof_prb; -#else int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); - if (q->smooth_filter_len == 3) { - float a = q->smooth_filter[0]; - float norm3 = 6.143*a*a+0.04859*a-0.002774; - norm /= norm3; - } -#endif - /* Substract noisy pilot estimates */ srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref); @@ -192,6 +179,12 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) #endif /* Compute average power. Normalized for filter len 3 using matlab */ + float norm = 1; + if (q->smooth_filter_len == 3) { + float a = q->smooth_filter[0]; + float norm3 = 6.143*a*a+0.04859*a-0.002774; + norm /= norm3; + } float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); return power; } @@ -232,29 +225,19 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id) { - -#ifdef AVERAGE_SUBFRAME - // Interpolate symbol 0 in the frequency domain - uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0); - srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates, - &ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], - fidx_offset, SRSLTE_NRE/2-fidx_offset); - // All channel estimates in the subframe are the same - for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) { - memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t)); - } -#else - uint32_t l=0; + /* interpolate the symbols with references in the freq domain */ + uint32_t l; uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); - - // Interpolate in the frequency domain + + /* Interpolate in the frequency domain */ for (l=0;lcell, l, port_id, 0); srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l], &ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE], fidx_offset, SRSLTE_NRE/2-fidx_offset); } - // Interpolate in the time domain between symbols + + /* Now interpolate in the time domain between symbols */ if (SRSLTE_CP_ISNORM(q->cell.cp)) { if (nsymbols == 4) { srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3); @@ -278,7 +261,6 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4); } } -#endif } void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { @@ -311,17 +293,9 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; - memcpy(output, input, nref*sizeof(cf_t)); - for (int l=1;lsmooth_filter, &output[l*nref], nref, q->smooth_filter_len); -#endif } -#ifdef AVERAGE_SUBFRAME - srslte_vec_sc_prod_cfc(output, (float) 1.0/nsymbols, output, nref); -#endif } float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) { diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index a81004ef0..d04c5c303 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -44,7 +44,7 @@ cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_MAX_LOST 4 #define TRACK_FRAME_SIZE 32 #define FIND_NOF_AVG_FRAMES 4 -#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 +#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 5 #define DEFAULT_SFO_EMA_COEFF 0.1 cf_t dummy_offset_buffer[1024*1024]; @@ -358,6 +358,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { { INFO("Warning: Expected SF idx %d but got %d! (%d frames)\n", q->sf_idx, srslte_sync_get_sf_idx(&q->strack), q->frame_no_cnt); + q->sf_idx = srslte_sync_get_sf_idx(&q->strack); q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); @@ -381,19 +382,18 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { // Compute cumulative moving average time offset */ if (!frame_idx) { - if (q->sample_offset_correct_period) { - // Adjust RF sampling time based on the mean sampling offset - q->next_rf_sample_offset = (int) round(q->mean_sample_offset); - // Reset PSS averaging if correcting every a period longer than 1 - if (q->sample_offset_correct_period > 1) { - srslte_sync_reset(&q->strack); - } + // Adjust RF sampling time based on the mean sampling offset + q->next_rf_sample_offset = (int) round(q->mean_sample_offset); + + // Reset PSS averaging if correcting every a period longer than 1 + if (q->sample_offset_correct_period > 1) { + srslte_sync_reset(&q->strack); + } + // Compute SFO based on mean sample offset + if (q->sample_offset_correct_period) { q->mean_sample_offset /= q->sample_offset_correct_period; - } else { - q->next_rf_sample_offset = q->last_sample_offset; } - q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema); INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/5-sf, ema=%f, length=%d\n", From ded17137b0c3d6b58c752209736ed8663f088c89 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 00:49:31 +0200 Subject: [PATCH 010/111] fixed bugs from coverty analysis --- matlab/tests/equalizer_test.m | 17 ++---- matlab/tests/pdsch_decode_signal.m | 9 ++- matlab/tests/pdsch_equal.m | 11 +++- srslte/examples/pdsch_ue.c | 7 +-- srslte/include/srslte/dft/dft_precoding.h | 4 +- srslte/lib/ch_estimation/chest_dl.c | 1 + srslte/lib/ch_estimation/chest_ul.c | 6 +- srslte/lib/ch_estimation/refsignal_ul.c | 60 +++++++++++-------- srslte/lib/ch_estimation/test/chest_test_ul.c | 2 +- srslte/lib/fec/convcoder.c | 2 +- srslte/lib/fec/parity.c | 2 +- srslte/lib/phch/cqi.c | 17 ++++-- srslte/lib/phch/dci.c | 4 +- srslte/lib/phch/pdcch.c | 53 ++++++++-------- srslte/lib/phch/pdsch.c | 27 +++++---- srslte/lib/phch/prach.c | 28 ++++++--- srslte/lib/phch/pucch.c | 4 +- srslte/lib/phch/ra.c | 5 +- srslte/lib/phch/regs.c | 10 +++- srslte/lib/phch/sch.c | 4 +- srslte/lib/phch/test/pdsch_test_mex.c | 4 +- srslte/lib/rf/rf_blade_imp.c | 5 +- srslte/lib/rf/rf_uhd_imp.c | 2 + srslte/lib/sync/cfo.c | 2 +- srslte/lib/sync/pss.c | 2 + srslte/lib/sync/sss.c | 13 ++-- srslte/lib/sync/sync.c | 9 ++- srslte/lib/ue/ue_sync.c | 3 +- srslte/lib/ue/ue_ul.c | 4 +- 29 files changed, 189 insertions(+), 128 deletions(-) diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m index 1391d5e53..816a29957 100644 --- a/matlab/tests/equalizer_test.m +++ b/matlab/tests/equalizer_test.m @@ -6,11 +6,11 @@ clear plot_noise_estimation_only=false; -SNR_values_db=100;%linspace(20,35,8); -Nrealizations=1; +SNR_values_db=linspace(0,30,8); +Nrealizations=10; w1=0.1; -w2=0.3; +w2=0.2; enb.NDLRB = 6; % Number of resource blocks @@ -55,7 +55,7 @@ L = gridsize(2); % Number of OFDM symbols in one subframe Ports = gridsize(3); % Number of transmit antenna ports %% Allocate memory -Ntests=2; +Ntests=4; hest=cell(1,Ntests); tmpnoise=cell(1,Ntests); for i=1:Ntests @@ -181,8 +181,8 @@ for i=1:10 rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14); %% Channel Estimation with Matlab - [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i), hls(:,(1:4*P)+(i-1)*4*P)] = ... - lteDLChannelEstimate2(enb,cec,rxGrid_sf); + [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i)] = ... + lteDLChannelEstimate(enb,cec,rxGrid_sf); tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP; %% LS-Linear estimation with srsLTE @@ -233,11 +233,6 @@ if (length(SNR_values_db) == 1) fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx))) fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx))) -<<<<<<< HEAD - -======= - ->>>>>>> master end end diff --git a/matlab/tests/pdsch_decode_signal.m b/matlab/tests/pdsch_decode_signal.m index d376c5c3f..72b733eb5 100644 --- a/matlab/tests/pdsch_decode_signal.m +++ b/matlab/tests/pdsch_decode_signal.m @@ -1,6 +1,6 @@ -enb=struct('NCellID',137,'NDLRB',50,'NSubframe',8,'CFI',1,'CyclicPrefix','Normal','CellRefP',2,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); +enb=struct('NCellID',313,'NDLRB',75,'NSubframe',5,'CFI',1,'CyclicPrefix','Normal','CellRefP',2,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); -RNTI=5; +RNTI=65535; addpath('../../build/srslte/lib/phch/test') @@ -44,12 +44,15 @@ if ~isempty(dci) [sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits); - [dec2, data, pdschRx2, pdschSymbols2, e_bits] = srslte_pdsch(enb, pdsch, ... + [dec2, data, pdschRx2, pdschSymbols2, e_bits, ce] = srslte_pdsch(enb, pdsch, ... trblklen, ... subframe_rx); + subplot(2,1,1) scatter(real(pdschSymbols{1}),imag(pdschSymbols{1})) + subplot(2,1,2) + scatter(real(pdschSymbols2),imag(pdschSymbols2)) if crc == 0 fprintf('PDSCH Matlab OK.\n\n'); diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index 665ff8047..1ad1d86dc 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -116,7 +116,7 @@ for snr_idx=1:length(SNR_values) rmccFgOut.TotSubframes=1; % Perform channel estimation - [hest, nest,estimates] = lteDLChannelEstimate2(rmccFgOut, cec, subframe_rx); + [hest, nest] = lteDLChannelEstimate(rmccFgOut, cec, subframe_rx); [cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest); [trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ... @@ -127,7 +127,7 @@ for snr_idx=1:length(SNR_values) %% Same with srsLTE if (rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1) > 0) - [dec2, data, pdschRx, pdschSymbols2, cws2] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ... + [dec2, data, pdschRx, pdschSymbols2, cws2, ce] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ... rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1), ... subframe_rx); else @@ -155,7 +155,12 @@ if (length(SNR_values)>1) ylabel('BLER') axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1]) else - scatter(real(symbols{1}),imag(symbols{1})) + subplot(2,1,1) + scatter(real(pdschSymbols2),imag(pdschSymbols2)) + %plot(real(hest)) + subplot(2,1,2) + %plot(1:180,angle(ce(1:180)),1:180,angle(hest(:,1))) + plot(abs(ce-hest(:))) fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index b0a9c5fd6..f8cf033a9 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -512,13 +512,12 @@ int main(int argc, char **argv) { srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, rv); - /* - if (!n) { + if (n>0) { printf("Saving signal...\n"); - srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv); + srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti); exit(-1); } - */ + } if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); diff --git a/srslte/include/srslte/dft/dft_precoding.h b/srslte/include/srslte/dft/dft_precoding.h index eac79e6c8..e860e5b7b 100644 --- a/srslte/include/srslte/dft/dft_precoding.h +++ b/srslte/include/srslte/dft/dft_precoding.h @@ -44,8 +44,8 @@ typedef struct SRSLTE_API { uint32_t max_prb; - srslte_dft_plan_t dft_plan[SRSLTE_MAX_PRB]; - srslte_dft_plan_t idft_plan[SRSLTE_MAX_PRB]; + srslte_dft_plan_t dft_plan[SRSLTE_MAX_PRB+1]; + srslte_dft_plan_t idft_plan[SRSLTE_MAX_PRB+1]; }srslte_dft_precoding_t; diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index beb7518d2..541f98646 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -293,6 +293,7 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; + // Average in the frequency domain for (int l=0;lsmooth_filter, &output[l*nref], nref, q->smooth_filter_len); } diff --git a/srslte/lib/ch_estimation/chest_ul.c b/srslte/lib/ch_estimation/chest_ul.c index 4286854c0..c61e88c7d 100644 --- a/srslte/lib/ch_estimation/chest_ul.c +++ b/srslte/lib/ch_estimation/chest_ul.c @@ -91,11 +91,11 @@ int srslte_chest_ul_init(srslte_chest_ul_t *q, srslte_cell_t cell) q->smooth_filter_len = 3; srslte_chest_ul_set_smooth_filter3_coeff(q, 0.3333); - - } - q->dmrs_signal_configured = false; + q->dmrs_signal_configured = false; + } + ret = SRSLTE_SUCCESS; clean_exit: diff --git a/srslte/lib/ch_estimation/refsignal_ul.c b/srslte/lib/ch_estimation/refsignal_ul.c index 3c7dcfb02..30aa7da08 100644 --- a/srslte/lib/ch_estimation/refsignal_ul.c +++ b/srslte/lib/ch_estimation/refsignal_ul.c @@ -177,6 +177,8 @@ int srslte_refsignal_ul_init(srslte_refsignal_ul_t * q, srslte_cell_t cell) if (q != NULL && srslte_cell_isvalid(&cell)) { + ret = SRSLTE_ERROR; + bzero(q, sizeof(srslte_refsignal_ul_t)); q->cell = cell; @@ -275,11 +277,13 @@ static uint32_t get_q(uint32_t u, uint32_t v, uint32_t N_sz) { static void arg_r_uv_mprb(float *arg, uint32_t M_sc, uint32_t u, uint32_t v) { uint32_t N_sz = largest_prime_lower_than(M_sc); - float q = get_q(u,v,N_sz); - float n_sz = (float) N_sz; - for (uint32_t i = 0; i < M_sc; i++) { - float m = (float) (i%N_sz); - arg[i] = -M_PI * q * m * (m + 1) / n_sz; + if (N_sz > 0) { + float q = get_q(u,v,N_sz); + float n_sz = (float) N_sz; + for (uint32_t i = 0; i < M_sc; i++) { + float m = (float) (i%N_sz); + arg[i] = -M_PI * q * m * (m + 1) / n_sz; + } } } @@ -478,29 +482,35 @@ static uint32_t get_pucch_dmrs_symbol(uint32_t m, srslte_pucch_format_t format, case SRSLTE_PUCCH_FORMAT_1A: case SRSLTE_PUCCH_FORMAT_1B: if (SRSLTE_CP_ISNORM(cp)) { - if (m < 4) { + if (m < 3) { return pucch_dmrs_symbol_format1_cpnorm[m]; } } else { - if (m < 3) { + if (m < 2) { return pucch_dmrs_symbol_format1_cpext[m]; } } + break; case SRSLTE_PUCCH_FORMAT_2: if (SRSLTE_CP_ISNORM(cp)) { - if (m < 3) { + if (m < 2) { return pucch_dmrs_symbol_format2_cpnorm[m]; } } else { - if (m < 2) { + if (m < 1) { return pucch_dmrs_symbol_format2_cpext[m]; } } + break; case SRSLTE_PUCCH_FORMAT_2A: case SRSLTE_PUCCH_FORMAT_2B: - if (m < 3) { + if (m < 2) { return pucch_dmrs_symbol_format2_cpnorm[m]; } + break; + default: + fprintf(stderr, "Unsupported format %d\n", format); + return 0; } return 0; } @@ -759,21 +769,23 @@ uint32_t srslte_refsignal_srs_rb_L_cs(uint32_t bw_cfg, uint32_t nof_prb) { } uint32_t srs_Fb(srslte_refsignal_srs_cfg_t *cfg, uint32_t b, uint32_t nof_prb, uint32_t tti) { - uint32_t n_srs = tti/T_srs_table(cfg->I_srs); - uint32_t N_b = Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; - - uint32_t prod_1=1; - for (uint32_t bp=cfg->b_hop+1;bpbw_cfg]; - } - uint32_t prod_2 = prod_1*Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; - uint32_t Fb; - if ((N_b%2) == 0) { - Fb = (N_b/2)*((n_srs%prod_2)/prod_1)+((n_srs%prod_2)/prod_1/2); - } else { - Fb = (N_b/2)*(n_srs/prod_1); + uint32_t Fb = 0; + uint32_t T = T_srs_table(cfg->I_srs); + if (T) { + uint32_t n_srs = tti/T; + uint32_t N_b = Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; + + uint32_t prod_1=1; + for (uint32_t bp=cfg->b_hop+1;bpbw_cfg]; + } + uint32_t prod_2 = prod_1*Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; + if ((N_b%2) == 0) { + Fb = (N_b/2)*((n_srs%prod_2)/prod_1)+((n_srs%prod_2)/prod_1/2); + } else { + Fb = (N_b/2)*(n_srs/prod_1); + } } - return Fb; } diff --git a/srslte/lib/ch_estimation/test/chest_test_ul.c b/srslte/lib/ch_estimation/test/chest_test_ul.c index 93953dcbc..b3b2331da 100644 --- a/srslte/lib/ch_estimation/test/chest_test_ul.c +++ b/srslte/lib/ch_estimation/test/chest_test_ul.c @@ -178,7 +178,7 @@ int main(int argc, char **argv) { /* Generate random input */ bzero(input, sizeof(cf_t) * num_re); for (i=0;itail_biting ? frame_length : (frame_length + q->K - 1); if (q != NULL && input != NULL && output != NULL && frame_length > q->K + 1) { + uint32_t len = q->tail_biting ? frame_length : (frame_length + q->K - 1); if (q->tail_biting) { sr = 0; for (i=frame_length - q->K + 1; i>= 1; + ti >>= 1; } Partab[i] = cnt & 1; } diff --git a/srslte/lib/phch/cqi.c b/srslte/lib/phch/cqi.c index a19060961..df46152b0 100644 --- a/srslte/lib/phch/cqi.c +++ b/srslte/lib/phch/cqi.c @@ -129,12 +129,12 @@ bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) { } else if (I_cqi_pmi <= 1023) { return false; } - - if ((tti-N_offset)%N_p == 0) { - return true; - } else { - return false; + if (N_p) { + if ((tti-N_offset)%N_p == 0) { + return true; + } } + return false; } @@ -181,5 +181,10 @@ int srslte_cqi_hl_get_subband_size(int nof_prb) */ int srslte_cqi_hl_get_no_subbands(int nof_prb) { - return (int)ceil(nof_prb/(float)srslte_cqi_hl_get_subband_size(nof_prb)); + int hl_size = srslte_cqi_hl_get_subband_size(nof_prb); + if (hl_size > 0) { + return (int)ceil((float)nof_prb/hl_size); + } else { + return 0; + } } diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index b4262f857..276768c67 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -170,7 +170,7 @@ int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, uint32_t nof_prb, ret = SRSLTE_ERROR; bzero(ul_dci, sizeof(srslte_ra_ul_dci_t)); - bzero(grant, sizeof(srslte_ra_ul_dci_t)); + bzero(grant, sizeof(srslte_ra_ul_grant_t)); if (srslte_dci_msg_unpack_pusch(msg, ul_dci, nof_prb)) { return ret; @@ -392,7 +392,7 @@ uint32_t srslte_dci_format_sizeof(srslte_dci_format_t format, uint32_t nof_prb, } uint32_t srslte_dci_format_sizeof_lut(srslte_dci_format_t format, uint32_t nof_prb) { - if (nof_prb <= 100 && format < 11) { + if (nof_prb < 101 && format < 4) { return dci_sz_table[nof_prb][format]; } else { return 0; diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 8a67f8d0f..d0db566eb 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -275,33 +275,36 @@ int srslte_pdcch_dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t uint16_t p_bits, crc_res; uint8_t *x; - if (q != NULL && - data != NULL && - E <= q->max_bits && - nof_bits <= SRSLTE_DCI_MAX_BITS) - { - bzero(q->rm_f, sizeof(float)*3 * (SRSLTE_DCI_MAX_BITS + 16)); - - uint32_t coded_len = 3 * (nof_bits + 16); - - /* unrate matching */ - srslte_rm_conv_rx(e, E, q->rm_f, coded_len); - - /* viterbi decoder */ - srslte_viterbi_decode_f(&q->decoder, q->rm_f, data, nof_bits + 16); + if (q != NULL) { + if (data != NULL && + E <= q->max_bits && + nof_bits <= SRSLTE_DCI_MAX_BITS) + { + bzero(q->rm_f, sizeof(float)*3 * (SRSLTE_DCI_MAX_BITS + 16)); + + uint32_t coded_len = 3 * (nof_bits + 16); + + /* unrate matching */ + srslte_rm_conv_rx(e, E, q->rm_f, coded_len); + + /* viterbi decoder */ + srslte_viterbi_decode_f(&q->decoder, q->rm_f, data, nof_bits + 16); - x = &data[nof_bits]; - p_bits = (uint16_t) srslte_bit_pack(&x, 16); - crc_res = ((uint16_t) srslte_crc_checksum(&q->crc, data, nof_bits) & 0xffff); - - if (crc) { - *crc = p_bits ^ crc_res; + x = &data[nof_bits]; + p_bits = (uint16_t) srslte_bit_pack(&x, 16); + crc_res = ((uint16_t) srslte_crc_checksum(&q->crc, data, nof_bits) & 0xffff); + + if (crc) { + *crc = p_bits ^ crc_res; + } + + return SRSLTE_SUCCESS; + } else { + fprintf(stderr, "Invalid parameters: E: %d, max_bits: %d, nof_bits: %d\n", E, q->max_bits, nof_bits); + return SRSLTE_ERROR_INVALID_INPUTS; } - - return SRSLTE_SUCCESS; } else { - fprintf(stderr, "Invalid parameters: E: %d, max_bits: %d, nof_bits: %d\n", E, q->max_bits, nof_bits); - return SRSLTE_ERROR_INVALID_INPUTS; + return SRSLTE_ERROR_INVALID_INPUTS; } } @@ -525,7 +528,7 @@ int srslte_pdcch_encode(srslte_pdcch_t *q, srslte_dci_msg_t *msg, srslte_dci_loc ret = SRSLTE_ERROR; if (location.ncce + PDCCH_FORMAT_NOF_CCE(location.L) <= q->nof_cce && - msg->nof_bits < SRSLTE_DCI_MAX_BITS) + msg->nof_bits < SRSLTE_DCI_MAX_BITS - 16) { DEBUG("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", msg->nof_bits, e_bits, location.ncce, location.L, rnti); diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index 10b50bf43..174b8715a 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -316,19 +316,22 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { */ int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint32_t rvidx) { - - if (cfg && grant) { - memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); - } - if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) { - fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs); - return SRSLTE_ERROR; - } - srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits); - cfg->sf_idx = sf_idx; - cfg->rv = rvidx; + if (cfg) { + if (grant) { + memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); + } + if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) { + fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs); + return SRSLTE_ERROR; + } + srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits); + cfg->sf_idx = sf_idx; + cfg->rv = rvidx; - return SRSLTE_SUCCESS; + return SRSLTE_SUCCESS; + } else { + return SRSLTE_ERROR_INVALID_INPUTS; + } } diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index cf47babc5..39114ec8e 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -264,7 +264,7 @@ int srslte_prach_gen_seqs(srslte_prach_t *p) if(((p_*u) % p->N_zc) == 1) break; } - if(p_ >= 0 && p_ < p->N_zc/2){ + if(p_ < p->N_zc/2){ d_u = p_; }else{ d_u = p->N_zc - p_; @@ -342,8 +342,7 @@ int srslte_prach_init(srslte_prach_t *p, if(p != NULL && N_ifft_ul < 2049 && config_idx < 16 && - root_seq_index < MAX_ROOTS && - zero_corr_zone_config < 16) + root_seq_index < MAX_ROOTS) { uint32_t preamble_format = srslte_prach_get_preamble_format(config_idx); p->config_idx = config_idx; @@ -356,14 +355,29 @@ int srslte_prach_init(srslte_prach_t *p, // Determine N_zc and N_cs if(4 == preamble_format){ - p->N_zc = 139; - p->N_cs = prach_Ncs_format4[p->zczc]; + if (p->zczc < 7) { + p->N_zc = 139; + p->N_cs = prach_Ncs_format4[p->zczc]; + } else { + fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for format4\n", p->zczc); + return SRSLTE_ERROR; + } }else{ p->N_zc = 839; if(p->hs){ - p->N_cs = prach_Ncs_restricted[p->zczc]; + if (p->zczc < 15) { + p->N_cs = prach_Ncs_restricted[p->zczc]; + } else { + fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d for restricted set\n", p->zczc); + return SRSLTE_ERROR; + } }else{ - p->N_cs = prach_Ncs_unrestricted[p->zczc]; + if (p->zczc < 16) { + p->N_cs = prach_Ncs_unrestricted[p->zczc]; + } else { + fprintf(stderr, "Invalid zeroCorrelationZoneConfig=%d\n", p->zczc); + return SRSLTE_ERROR; + } } } diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index 9c55768e1..fb2419be0 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -136,7 +136,7 @@ uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t case SRSLTE_PUCCH_FORMAT_1: case SRSLTE_PUCCH_FORMAT_1A: case SRSLTE_PUCCH_FORMAT_1B: - if (m < 5) { + if (m < 4) { if (SRSLTE_CP_ISNORM(cp)) { return pucch_symbol_format1_cpnorm[m]; } else { @@ -147,7 +147,7 @@ uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t case SRSLTE_PUCCH_FORMAT_2: case SRSLTE_PUCCH_FORMAT_2A: case SRSLTE_PUCCH_FORMAT_2B: - if (m < 6) { + if (m < 5) { if (SRSLTE_CP_ISNORM(cp)) { return pucch_symbol_format2_cpnorm[m]; } else { diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index f005cd9aa..3ea7b9c30 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -595,7 +595,10 @@ int srslte_ra_tbs_to_table_idx(uint32_t tbs, uint32_t n_prb) { if (tbs <= tbs_table[0][n_prb-1]) { return 0; } - for (idx = 0; idx < 27; idx++) { + if (tbs >= tbs_table[26][n_prb-1]) { + return 27; + } + for (idx = 0; idx < 26; idx++) { if (tbs_table[idx][n_prb-1] <= tbs && tbs_table[idx+1][n_prb-1] >= tbs) { return idx+1; } diff --git a/srslte/lib/phch/regs.c b/srslte/lib/phch/regs.c index 9c2764866..8ada33e7f 100644 --- a/srslte/lib/phch/regs.c +++ b/srslte/lib/phch/regs.c @@ -247,6 +247,10 @@ int regs_phich_init(srslte_regs_t *h) { srslte_regs_reg_t **regs_phich[3]; int ret = SRSLTE_ERROR; + for (int i=0;i<3;i++) { + regs_phich[i] = NULL; + } + switch(h->phich_res) { case SRSLTE_PHICH_R_1_6: ng = (float) 1/6; @@ -768,8 +772,10 @@ int srslte_regs_init(srslte_regs_t *h, srslte_cell_t cell) { ret = SRSLTE_SUCCESS; } clean_and_exit: - if (ret != SRSLTE_SUCCESS) { - srslte_regs_free(h); + if (h) { + if (ret != SRSLTE_SUCCESS) { + srslte_regs_free(h); + } } return ret; } diff --git a/srslte/lib/phch/sch.c b/srslte/lib/phch/sch.c index 0550a492f..0655b5cd1 100644 --- a/srslte/lib/phch/sch.c +++ b/srslte/lib/phch/sch.c @@ -58,7 +58,7 @@ float beta_cqi_offset[16] = {-1.0, -1.0, 1.125, 1.25, 1.375, 1.625, 1.750, 2.0, float srslte_sch_beta_cqi(uint32_t I_cqi) { - if (I_cqi <= 16) { + if (I_cqi < 16) { return beta_cqi_offset[I_cqi]; } else { return 0; @@ -463,7 +463,7 @@ static int decode_tb(srslte_sch_t *q, par_tx = ((uint32_t) parity[0])<<16 | ((uint32_t) parity[1])<<8 | ((uint32_t) parity[2]); if (!par_rx) { - printf("Warning: Received all-zero transport block\n\n", 0); + printf("Warning: Received all-zero transport block\n\n"); } if (par_rx == par_tx && par_rx) { diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index 699fbb1f6..9deaef2cb 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -271,7 +271,9 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (nlhs >= 5) { mexutils_write_s(pdsch.e, &plhs[4], cfg.nbits.nof_bits, 1); } - + if (nlhs >= 6) { + mexutils_write_cf(ce[0], &plhs[5], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1); + } srslte_softbuffer_rx_free(&softbuffer); srslte_chest_dl_free(&chest); srslte_pdsch_free(&pdsch); diff --git a/srslte/lib/rf/rf_blade_imp.c b/srslte/lib/rf/rf_blade_imp.c index ee7185c88..af2916f65 100644 --- a/srslte/lib/rf/rf_blade_imp.c +++ b/srslte/lib/rf/rf_blade_imp.c @@ -478,10 +478,12 @@ int rf_blade_send_timed(void *h, if (is_end_of_burst) { meta.flags |= BLADERF_META_FLAG_TX_BURST_END; } + srslte_rf_error_t error; + bzero(&error, sizeof(srslte_rf_error_t)); + status = bladerf_sync_tx(handler->dev, handler->tx_buffer, nsamples, &meta, 2000); if (status == BLADERF_ERR_TIME_PAST) { if (blade_error_handler) { - srslte_rf_error_t error; error.type = SRSLTE_RF_ERROR_LATE; blade_error_handler(error); } else { @@ -492,7 +494,6 @@ int rf_blade_send_timed(void *h, return status; } else if (meta.status == BLADERF_META_STATUS_UNDERRUN) { if (blade_error_handler) { - srslte_rf_error_t error; error.type = SRSLTE_RF_ERROR_UNDERFLOW; blade_error_handler(error); } else { diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index 73e7af981..c0b4cc71a 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -62,6 +62,8 @@ srslte_rf_error_handler_t uhd_error_handler = NULL; void msg_handler(const char *msg) { srslte_rf_error_t error; + bzero(&error, sizeof(srslte_rf_error_t)); + if(0 == strcmp(msg, "O")) { error.type = SRSLTE_RF_ERROR_OVERFLOW; } else if(0 == strcmp(msg, "D")) { diff --git a/srslte/lib/sync/cfo.c b/srslte/lib/sync/cfo.c index 84997dc3f..f9304576a 100644 --- a/srslte/lib/sync/cfo.c +++ b/srslte/lib/sync/cfo.c @@ -62,7 +62,7 @@ void srslte_cfo_free(srslte_cfo_t *h) { if (h->cur_cexp) { free(h->cur_cexp); } - bzero(h, sizeof(cf_t)); + bzero(h, sizeof(srslte_cfo_t)); } void srslte_cfo_set_tol(srslte_cfo_t *h, float tol) { diff --git a/srslte/lib/sync/pss.c b/srslte/lib/sync/pss.c index 16efa4f1b..f7edbb353 100644 --- a/srslte/lib/sync/pss.c +++ b/srslte/lib/sync/pss.c @@ -94,6 +94,8 @@ int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size, if (q != NULL) { + ret = SRSLTE_ERROR; + uint32_t N_id_2; uint32_t buffer_size; bzero(q, sizeof(srslte_pss_synch_t)); diff --git a/srslte/lib/sync/sss.c b/srslte/lib/sync/sss.c index d64c0db1d..27818866a 100644 --- a/srslte/lib/sync/sss.c +++ b/srslte/lib/sync/sss.c @@ -139,14 +139,15 @@ uint32_t srslte_sss_synch_subframe(uint32_t m0, uint32_t m1) { /** Returns the N_id_1 value based on the m0 and m1 values */ int srslte_sss_synch_N_id_1(srslte_sss_synch_t *q, uint32_t m0, uint32_t m1) { - if (m0==m1 || m0 > 30 || m1 > 30) { - return SRSLTE_ERROR; - } - int N_id_1; + int N_id_1 = -1; if (m1 > m0) { - N_id_1 = q->N_id_1_table[m0][m1 - 1]; + if (m0 < 30 && m1 - 1 < 30) { + N_id_1 = q->N_id_1_table[m0][m1 - 1]; + } } else { - N_id_1 = q->N_id_1_table[m1][m0 - 1]; + if (m1 < 30 && m0 - 1 < 30) { + N_id_1 = q->N_id_1_table[m1][m0 - 1]; + } } return N_id_1; } diff --git a/srslte/lib/sync/sync.c b/srslte/lib/sync/sync.c index 41a4c5efc..df44ed77b 100644 --- a/srslte/lib/sync/sync.c +++ b/srslte/lib/sync/sync.c @@ -79,7 +79,7 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, } // Set a CFO tolerance of approx 100 Hz - srslte_cfo_set_tol(&q->cfocorr, 100/(15000*q->fft_size)); + srslte_cfo_set_tol(&q->cfocorr, 100.0/(15000.0*q->fft_size)); for (int i=0;i<2;i++) { q->cfo_i_corr[i] = srslte_vec_malloc(sizeof(cf_t)*q->frame_size); @@ -398,8 +398,11 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t srslte_sync_find_ret_t ret = SRSLTE_SYNC_ERROR; - if (q != NULL && - input != NULL && + if (!q) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (input != NULL && srslte_N_id_2_isvalid(q->N_id_2) && fft_size_isvalid(q->fft_size)) { diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index d04c5c303..7a9b7cb64 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -44,7 +44,7 @@ cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_MAX_LOST 4 #define TRACK_FRAME_SIZE 32 #define FIND_NOF_AVG_FRAMES 4 -#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 5 +#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 #define DEFAULT_SFO_EMA_COEFF 0.1 cf_t dummy_offset_buffer[1024*1024]; @@ -358,7 +358,6 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { { INFO("Warning: Expected SF idx %d but got %d! (%d frames)\n", q->sf_idx, srslte_sync_get_sf_idx(&q->strack), q->frame_no_cnt); - q->sf_idx = srslte_sync_get_sf_idx(&q->strack); q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index 1e5d7a51f..1d8a371e4 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -434,12 +434,14 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, { int ret = SRSLTE_ERROR_INVALID_INPUTS; - bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); if (q != NULL && softbuffer != NULL && output_signal != NULL) { + + bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); + if (srslte_pusch_uci_encode_rnti(&q->pusch, &q->pusch_cfg, softbuffer, data, uci_data, rnti, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); return ret; From f61448e4ea062ed82bbb508e6b3efc267fc2bcc0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 15:22:03 +0200 Subject: [PATCH 011/111] changed ue_dl API dci_msg order --- srslte/include/srslte/ue/ue_dl.h | 12 ++++++------ srslte/lib/ue/ue_dl.c | 30 +++++++++++++++--------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 07bcd9470..f31056ee4 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -117,23 +117,23 @@ SRSLTE_API int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, uint32_t rvidx); SRSLTE_API int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, - srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, - uint16_t rnti); + uint16_t rnti, + srslte_dci_msg_t *dci_msg); SRSLTE_API int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, - srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, - uint16_t rnti); + uint16_t rnti, + srslte_dci_msg_t *dci_msg); SRSLTE_API int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, - srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, - srslte_rnti_type_t rnti_type); + srslte_rnti_type_t rnti_type, + srslte_dci_msg_t *dci_msg); SRSLTE_API uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q); diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 7e1b97bef..87b2e56e2 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -296,7 +296,7 @@ typedef struct { uint32_t nof_locations; } dci_blind_search_t; -static int dci_blind_search(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, dci_blind_search_t *search_space, uint16_t rnti) +static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, uint16_t rnti, srslte_dci_msg_t *dci_msg) { int ret = SRSLTE_ERROR; uint16_t crc_rem = 0; @@ -329,7 +329,7 @@ static int dci_blind_search(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, dci_bl return ret; } -int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) +int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, srslte_dci_msg_t *dci_msg) { if (rnti) { /* Do not search if an UL DCI is already pending */ @@ -343,14 +343,14 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 dci_blind_search_t search_space; search_space.format = SRSLTE_DCI_FORMAT0; search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); - return dci_blind_search(q, dci_msg, &search_space, rnti); + return dci_blind_search(q, &search_space, rnti, dci_msg); } else { return 0; } } -int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) +int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, srslte_dci_msg_t *dci_msg) { srslte_rnti_type_t rnti_type; if (rnti == SRSLTE_SIRNTI) { @@ -362,11 +362,11 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 } else { rnti_type = SRSLTE_RNTI_USER; } - return srslte_ue_dl_find_dl_dci_type(q, dci_msg, cfi, sf_idx, rnti, rnti_type); + return srslte_ue_dl_find_dl_dci_type(q, cfi, sf_idx, rnti, rnti_type, dci_msg); } // Blind search for SI/P/RA-RNTI -static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint16_t rnti) +static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, uint32_t cfi, uint16_t rnti, srslte_dci_msg_t *dci_msg) { int ret = 0; // Configure and run DCI blind search @@ -374,7 +374,7 @@ static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_m search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, q->cfi, rnti); for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); - return dci_blind_search(q, dci_msg, &search_space, rnti); + return dci_blind_search(q, &search_space, rnti, dci_msg); } -int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, - uint16_t rnti, srslte_rnti_type_t rnti_type) +int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, + uint16_t rnti, srslte_rnti_type_t rnti_type, srslte_dci_msg_t *dci_msg) { if (rnti_type == SRSLTE_RNTI_SI || rnti_type == SRSLTE_RNTI_PCH || rnti_type == SRSLTE_RNTI_RAR) { - return find_dl_dci_type_siprarnti(q, dci_msg, cfi, rnti); + return find_dl_dci_type_siprarnti(q, cfi, rnti, dci_msg); } else { - return find_dl_dci_type_crnti(q, dci_msg, cfi, sf_idx, rnti); + return find_dl_dci_type_crnti(q, cfi, sf_idx, rnti, dci_msg); } } @@ -427,7 +427,7 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u return SRSLTE_ERROR; } - int found_dci = srslte_ue_dl_find_dl_dci(q, &dci_msg, q->cfi, sf_idx, rnti); + int found_dci = srslte_ue_dl_find_dl_dci(q, q->cfi, sf_idx, rnti, &dci_msg); if (found_dci == 1) { if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) { From 3941589cc567e0e9ddf3d47a5e7febaf4e620ac3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 15:27:54 +0200 Subject: [PATCH 012/111] added printfs --- srslte/examples/pdsch_ue.c | 5 +++-- srslte/lib/ue/ue_dl.c | 17 ++++++++++++----- srslte/lib/ue/ue_sync.c | 5 +++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index f8cf033a9..dd38541f8 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -511,13 +511,14 @@ int main(int argc, char **argv) { n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, rv); - + + /* if (n>0) { printf("Saving signal...\n"); srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti); exit(-1); } - + */ } if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 87b2e56e2..4ddc35b8c 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -304,23 +304,27 @@ static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, ret = 0; int i=0; do { - if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &search_space->loc[i], search_space->format, &crc_rem)) { + printf("Searching format %s in %d,%d\n", + srslte_dci_format_string(search_space->format), search_space->loc[i].ncce, search_space->loc[i].L); + if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &search_space->loc[i], search_space->format, &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } if (crc_rem == rnti) { - + printf("Found crc_rem=0x%x, format=%d\n", rnti, dci_msg->format); // If searching for Format1A but found Format0 save it for later if (dci_msg->format == SRSLTE_DCI_FORMAT0 && search_space->format == SRSLTE_DCI_FORMAT1A) { q->pending_ul_dci_rnti = crc_rem; memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); - + printf("Saved UL for later\n"); // Else if we found it, save location and leave - } else if (dci_msg->format != search_space->format) + } else if (dci_msg->format == search_space->format) { ret = 1; memcpy(&q->last_location, &search_space->loc[i], sizeof(srslte_dci_location_t)); + } else { + printf("msg_format=%d, search_format=%d\n", dci_msg->format, search_space->format); } } i++; @@ -343,8 +347,8 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, u dci_blind_search_t search_space; search_space.format = SRSLTE_DCI_FORMAT0; search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + printf("Searching UL C-RNTI in %d ue locations\n", search_space.nof_locations); return dci_blind_search(q, &search_space, rnti, dci_msg); - } else { return 0; } @@ -372,6 +376,7 @@ static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, uint32_t cfi, uint16_t // Configure and run DCI blind search dci_blind_search_t search_space; search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); + printf("Searching SI/P/RA-RNTI in %d common locations, %d formats\n", search_space.nof_locations, nof_common_formats); for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, q->cfi, rnti); + printf("Searching DL C-RNTI in %d ue locations, %d formats\n", search_space.nof_locations, nof_ue_formats); for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); + printf("Searching DL C-RNTI in %d ue locations, format 1A\n", search_space.nof_locations, nof_ue_formats); return dci_blind_search(q, &search_space, rnti, dci_msg); } diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 7a9b7cb64..aef15e342 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -395,11 +395,12 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { } q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema); - INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/5-sf, ema=%f, length=%d\n", + if (q->next_rf_sample_offset) { + INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/5-sf, ema=%f, length=%d\n", q->next_rf_sample_offset, q->mean_sample_offset, srslte_ue_sync_get_sfo(q), q->mean_sfo, q->sfo_ema, q->sample_offset_correct_period); - + } q->mean_sample_offset = 0; } From 52d45d001c00fbbd54da4068bcbe62ac434e1db9 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Tue, 30 Aug 2016 15:01:37 +0100 Subject: [PATCH 013/111] Fix for build without RF dependencies --- srslte/lib/CMakeLists.txt | 61 ++++++++++++++------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/srslte/lib/CMakeLists.txt b/srslte/lib/CMakeLists.txt index 355720a8c..1eec0bf40 100644 --- a/srslte/lib/CMakeLists.txt +++ b/srslte/lib/CMakeLists.txt @@ -35,56 +35,39 @@ add_subdirectory(resampling) add_subdirectory(scrambling) add_subdirectory(ue) -add_library(srslte SHARED version.c - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ +set(srslte_srcs version.c + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ ) +if(RF_FOUND) + list(APPEND srslte_srcs $) +endif(RF_FOUND) -if(NOT DisableMEX) - add_library(srslte_static STATIC version.c - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - ) -endif(NOT DisableMEX) +add_library(srslte SHARED ${srslte_srcs}) target_link_libraries(srslte pthread m ${FFTW3F_LIBRARIES}) set_target_properties(srslte PROPERTIES VERSION ${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}) if(NOT DisableMEX) + add_library(srslte_static STATIC ${srslte_srcs}) target_link_libraries(srslte_static ${FFTW3F_LIBRARIES}) endif(NOT DisableMEX) - - + if(RF_FOUND) if(UHD_FOUND) target_link_libraries(srslte ${UHD_LIBRARIES}) From f605400bed442d6d305785e2228e07dd21df7787 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 16:56:12 +0200 Subject: [PATCH 014/111] fixed issues in new dci search --- srslte/examples/pdsch_ue.c | 2 +- srslte/include/srslte/ue/ue_dl.h | 4 +- srslte/lib/phch/pdcch.c | 14 +++--- srslte/lib/ue/ue_dl.c | 74 ++++++++++++++++++-------------- 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index dd38541f8..100123fde 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -536,7 +536,7 @@ int main(int argc, char **argv) { memcmp(&ue_dl.dl_dci.type2_alloc, &old_dl_dci.type2_alloc, sizeof(srslte_ra_type2_t))) { memcpy(&old_dl_dci, &ue_dl.dl_dci, sizeof(srslte_ra_dl_dci_t)); - fflush(stdout);printf("\nCFI:\t%d\n", ue_dl.cfi); + fflush(stdout); printf("Format: %s\n", srslte_dci_format_string(ue_dl.dci_format)); srslte_ra_pdsch_fprint(stdout, &old_dl_dci, cell.nof_prb); srslte_ra_dl_grant_fprint(stdout, &ue_dl.pdsch_cfg.grant); diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index f31056ee4..d248ad288 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -80,7 +80,6 @@ typedef struct SRSLTE_API { cf_t *ce[SRSLTE_MAX_PORTS]; srslte_dci_format_t dci_format; - uint32_t cfi; uint64_t pkt_errors; uint64_t pkts_total; uint64_t nof_detected; @@ -172,7 +171,8 @@ SRSLTE_API void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuffer, uint32_t tti, uint32_t rv_idx, - uint16_t rnti); + uint16_t rnti, + uint32_t cfi); #endif diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index d0db566eb..2ac4ba115 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -322,14 +322,15 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && msg != NULL && - srslte_dci_location_isvalid(location) && - crc_rem != NULL) + srslte_dci_location_isvalid(location)) { if (location->ncce * 72 + PDCCH_FORMAT_NOF_BITS(location->L) > q->nof_cce*72) { fprintf(stderr, "Invalid location: nCCE: %d, L: %d, NofCCE: %d\n", location->ncce, location->L, q->nof_cce); } else { + ret = SRSLTE_SUCCESS; + uint32_t nof_bits = srslte_dci_format_sizeof_lut(format, q->cell.nof_prb); uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L); @@ -349,17 +350,20 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, } else { msg->format = format; } - } + } else { + fprintf(stderr, "Error calling pdcch_dci_decode\n"); + } if (crc_rem) { DEBUG("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x\n", location->ncce, location->L, srslte_dci_format_string(format), nof_bits, mean, *crc_rem); } } else { DEBUG("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f\n", - location->ncce, location->L, nof_bits, mean); - ret = SRSLTE_SUCCESS; + location->ncce, location->L, nof_bits, mean); } } + } else { + fprintf(stderr, "Invalid parameters, location=%d,%d\n", location->ncce, location->L); } return ret; } diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 4ddc35b8c..810397b78 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -303,32 +303,29 @@ static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, if (rnti) { ret = 0; int i=0; - do { - printf("Searching format %s in %d,%d\n", + while (!ret && i < search_space->nof_locations) { + INFO("Searching format %s in %d,%d\n", srslte_dci_format_string(search_space->format), search_space->loc[i].ncce, search_space->loc[i].L); if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &search_space->loc[i], search_space->format, &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } if (crc_rem == rnti) { - printf("Found crc_rem=0x%x, format=%d\n", rnti, dci_msg->format); // If searching for Format1A but found Format0 save it for later if (dci_msg->format == SRSLTE_DCI_FORMAT0 && search_space->format == SRSLTE_DCI_FORMAT1A) { q->pending_ul_dci_rnti = crc_rem; - memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); - printf("Saved UL for later\n"); + memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); // Else if we found it, save location and leave - } else if (dci_msg->format == search_space->format) - { + } else if (dci_msg->format == search_space->format) { ret = 1; memcpy(&q->last_location, &search_space->loc[i], sizeof(srslte_dci_location_t)); - } else { - printf("msg_format=%d, search_format=%d\n", dci_msg->format, search_space->format); - } + } } i++; - } while (!ret && i < search_space->nof_locations); + } + } else { + fprintf(stderr, "RNTI not specified\n"); } return ret; } @@ -338,7 +335,7 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, u if (rnti) { /* Do not search if an UL DCI is already pending */ if (q->pending_ul_dci_rnti == rnti) { - q->pending_ul_dci_rnti = 0; + q->pending_ul_dci_rnti = 0; memcpy(dci_msg, &q->pending_ul_dci_msg, sizeof(srslte_dci_msg_t)); return 1; } @@ -347,7 +344,7 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, u dci_blind_search_t search_space; search_space.format = SRSLTE_DCI_FORMAT0; search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); - printf("Searching UL C-RNTI in %d ue locations\n", search_space.nof_locations); + INFO("Searching UL C-RNTI in %d ue locations\n", search_space.nof_locations); return dci_blind_search(q, &search_space, rnti, dci_msg); } else { return 0; @@ -375,36 +372,45 @@ static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, uint32_t cfi, uint16_t int ret = 0; // Configure and run DCI blind search dci_blind_search_t search_space; - search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); - printf("Searching SI/P/RA-RNTI in %d common locations, %d formats\n", search_space.nof_locations, nof_common_formats); - for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_COM, cfi); + INFO("Searching SI/P/RA-RNTI in %d common locations, %d formats\n", search_space.nof_locations, nof_common_formats); + // Search for RNTI only if there is room for the common search space + if (search_space.nof_locations > 0) { + for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, q->cfi, rnti); - printf("Searching DL C-RNTI in %d ue locations, %d formats\n", search_space.nof_locations, nof_ue_formats); + search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + INFO("Searching DL C-RNTI in %d ue locations, %d formats\n", search_space.nof_locations, nof_ue_formats); for (int f=0;fpdcch, search_space.loc, MAX_CANDIDATES_COM, q->cfi); - printf("Searching DL C-RNTI in %d ue locations, format 1A\n", search_space.nof_locations, nof_ue_formats); - return dci_blind_search(q, &search_space, rnti, dci_msg); + search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, cfi); + // Search for RNTI only if there is room for the common search space + if (search_space.nof_locations > 0) { + INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", search_space.nof_locations, nof_ue_formats); + return dci_blind_search(q, &search_space, rnti, dci_msg); + } + return SRSLTE_SUCCESS; } int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, @@ -424,17 +430,19 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u srslte_ra_dl_dci_t dci_unpacked; srslte_ra_dl_grant_t grant; int ret = SRSLTE_ERROR; + uint32_t cfi; + - if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &q->cfi)) < 0) { + if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &cfi)) < 0) { return ret; } - if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, q->cfi)) { + if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } - int found_dci = srslte_ue_dl_find_dl_dci(q, q->cfi, sf_idx, rnti, &dci_msg); + int found_dci = srslte_ue_dl_find_dl_dci(q, cfi, sf_idx, rnti, &dci_msg); if (found_dci == 1) { if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) { @@ -442,7 +450,7 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u return SRSLTE_ERROR; } - ret = srslte_ue_dl_decode_rnti_rv_packet(q, &grant, data, q->cfi, sf_idx, rnti, rvidx); + ret = srslte_ue_dl_decode_rnti_rv_packet(q, &grant, data, cfi, sf_idx, rnti, rvidx); } if (found_dci == 1 && ret == SRSLTE_SUCCESS) { @@ -474,7 +482,7 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr } } -void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuffer, uint32_t tti, uint32_t rv_idx, uint16_t rnti) { +void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuffer, uint32_t tti, uint32_t rv_idx, uint16_t rnti, uint32_t cfi) { srslte_vec_save_file("sf_symbols", q->sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); printf("%d samples\n", SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); srslte_vec_save_file("ce0", q->ce[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); @@ -502,7 +510,7 @@ void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuf snprintf(tmpstr,64,"rmout_%d.dat",i); srslte_vec_save_file(tmpstr, softbuffer->buffer_f[i], (3*cb_len+12)*sizeof(int16_t)); } - printf("Saved files for tti=%d, sf=%d, cfi=%d, mcs=%d, rv=%d, rnti=%d\n", tti, tti%10, q->cfi, + printf("Saved files for tti=%d, sf=%d, cfi=%d, mcs=%d, rv=%d, rnti=%d\n", tti, tti%10, cfi, q->pdsch_cfg.grant.mcs.idx, rv_idx, rnti); } From 9b01555626bcc8b579b7eaa55e37914db1d0c6fc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 19:22:37 +0200 Subject: [PATCH 015/111] Fixed MAX_CANDIDATES --- srslte/lib/enb/enb_ul.c | 2 +- srslte/lib/phch/test/pdcch_file_test.c | 2 +- srslte/lib/phch/test/pdcch_test_mex.c | 2 +- srslte/lib/phch/test/pdsch_pdcch_file_test.c | 2 +- srslte/lib/ue/ue_dl.c | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index e3732b8ce..01940f5b0 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -37,7 +37,7 @@ #define CURRENT_SLOTLEN_RE SRSLTE_SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp) #define CURRENT_SFLEN_RE SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp) -#define MAX_CANDIDATES 64 +#define MAX_CANDIDATES 16 int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, srslte_prach_cfg_t *prach_cfg, diff --git a/srslte/lib/phch/test/pdcch_file_test.c b/srslte/lib/phch/test/pdcch_file_test.c index 9f6af1afd..a53dd7afc 100644 --- a/srslte/lib/phch/test/pdcch_file_test.c +++ b/srslte/lib/phch/test/pdcch_file_test.c @@ -34,7 +34,7 @@ char *input_file_name = NULL; -#define MAX_CANDIDATES 64 +#define MAX_CANDIDATES 16 srslte_cell_t cell = { 6, // cell.cell.cell.nof_prb diff --git a/srslte/lib/phch/test/pdcch_test_mex.c b/srslte/lib/phch/test/pdcch_test_mex.c index 754050b53..e2728be2c 100644 --- a/srslte/lib/phch/test/pdcch_test_mex.c +++ b/srslte/lib/phch/test/pdcch_test_mex.c @@ -36,7 +36,7 @@ #define INPUT prhs[2] #define NOF_INPUTS 3 -#define MAX_CANDIDATES 64 +#define MAX_CANDIDATES 16 srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FORMAT1}; // SRSLTE_DCI_FORMAT1B should go here also diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index 5a8a8e766..9ee136c86 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -32,7 +32,7 @@ #include "srslte/srslte.h" -#define MAX_CANDIDATES 64 +#define MAX_CANDIDATES 16 char *input_file_name = NULL; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 810397b78..e527f0d49 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -287,8 +287,8 @@ uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { return q->last_n_cce; } -#define MAX_CANDIDATES_UE 6 // From 36.213 Table 9.1.1-1 -#define MAX_CANDIDATES_COM 4 // From 36.213 Table 9.1.1-1 +#define MAX_CANDIDATES_UE 16 // From 36.213 Table 9.1.1-1 +#define MAX_CANDIDATES_COM 6 // From 36.213 Table 9.1.1-1 #define MAX_CANDIDATES (MAX_CANDIDATES_UE + MAX_CANDIDATES_COM) typedef struct { srslte_dci_format_t format; From d80146e657efe1d35fe5447c03f3b1aa0fdd352a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 19:49:50 +0200 Subject: [PATCH 016/111] Fixed blind search --- srslte/lib/phch/pdcch.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 2ac4ba115..5881e2b17 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -187,7 +187,7 @@ uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t int l; // this must be int because of the for(;;--) loop uint32_t i, k, L, m; uint32_t Yk, ncce; - const int S[4] = { 6, 12, 8, 16 }; + const int M[4] = { 6, 6, 2, 2 }; // Compute Yk for this subframe Yk = rnti; @@ -200,7 +200,7 @@ uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t for (l = 3; l >= 0; l--) { L = (1 << l); // For all possible ncce offset - for (i = 0; i < SRSLTE_MIN(nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { + for (i = 0; i < M[l]; i++) { ncce = L * ((Yk + i) % (nof_cce / L)); if (k < max_candidates && ncce + PDCCH_FORMAT_NOF_CCE(l) <= nof_cce) @@ -239,14 +239,18 @@ uint32_t srslte_pdcch_common_locations(srslte_pdcch_t *q, srslte_dci_location_t uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_location_t *c, uint32_t max_candidates) { uint32_t i, l, L, k; - + const int M[4] = { 0, 0, 4, 2 }; + k = 0; for (l = 3; l > 1; l--) { L = (1 << l); - for (i = 0; i < SRSLTE_MIN(nof_cce, 16) / (L); i++) { - if (k < max_candidates) { + for (i = 0; i < M[l]; i++) { + uint32_t ncce = L * (i % (nof_cce / L)); + if (k < max_candidates && + ncce + PDCCH_FORMAT_NOF_CCE(l) <= nof_cce) + { c[k].L = l; - c[k].ncce = (L) * (i % (nof_cce / (L))); + c[k].ncce = ncce; DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n", k, c[k].ncce, c[k].L); k++; From 64f90bbe4c20e7f8232e72ada48e5d390aa4703a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 30 Aug 2016 23:52:52 +0200 Subject: [PATCH 017/111] Fixed test failing --- srslte/lib/phch/pdcch.c | 46 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 5881e2b17..ed0b041f6 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -201,20 +201,21 @@ uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t L = (1 << l); // For all possible ncce offset for (i = 0; i < M[l]; i++) { - ncce = L * ((Yk + i) % (nof_cce / L)); - if (k < max_candidates && - ncce + PDCCH_FORMAT_NOF_CCE(l) <= 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++; - } + if (nof_cce > L) { + ncce = L * ((Yk + i) % (nof_cce / L)); + if (k < max_candidates && ncce + L <= 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++; + } + } } - } + } DEBUG("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x\n", k, rnti); @@ -245,15 +246,16 @@ uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_locatio for (l = 3; l > 1; l--) { L = (1 << l); for (i = 0; i < M[l]; i++) { - uint32_t ncce = L * (i % (nof_cce / L)); - if (k < max_candidates && - ncce + PDCCH_FORMAT_NOF_CCE(l) <= nof_cce) - { - c[k].L = l; - c[k].ncce = ncce; - DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n", - k, c[k].ncce, c[k].L); - k++; + if (nof_cce > L) { + uint32_t ncce = L * (i % (nof_cce / L)); + if (k < max_candidates && ncce + L <= nof_cce) + { + c[k].L = l; + c[k].ncce = ncce; + DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n", + k, c[k].ncce, c[k].L); + k++; + } } } } From 39fde1b3426bd9f57ce4ec32c0faa4647cde55ec Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 31 Aug 2016 14:01:38 +0100 Subject: [PATCH 018/111] Added coverity badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e6597fdde..c09590093 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ srsLTE ======== +[![Coverity Scan Build Status](https://scan.coverity.com/projects/10045/badge.svg)](https://scan.coverity.com/projects/10045) + srsLTE is a free and open-source LTE library for SDR UE and eNodeB developed by SRS (www.softwareradiosystems.com). The library is highly modular with minimum inter-module or external dependencies. It is entirely written in C and, if available in the system, uses the acceleration library VOLK distributed in GNURadio. **srsLTE is used by srsUE, a full stack (PHY to IP) implementation of an LTE UE. srsUE is available at https://github.com/srslte/srsue** From 16454f5eb17cbe34685089a618c9b7818f5f27cb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 31 Aug 2016 16:58:39 +0200 Subject: [PATCH 019/111] Added guard carriers to pdsch_ue plot --- srslte/examples/pdsch_ue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 100123fde..8b6cf53a6 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -702,14 +702,16 @@ void *plot_thread_run(void *arg) { tmp_plot[i] = -80; } } + int sz = srslte_symbol_sz(ue_dl.cell.nof_prb); + bzero(tmp_plot2, sizeof(float)*sz); + int g = (sz - 12*ue_dl.cell.nof_prb)/2; for (i = 0; i < 12*ue_dl.cell.nof_prb; i++) { - tmp_plot2[i] = 20 * log10f(cabsf(ue_dl.ce[0][i])); - if (isinf(tmp_plot2[i])) { - tmp_plot2[i] = -80; + tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][i])); + if (isinf(tmp_plot2[g+i])) { + tmp_plot2[g+i] = -80; } } - - plot_real_setNewData(&pce, tmp_plot2, i); + plot_real_setNewData(&pce, tmp_plot2, sz); if (!prog_args.input_file_name) { if (plot_track) { From 66ac734c514db163c41bab9db81b6f732fd4d68f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 31 Aug 2016 19:07:20 +0200 Subject: [PATCH 020/111] added support for 2 tb in format2 --- srslte/include/srslte/phch/ra.h | 6 ++- srslte/lib/phch/dci.c | 11 ++++- srslte/lib/phch/ra.c | 79 +++++++++++++++++++-------------- 3 files changed, 61 insertions(+), 35 deletions(-) diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 0b51331f3..b32f759b2 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -102,8 +102,10 @@ typedef struct SRSLTE_API { typedef struct SRSLTE_API { bool prb_idx[2][SRSLTE_MAX_PRB]; uint32_t nof_prb; - uint32_t Qm; + uint32_t Qm; + uint32_t Qm2; srslte_ra_mcs_t mcs; + srslte_ra_mcs_t mcs2; } srslte_ra_dl_grant_t; /** Unpacked DCI message for DL grant */ @@ -130,6 +132,8 @@ typedef struct SRSLTE_API { bool pconf; bool power_offset; + uint32_t nof_tb; + bool dci_is_1a; bool dci_is_1c; } srslte_ra_dl_dci_t; diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index e6587c629..3203fc48d 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -627,6 +627,7 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t // TPC not implemented + data->nof_tb = 1; return SRSLTE_SUCCESS; } @@ -812,6 +813,8 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 y++; // MSB of TPC is reserved data->type2_alloc.n_prb1a = *y++; // LSB indicates N_prb_1a for TBS } + + data->nof_tb = 1; return SRSLTE_SUCCESS; } @@ -856,7 +859,8 @@ int dci_format1B_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ data->pinfo = srslte_bit_pack(&y, tpmi_bits(nof_ports)); data->pconf = *y++ ? true : false; - + + data->nof_tb = 1; return SRSLTE_SUCCESS; } @@ -948,6 +952,8 @@ int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 data->rv_idx = -1; // Get RV later msg->nof_bits = (y - msg->data); + + data->nof_tb = 1; return SRSLTE_SUCCESS; } @@ -993,6 +999,7 @@ int dci_format1D_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ data->pinfo = srslte_bit_pack(&y, tpmi_bits(nof_ports)); data->power_offset = *y++ ? true : false; + data->nof_tb = 1; return SRSLTE_SUCCESS; } @@ -1060,6 +1067,8 @@ int dci_format2AB_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 data->pinfo = srslte_bit_pack(&y, precoding_bits_f2a(nof_ports)); } + data->nof_tb = 2; + return SRSLTE_SUCCESS; } diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index 3ea7b9c30..dc12b7d4d 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -380,6 +380,40 @@ static int dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_dl_ return SRSLTE_SUCCESS; } +static int dl_fill_ra_mcs(srslte_ra_mcs_t *mcs, uint32_t nprb) { + uint32_t i_tbs = 0; + int tbs = -1; + if (mcs->idx < 10) { + mcs->mod = SRSLTE_MOD_QPSK; + i_tbs = mcs->idx; + } else if (mcs->idx < 17) { + mcs->mod = SRSLTE_MOD_16QAM; + i_tbs = mcs->idx-1; + } else if (mcs->idx < 29) { + mcs->mod = SRSLTE_MOD_64QAM; + i_tbs = mcs->idx-2; + } else if (mcs->idx == 29) { + mcs->mod = SRSLTE_MOD_QPSK; + tbs = 0; + i_tbs = 0; + } else if (mcs->idx == 30) { + mcs->mod = SRSLTE_MOD_16QAM; + tbs = 0; + i_tbs = 0; + } else if (mcs->idx == 31) { + mcs->mod = SRSLTE_MOD_64QAM; + tbs = 0; + i_tbs = 0; + } + if (tbs == -1) { + tbs = srslte_ra_tbs_from_idx(i_tbs, nprb); + if (tbs >= 0) { + mcs->tbs = tbs; + } + } + return tbs; +} + /* Modulation order and transport block size determination 7.1.7 in 36.213 */ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, bool crc_is_crnti) { uint32_t n_prb=0; @@ -397,40 +431,23 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr } } grant->mcs.mod = SRSLTE_MOD_QPSK; + grant->mcs.tbs = (uint32_t) tbs; } else { - tbs = -1; n_prb = grant->nof_prb; - if (dci->mcs_idx < 10) { - grant->mcs.mod = SRSLTE_MOD_QPSK; - i_tbs = dci->mcs_idx; - } else if (dci->mcs_idx < 17) { - grant->mcs.mod = SRSLTE_MOD_16QAM; - i_tbs = dci->mcs_idx-1; - } else if (dci->mcs_idx < 29) { - grant->mcs.mod = SRSLTE_MOD_64QAM; - i_tbs = dci->mcs_idx-2; - } else if (dci->mcs_idx == 29) { - grant->mcs.mod = SRSLTE_MOD_QPSK; - tbs = 0; - i_tbs = 0; - } else if (dci->mcs_idx == 30) { - grant->mcs.mod = SRSLTE_MOD_16QAM; - tbs = 0; - i_tbs = 0; - } else if (dci->mcs_idx == 31) { - grant->mcs.mod = SRSLTE_MOD_64QAM; - tbs = 0; - i_tbs = 0; - } - if (tbs == -1) { - tbs = srslte_ra_tbs_from_idx(i_tbs, n_prb); + grant->mcs.idx = dci->mcs_idx; + tbs = dl_fill_ra_mcs(&grant->mcs, n_prb); + if (dci->nof_tb == 2) { + grant->mcs2.idx = dci->mcs_idx_1; + tbs = dl_fill_ra_mcs(&grant->mcs2, n_prb); } } - + grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); + if (dci->nof_tb == 2) { + grant->Qm2 = srslte_mod_bits_x_symbol(grant->mcs2.mod); + } if (tbs < 0) { return SRSLTE_ERROR; - } else { - grant->mcs.tbs = (uint32_t) tbs; + } else { return SRSLTE_SUCCESS; } } @@ -455,11 +472,7 @@ int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, // Compute PRB allocation if (!dl_dci_to_grant_prb_allocation(dci, grant, nof_prb)) { // Compute MCS - if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) { - // Fill rest of grant structure - grant->mcs.idx = dci->mcs_idx; - grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); - + if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) { // Apply Section 7.1.7.3. If RA-RNTI and Format1C rv_idx=0 if (msg_rnti >= SRSLTE_RARNTI_START && msg_rnti <= SRSLTE_RARNTI_END && dci->dci_is_1c) From 76ad1aeffc74740cddbd01a119862a0dc7fa3731 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Sep 2016 11:55:55 +0200 Subject: [PATCH 021/111] Fixed last_n_cce in new dci search --- srslte/include/srslte/ue/ue_dl.h | 1 - srslte/lib/ue/ue_dl.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index d248ad288..51a539513 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -85,7 +85,6 @@ typedef struct SRSLTE_API { uint64_t nof_detected; uint16_t current_rnti; - uint32_t last_n_cce; srslte_dci_location_t last_location; srslte_dci_msg_t pending_ul_dci_msg; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index e527f0d49..f7d13ff1a 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -284,7 +284,7 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_ra_dl_grant_t * uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { - return q->last_n_cce; + return q->last_location.ncce; } #define MAX_CANDIDATES_UE 16 // From 36.213 Table 9.1.1-1 From 7eaf004619fe96e69e44d8f8371013a709cfe6c8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Sep 2016 12:50:28 +0200 Subject: [PATCH 022/111] updated to version 1.3 --- cmake/modules/SRSLTEVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index 13a83bded..58d2de957 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -19,6 +19,6 @@ # SET(SRSLTE_VERSION_MAJOR 001) -SET(SRSLTE_VERSION_MINOR 002) +SET(SRSLTE_VERSION_MINOR 003) SET(SRSLTE_VERSION_PATCH 000) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") From 60312e145f58414ca6829acf17602a272d47e03c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Sep 2016 13:02:23 +0200 Subject: [PATCH 023/111] Updated changelog --- CHANGELOG | 14 ++++++++++++++ README.md | 1 - 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 8832d4268..57aba3f80 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,20 @@ Change Log for Releases ============================== +## 001.003.000 + +* Bugfixes: + * x300 master clock rate + * PHICH: fixed bug causing more NACKs + * PBCH: fixed bug in encoding function + * channel estimation: fixed issue in time interpolation + * DCI: Fixed bug in Format1A packing + * DCI: Fixed bug in Format1C for RA-RNTI + * DCI: Fixed overflow in MIMO formats + +* Improvements: + * Changed and cleaned DCI blind search API + * Added eNodeB PHY processing functions ## 001.002.000 diff --git a/README.md b/README.md index c09590093..b19fe83f8 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ Current Features: Missing Features: * Closed-loop power control * Semi-Persistent Scheduling - * Aperiodic CQI reports Hardware ======== From d37ae08719e9dc1c9d514bf042bd7189425bea81 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Sep 2016 13:19:08 +0200 Subject: [PATCH 024/111] make net sockets reusable --- srslte/lib/io/netsink.c | 6 ++++++ srslte/lib/io/netsource.c | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/srslte/lib/io/netsink.c b/srslte/lib/io/netsink.c index bc1648933..bedb5fc92 100644 --- a/srslte/lib/io/netsink.c +++ b/srslte/lib/io/netsink.c @@ -47,6 +47,12 @@ int srslte_netsink_init(srslte_netsink_t *q, char *address, int port, srslte_net return -1; } + int enable = 1; + if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) + perror("setsockopt(SO_REUSEADDR) failed"); + if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) + perror("setsockopt(SO_REUSEPORT) failed"); + q->servaddr.sin_family = AF_INET; q->servaddr.sin_addr.s_addr=inet_addr(address); q->servaddr.sin_port=htons(port); diff --git a/srslte/lib/io/netsource.c b/srslte/lib/io/netsource.c index 75e311812..f41296c3c 100644 --- a/srslte/lib/io/netsource.c +++ b/srslte/lib/io/netsource.c @@ -45,6 +45,14 @@ int srslte_netsource_init(srslte_netsource_t *q, char *address, int port, srslte perror("socket"); return -1; } + + // Make sockets reusable + int enable = 1; + if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) + perror("setsockopt(SO_REUSEADDR) failed"); + if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) + perror("setsockopt(SO_REUSEPORT) failed"); + q->type = type; q->servaddr.sin_family = AF_INET; From 9165808f8c38bde3863b956c6ab5784f21561a2f Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Fri, 2 Sep 2016 14:21:02 +0100 Subject: [PATCH 025/111] Updating notices --- COPYRIGHT | 2 +- README.md | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 7844c6d07..592199877 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (C) 2013-2015 Software Radio Systems Limited. All rights reserved. +Copyright (C) 2013-2016 Software Radio Systems Limited. All rights reserved. The following copyright notices are for libraries used within srsLTE: diff --git a/README.md b/README.md index b19fe83f8..5df567913 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,7 @@ srsLTE srsLTE is a free and open-source LTE library for SDR UE and eNodeB developed by SRS (www.softwareradiosystems.com). The library is highly modular with minimum inter-module or external dependencies. It is entirely written in C and, if available in the system, uses the acceleration library VOLK distributed in GNURadio. -**srsLTE is used by srsUE, a full stack (PHY to IP) implementation of an LTE UE. srsUE is available at https://github.com/srslte/srsue** - -*News*: We have just released srsUE 1.2 containing important bugfixes and improvements in the synchronization procedure. Checkout the [CHANGELOG](CHANGELOG) +**srsLTE is used by srsUE, a full stack (PHY to IP) implementation of an LTE UE. srsUE is available at https://github.com/srslte/srsue** The srsLTE software license is AGPLv3. From e36bd6a20fedd5d08d91fe045a9088d5160fda31 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Sep 2016 16:53:44 +0200 Subject: [PATCH 026/111] Revert "Fixed blind search" This reverts commit d80146e657efe1d35fe5447c03f3b1aa0fdd352a. Seems to have problems with OAI eNB. --- srslte/lib/phch/pdcch.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index ed0b041f6..5e03b9fbf 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -187,7 +187,7 @@ uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t int l; // this must be int because of the for(;;--) loop uint32_t i, k, L, m; uint32_t Yk, ncce; - const int M[4] = { 6, 6, 2, 2 }; + const int S[4] = { 6, 12, 8, 16 }; // Compute Yk for this subframe Yk = rnti; @@ -200,7 +200,7 @@ uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t for (l = 3; l >= 0; l--) { L = (1 << l); // For all possible ncce offset - for (i = 0; i < M[l]; i++) { + for (i = 0; i < SRSLTE_MIN(nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { if (nof_cce > L) { ncce = L * ((Yk + i) % (nof_cce / L)); if (k < max_candidates && ncce + L <= nof_cce) @@ -240,22 +240,17 @@ uint32_t srslte_pdcch_common_locations(srslte_pdcch_t *q, srslte_dci_location_t uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_location_t *c, uint32_t max_candidates) { uint32_t i, l, L, k; - const int M[4] = { 0, 0, 4, 2 }; - + k = 0; for (l = 3; l > 1; l--) { L = (1 << l); - for (i = 0; i < M[l]; i++) { - if (nof_cce > L) { - uint32_t ncce = L * (i % (nof_cce / L)); - if (k < max_candidates && ncce + L <= nof_cce) - { - c[k].L = l; - c[k].ncce = ncce; - DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n", - k, c[k].ncce, c[k].L); - k++; - } + for (i = 0; i < SRSLTE_MIN(nof_cce, 16) / (L); i++) { + if (k < max_candidates) { + c[k].L = l; + c[k].ncce = (L) * (i % (nof_cce / (L))); + DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n", + k, c[k].ncce, c[k].L); + k++; } } } From b161e360a434c1fab0e6a4fed53850e2e8de3788 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Sep 2016 12:14:11 +0200 Subject: [PATCH 027/111] Added checks for TBS decoding --- srslte/lib/phch/ra.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index dc12b7d4d..32902224b 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -425,10 +425,15 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr n_prb = dci->type2_alloc.n_prb1a == SRSLTE_RA_TYPE2_NPRB1A_2 ? 2 : 3; i_tbs = dci->mcs_idx; tbs = srslte_ra_tbs_from_idx(i_tbs, n_prb); - } else { + } else if (dci->dci_is_1c) { if (dci->mcs_idx < 32) { tbs = tbs_format1c_table[dci->mcs_idx]; - } + } else { + fprintf(stderr, "Error decoding DCI: Invalid mcs_idx=%d in Format1C\n", dci->mcs_idx); + } + } else { + fprintf(stderr, "Error decoding DCI: P/SI/RA-RNTI supports Format1A/1C only\n"); + return SRSLTE_ERROR; } grant->mcs.mod = SRSLTE_MOD_QPSK; grant->mcs.tbs = (uint32_t) tbs; From c58f1c9edc89216488dc93c095c8808428b26dfb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Sep 2016 21:41:19 -0400 Subject: [PATCH 028/111] fixed dl tbs for mcs >= 29 --- srslte/examples/pdsch_ue.c | 1 + srslte/lib/phch/ra.c | 19 +++++++++++++------ srslte/lib/ue/ue_dl.c | 5 +++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 8b6cf53a6..9e5feccfa 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -426,6 +426,7 @@ int main(int argc, char **argv) { #ifndef DISABLE_GRAPHICS if (!prog_args.disable_plots) { init_plots(cell); + sleep(1); } #endif diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index 32902224b..3a5b67a40 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -170,7 +170,8 @@ int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_ } srslte_mod_t last_mod[8]; -uint32_t last_tbs_idx[8]; +uint32_t last_ul_tbs_idx[8]; +uint32_t last_dl_tbs[8]; static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t harq_pid) { int tbs = -1; @@ -180,15 +181,15 @@ static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *gr if (dci->mcs_idx < 11) { grant->mcs.mod = SRSLTE_MOD_QPSK; tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->L_prb); - last_tbs_idx[harq_pid%8] = dci->mcs_idx; + last_ul_tbs_idx[harq_pid%8] = dci->mcs_idx; } else if (dci->mcs_idx < 21) { grant->mcs.mod = SRSLTE_MOD_16QAM; tbs = srslte_ra_tbs_from_idx(dci->mcs_idx-1, grant->L_prb); - last_tbs_idx[harq_pid%8] = dci->mcs_idx-1; + last_ul_tbs_idx[harq_pid%8] = dci->mcs_idx-1; } else if (dci->mcs_idx < 29) { grant->mcs.mod = SRSLTE_MOD_64QAM; tbs = srslte_ra_tbs_from_idx(dci->mcs_idx-2, grant->L_prb); - last_tbs_idx[harq_pid%8] = dci->mcs_idx-2; + last_ul_tbs_idx[harq_pid%8] = dci->mcs_idx-2; } else { fprintf(stderr, "Invalid MCS index %d\n", dci->mcs_idx); } @@ -196,10 +197,10 @@ static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *gr } else if (dci->mcs_idx == 29 && dci->cqi_request && grant->L_prb <= 4) { // 8.6.1 and 8.6.2 36.213 second paragraph grant->mcs.mod = SRSLTE_MOD_QPSK; - tbs = srslte_ra_tbs_from_idx(last_tbs_idx[harq_pid%8], grant->L_prb); + tbs = srslte_ra_tbs_from_idx(last_ul_tbs_idx[harq_pid%8], grant->L_prb); } else if (dci->mcs_idx >= 29) { // Else use last TBS/Modulation and use mcs to obtain rv_idx - tbs = srslte_ra_tbs_from_idx(last_tbs_idx[harq_pid%8], grant->L_prb); + tbs = srslte_ra_tbs_from_idx(last_ul_tbs_idx[harq_pid%8], grant->L_prb); grant->mcs.mod = last_mod[harq_pid%8]; dci->rv_idx = dci->mcs_idx - 28; DEBUG("TTI=%d, harq_pid=%d, mcs_idx=%d, tbs=%d, mod=%d, rv=%d\n", @@ -441,6 +442,12 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr n_prb = grant->nof_prb; grant->mcs.idx = dci->mcs_idx; tbs = dl_fill_ra_mcs(&grant->mcs, n_prb); + if (tbs) { + last_dl_tbs[dci->harq_process%8] = tbs; + } else { + // For mcs>=29, set last TBS received for this PID + grant->mcs.tbs = last_dl_tbs[dci->harq_process%8]; + } if (dci->nof_tb == 2) { grant->mcs2.idx = dci->mcs_idx_1; tbs = dl_fill_ra_mcs(&grant->mcs2, n_prb); diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index f7d13ff1a..fdfacc400 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -467,8 +467,9 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr float distance; uint32_t ngroup, nseq; srslte_phich_calc(&q->phich, n_prb_lowest, n_dmrs, &ngroup, &nseq); - DEBUG("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d\n", - sf_idx, n_prb_lowest, n_dmrs, ngroup, nseq); + INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d, Ngroups=%d, Nsf=%d\n", + sf_idx, n_prb_lowest, n_dmrs, ngroup, nseq, + srslte_phich_ngroups(&q->phich), srslte_phich_nsf(&q->phich)); if (!srslte_phich_decode(&q->phich, q->sf_symbols, q->ce, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); } else { From 60e77144ca592bb874da0fee8cb21cbc8e525875 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Sep 2016 18:26:35 +0200 Subject: [PATCH 029/111] Added prach detection to prach_test_usrp. Added full device names to RF objects --- srslte/include/srslte/phch/prach.h | 2 +- srslte/lib/phch/test/prach_test_usrp.c | 88 ++++++++++++++------------ srslte/lib/rf/rf_blade_imp.c | 7 +- srslte/lib/rf/rf_blade_imp.h | 5 ++ srslte/lib/rf/rf_dev.h | 6 +- srslte/lib/rf/rf_imp.c | 2 +- srslte/lib/rf/rf_uhd_imp.c | 14 ++++ srslte/lib/rf/rf_uhd_imp.h | 6 ++ 8 files changed, 85 insertions(+), 45 deletions(-) diff --git a/srslte/include/srslte/phch/prach.h b/srslte/include/srslte/phch/prach.h index de2085317..8221fc434 100644 --- a/srslte/include/srslte/phch/prach.h +++ b/srslte/include/srslte/phch/prach.h @@ -155,7 +155,7 @@ SRSLTE_API int srslte_prach_detect_offset(srslte_prach_t *p, uint32_t sig_len, uint32_t *indices, float *t_offsets, - float *peak_to_avg, + float *peak_to_avg, uint32_t *ind_len); SRSLTE_API void srslte_prach_set_detect_factor(srslte_prach_t *p, diff --git a/srslte/lib/phch/test/prach_test_usrp.c b/srslte/lib/phch/test/prach_test_usrp.c index acdaf1947..56ec6b506 100644 --- a/srslte/lib/phch/test/prach_test_usrp.c +++ b/srslte/lib/phch/test/prach_test_usrp.c @@ -45,10 +45,10 @@ uint32_t root_seq_idx = 0; uint32_t seq_idx = 0; uint32_t frequency_offset = 0; uint32_t zero_corr_zone = 11; -uint32_t timeadv = 0; +float timeadv = 0; uint32_t nof_frames = 20; -float uhd_gain=40, uhd_freq=2.4e9; +float uhd_rx_gain=40, uhd_tx_gain=60, uhd_freq=2.4e9; char *uhd_args=""; char *output_filename = "prach_rx"; @@ -56,20 +56,21 @@ void usage(char *prog) { printf("Usage: %s \n", prog); printf("\t-a UHD args [Default %s]\n", uhd_args); printf("\t-f UHD TX/RX frequency [Default %.2f MHz]\n", uhd_freq/1e6); - printf("\t-g UHD TX/RX gain [Default %.1f dB]\n", uhd_gain); + printf("\t-g UHD RX gain [Default %.1f dB]\n", uhd_rx_gain); + printf("\t-G UHD TX gain [Default %.1f dB]\n", uhd_tx_gain); printf("\t-p Number of UL RB [Default %d]\n", nof_prb); printf("\t-F Preamble format [Default %d]\n", preamble_format); printf("\t-O Frequency offset [Default %d]\n", frequency_offset); printf("\t-s sequence index [Default %d]\n", seq_idx); printf("\t-r Root sequence index [Default %d]\n", root_seq_idx); - printf("\t-t Time advance (us) [Default %d]\n", timeadv); + printf("\t-t Time advance (us) [Default %.1f us]\n", timeadv); printf("\t-z Zero correlation zone config [Default %d]\n", zero_corr_zone); printf("\t-o Save transmitted PRACH in file [Default no]\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "apfFgrstoPOz")) != -1) { + while ((opt = getopt(argc, argv, "apfFgGrstoPOz")) != -1) { switch (opt) { case 'a': uhd_args = argv[optind]; @@ -81,7 +82,10 @@ void parse_args(int argc, char **argv) { uhd_freq = atof(argv[optind]); break; case 'g': - uhd_gain = atof(argv[optind]); + uhd_rx_gain = atof(argv[optind]); + break; + case 'G': + uhd_tx_gain = atof(argv[optind]); break; case 'P': preamble_format = atoi(argv[optind]); @@ -90,7 +94,7 @@ void parse_args(int argc, char **argv) { frequency_offset = atoi(argv[optind]); break; case 't': - timeadv = atoi(argv[optind]); + timeadv = atof(argv[optind]); break; case 'p': nof_prb = atoi(argv[optind]); @@ -129,11 +133,11 @@ int main(int argc, char **argv) { memset(preamble, 0, sizeof(cf_t)*MAX_LEN); srslte_prach_init(p, - srslte_symbol_sz(nof_prb), - preamble_format, - root_seq_idx, - high_speed_flag, - zero_corr_zone); + srslte_symbol_sz(nof_prb), + preamble_format, + root_seq_idx, + high_speed_flag, + zero_corr_zone); int srate = srslte_sampling_freq_hz(nof_prb); uint32_t flen = srate/1000; @@ -153,71 +157,73 @@ int main(int argc, char **argv) { cf_t *buffer = malloc(sizeof(cf_t)*flen*nof_frames); // Send through UHD - srslte_rf_t uhd; - printf("Opening UHD device...\n"); - if (srslte_rf_open(&uhd, uhd_args)) { + srslte_rf_t rf; + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, uhd_args)) { fprintf(stderr, "Error opening &uhd\n"); exit(-1); } printf("Subframe len: %d samples\n", flen); - printf("Set RX gain: %.1f dB\n", uhd_gain); - printf("Set TX gain: %.1f dB\n", 20+uhd_gain); + printf("Set RX gain: %.1f dB\n", uhd_rx_gain); + printf("Set TX gain: %.1f dB\n", uhd_tx_gain); printf("Set TX/RX freq: %.2f MHz\n", uhd_freq/ 1000000); - srslte_rf_set_rx_gain(&uhd, uhd_gain); - srslte_rf_set_tx_gain(&uhd, 10+uhd_gain); - srslte_rf_set_rx_freq(&uhd, uhd_freq); - srslte_rf_set_tx_freq(&uhd, uhd_freq); + srslte_rf_set_rx_gain(&rf, uhd_rx_gain); + srslte_rf_set_tx_gain(&rf, uhd_tx_gain); + srslte_rf_set_rx_freq(&rf, uhd_freq); + srslte_rf_set_tx_freq(&rf, uhd_freq); - if (srate < 10e6) { - srslte_rf_set_master_clock_rate(&uhd, 4*srate); + if (30720%((int) srate/1000) == 0) { + srslte_rf_set_master_clock_rate(&rf, 30.72e6); } else { - srslte_rf_set_master_clock_rate(&uhd, srate); + srslte_rf_set_master_clock_rate(&rf, 23.04e6); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); - float srate_rf = srslte_rf_set_rx_srate(&uhd, (double) srate); + float srate_rf = srslte_rf_set_rx_srate(&rf, (double) srate); if (srate_rf != srate) { fprintf(stderr, "Could not set sampling rate\n"); exit(-1); } - srslte_rf_set_tx_srate(&uhd, (double) srate); + srslte_rf_set_tx_srate(&rf, (double) srate); sleep(1); cf_t *zeros = calloc(sizeof(cf_t),flen); - FILE *f = NULL; - if (output_filename) { - f = fopen(output_filename, "w"); - } - srslte_timestamp_t tstamp; - srslte_rf_start_rx_stream(&uhd); + srslte_rf_start_rx_stream(&rf); uint32_t nframe=0; while(nframeN_cp], flen, indices, offsets, NULL, &nof_detected)) { + printf("Error detecting prach\n"); } - if (f) { - fclose(f); + printf("Nof detected PRACHs: %d\n", nof_detected); + for (int i=0;idev)->name; + return ((rf_dev_t*) rf->dev)->srslte_rf_devname(rf->handler); } bool srslte_rf_rx_wait_lo_locked(srslte_rf_t *rf) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index c0b4cc71a..e03d7d346 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -36,6 +36,7 @@ #include "uhd_c_api.h" typedef struct { + char *devname; uhd_usrp_handle usrp; uhd_rx_streamer_handle rx_stream; uhd_tx_streamer_handle tx_stream; @@ -117,6 +118,12 @@ static bool isLocked(rf_uhd_handler_t *handler, char *sensor_name, uhd_sensor_va return val_out; } +char* rf_uhd_devname(void* h) +{ + rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; + return handler->devname; +} + bool rf_uhd_rx_wait_lo_locked(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; @@ -251,15 +258,19 @@ int rf_uhd_open(char *args, void **h) if (args == NULL) { args = ""; } + handler->devname = "uhd_unknown"; + /* If device type or name not given in args, choose a B200 */ if (args[0]=='\0') { if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { // If B200 is available, use it args = "type=b200,recv_frame_size=9232,send_frame_size=9232"; + handler->devname = DEVNAME_B200; } else if (find_string(devices_str, "type=x300")) { // Else if X300 is available, set master clock rate now (can't be changed later) args = "type=x300,master_clock_rate=184.32e6"; handler->dynamic_rate = false; + handler->devname = DEVNAME_X300; } } else { // If args is set and x300 type is specified, make sure master_clock_rate is defined @@ -267,6 +278,9 @@ int rf_uhd_open(char *args, void **h) sprintf(args2, "%s,master_clock_rate=184.32e6",args); args = args2; handler->dynamic_rate = false; + handler->devname = DEVNAME_X300; + } else if (strstr(args, "type=b200")) { + handler->devname = DEVNAME_B200; } } diff --git a/srslte/lib/rf/rf_uhd_imp.h b/srslte/lib/rf/rf_uhd_imp.h index 240cfc8f0..ee13ea36e 100644 --- a/srslte/lib/rf/rf_uhd_imp.h +++ b/srslte/lib/rf/rf_uhd_imp.h @@ -30,9 +30,15 @@ #include "srslte/config.h" #include "srslte/rf/rf.h" +#define DEVNAME_B200 "uhd_b200" +#define DEVNAME_X300 "uhd_x300" + + SRSLTE_API int rf_uhd_open(char *args, void **handler); +SRSLTE_API char* rf_uhd_devname(void *h); + SRSLTE_API int rf_uhd_close(void *h); SRSLTE_API void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal); From 2b3087b1f92b4b466e163501693c00e76743a8e2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 22 Sep 2016 11:04:18 +0200 Subject: [PATCH 030/111] fixed coverty bug --- srslte/lib/phch/test/prach_test_usrp.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/srslte/lib/phch/test/prach_test_usrp.c b/srslte/lib/phch/test/prach_test_usrp.c index 56ec6b506..0cd85e39d 100644 --- a/srslte/lib/phch/test/prach_test_usrp.c +++ b/srslte/lib/phch/test/prach_test_usrp.c @@ -173,10 +173,15 @@ int main(int argc, char **argv) { srslte_rf_set_rx_freq(&rf, uhd_freq); srslte_rf_set_tx_freq(&rf, uhd_freq); - if (30720%((int) srate/1000) == 0) { - srslte_rf_set_master_clock_rate(&rf, 30.72e6); + if (srate > 1e6) { + if (30720%((int) srate/1000) == 0) { + srslte_rf_set_master_clock_rate(&rf, 30.72e6); + } else { + srslte_rf_set_master_clock_rate(&rf, 23.04e6); + } } else { - srslte_rf_set_master_clock_rate(&rf, 23.04e6); + printf("Invalid sampling rate %d Hz\n", srate); + exit(-1); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); float srate_rf = srslte_rf_set_rx_srate(&rf, (double) srate); From ceddb15debc2bafbfcac412610ce01e4888649d7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 22 Sep 2016 13:56:46 +0200 Subject: [PATCH 031/111] Fixed RV for SIB in pdsch_ue example --- srslte/examples/cell_measurement.c | 3 +- srslte/examples/pdsch_ue.c | 31 +++---- srslte/include/srslte/ue/ue_dl.h | 11 +-- srslte/lib/ue/ue_dl.c | 143 ++++++++++++++--------------- 4 files changed, 85 insertions(+), 103 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index 6de938c78..616d77df0 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -307,8 +307,7 @@ int main(int argc, char **argv) { case DECODE_SIB: /* We are looking for SI Blocks, search only in appropiate places */ if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { - n = srslte_ue_dl_decode_rnti_rv(&ue_dl, sf_buffer, data, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, - ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); + n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); if (n < 0) { fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); return -1; diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 8b6cf53a6..f3276fcdc 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -494,7 +494,7 @@ int main(int argc, char **argv) { decode_pdsch = true; } else { /* We are looking for SIB1 Blocks, search only in appropiate places */ - if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%8)==0)) { + if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { decode_pdsch = true; } else { decode_pdsch = false; @@ -502,28 +502,21 @@ int main(int argc, char **argv) { } if (decode_pdsch) { INFO("Attempting DL decode SFN=%d\n", sfn); - if (prog_args.rnti != SRSLTE_SIRNTI) { - n = srslte_ue_dl_decode(&ue_dl, &sf_buffer[prog_args.time_offset], data, srslte_ue_sync_get_sfidx(&ue_sync)); - } else { - // RV for SIB1 is predefined - uint32_t k = (sfn/2)%4; - uint32_t rv = ((uint32_t) ceilf((float)1.5*k))%4; - n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data, - srslte_ue_sync_get_sfidx(&ue_sync), - SRSLTE_SIRNTI, rv); - - /* - if (n>0) { - printf("Saving signal...\n"); - srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti); - exit(-1); - } - */ - } + n = srslte_ue_dl_decode(&ue_dl, + &sf_buffer[prog_args.time_offset], + data, + sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); + if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); } else if (n > 0) { + /* + printf("Saving signal...\n"); + srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti); + exit(-1); + */ + /* Send data if socket active */ if (prog_args.net_port > 0) { srslte_netsink_write(&net_sink, data, 1+(n-1)/8); diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 51a539513..9624acdea 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -141,21 +141,14 @@ SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q, cf_t *input, uint8_t *data, - uint32_t sf_idx); + uint32_t tti); SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q, cf_t *input, uint8_t *data, - uint32_t sf_idx, + uint32_t tti, uint16_t rnti); -SRSLTE_API int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t * q, - cf_t *input, - uint8_t * data, - uint32_t sf_idx, - uint16_t rnti, - uint32_t rvidx); - SRSLTE_API bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_prb_lowest, diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index f7d13ff1a..1f4e097b6 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -178,12 +178,8 @@ void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { * - PDCCH decoding: Find DCI for RNTI given by previous call to srslte_ue_dl_set_rnti() * - PDSCH decoding: Decode TB scrambling with RNTI given by srslte_ue_dl_set_rnti() */ -int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx) { - return srslte_ue_dl_decode_rnti_rv(q, input, data, sf_idx, q->current_rnti, 0); -} - -int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti) { - return srslte_ue_dl_decode_rnti_rv(q, input, data, sf_idx, rnti, 0); +int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti) { + return srslte_ue_dl_decode_rnti(q, input, data, tti, q->current_rnti); } int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t *cfi) { @@ -241,47 +237,86 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx); } -int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint8_t *data, - uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) +int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti) { + srslte_dci_msg_t dci_msg; + srslte_ra_dl_dci_t dci_unpacked; + srslte_ra_dl_grant_t grant; int ret = SRSLTE_ERROR; - - q->nof_detected++; + uint32_t cfi; - /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */ - if (srslte_ue_dl_cfg_grant(q, grant, cfi, sf_idx, rvidx)) { - return SRSLTE_ERROR; - } + uint32_t sf_idx = tti%10; - if (q->pdsch_cfg.rv == 0) { - srslte_softbuffer_rx_reset_tbs(&q->softbuffer, grant->mcs.tbs); + if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &cfi)) < 0) { + return ret; } - // Uncoment next line to do ZF by default in pdsch_ue example - //float noise_estimate = 0; - float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); + if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { + fprintf(stderr, "Error extracting LLRs\n"); + return SRSLTE_ERROR; + } + + int found_dci = srslte_ue_dl_find_dl_dci(q, cfi, sf_idx, rnti, &dci_msg); + if (found_dci == 1) { + + if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) { + fprintf(stderr, "Error unpacking DCI\n"); + return SRSLTE_ERROR; + } + + /* ===== These lines of code are supposed to be MAC functionality === */ + + + uint32_t rvidx = 0; + if (dci_unpacked.rv_idx < 0) { + uint32_t sfn = tti/10; + uint32_t k = (sfn/2)%4; + rvidx = ((uint32_t) ceilf((float)1.5*k))%4; + srslte_softbuffer_rx_reset_tbs(&q->softbuffer, grant.mcs.tbs); + } else { + rvidx = dci_unpacked.rv_idx; + srslte_softbuffer_rx_reset_tbs(&q->softbuffer, grant.mcs.tbs); + } + + if (srslte_ue_dl_cfg_grant(q, &grant, cfi, sf_idx, rvidx)) { + return SRSLTE_ERROR; + } + + /* ===== End of MAC functionality ========== */ + + q->nof_detected++; - if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { - ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, - q->sf_symbols, q->ce, - noise_estimate, - rnti, data); + // Uncoment next line to do ZF by default in pdsch_ue example + //float noise_estimate = 0; + float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); - if (ret == SRSLTE_ERROR) { - q->pkt_errors++; - } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { - fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); - } else if (ret == SRSLTE_SUCCESS) { - if (SRSLTE_VERBOSE_ISDEBUG()) { - INFO("Decoded Message: ", 0); - srslte_vec_fprint_hex(stdout, data, q->pdsch_cfg.grant.mcs.tbs); + if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { + ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, + q->sf_symbols, q->ce, + noise_estimate, + rnti, data); + + if (ret == SRSLTE_ERROR) { + q->pkt_errors++; + } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { + fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); + } else if (ret == SRSLTE_SUCCESS) { + if (SRSLTE_VERBOSE_ISDEBUG()) { + INFO("Decoded Message: ", 0); + srslte_vec_fprint_hex(stdout, data, q->pdsch_cfg.grant.mcs.tbs); + } } } - q->pkts_total++; } - return ret; -} + q->pkts_total++; + + if (found_dci == 1 && ret == SRSLTE_SUCCESS) { + return q->pdsch_cfg.grant.mcs.tbs; + } else { + return 0; + } +} uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { return q->last_location.ncce; @@ -423,44 +458,6 @@ int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_i } } - -int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) -{ - srslte_dci_msg_t dci_msg; - srslte_ra_dl_dci_t dci_unpacked; - srslte_ra_dl_grant_t grant; - int ret = SRSLTE_ERROR; - uint32_t cfi; - - - if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &cfi)) < 0) { - return ret; - } - - if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { - fprintf(stderr, "Error extracting LLRs\n"); - return SRSLTE_ERROR; - } - - int found_dci = srslte_ue_dl_find_dl_dci(q, cfi, sf_idx, rnti, &dci_msg); - if (found_dci == 1) { - - if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) { - fprintf(stderr, "Error unpacking DCI\n"); - return SRSLTE_ERROR; - } - - ret = srslte_ue_dl_decode_rnti_rv_packet(q, &grant, data, cfi, sf_idx, rnti, rvidx); - } - - if (found_dci == 1 && ret == SRSLTE_SUCCESS) { - return q->pdsch_cfg.grant.mcs.tbs; - } else { - return 0; - } -} - - bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_prb_lowest, uint32_t n_dmrs) { uint8_t ack_bit; From 59ecfcdfdd8074e76b66efde352d77157da3df0c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 22 Sep 2016 17:51:04 +0200 Subject: [PATCH 032/111] Updated to version 1.3.1 --- cmake/modules/SRSLTEVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index 58d2de957..39937c1d8 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -20,5 +20,5 @@ SET(SRSLTE_VERSION_MAJOR 001) SET(SRSLTE_VERSION_MINOR 003) -SET(SRSLTE_VERSION_PATCH 000) +SET(SRSLTE_VERSION_PATCH 001) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") From 1d7bfc79c28f8473fbbe085d836911b00b50f9c8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 22 Sep 2016 18:21:50 +0200 Subject: [PATCH 033/111] fixed coverty bugs --- srslte/lib/ue/ue_dl.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 6886aabd7..a26242da9 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -300,12 +300,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint q->pkt_errors++; } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); - } else if (ret == SRSLTE_SUCCESS) { - if (SRSLTE_VERBOSE_ISDEBUG()) { - INFO("Decoded Message: ", 0); - srslte_vec_fprint_hex(stdout, data, q->pdsch_cfg.grant.mcs.tbs); - } - } + } } } From f4ed3c48213224914249a27756c2c1da3ee5d4c4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 26 Sep 2016 12:56:16 +0200 Subject: [PATCH 034/111] dci: added missing flag 1a/1c in pack functions --- srslte/lib/phch/dci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 3203fc48d..fbe7d6b45 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -648,6 +648,8 @@ int dci_format1As_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t fprintf(stderr, "Format 1A accepts type2 resource allocation only\n"); return SRSLTE_ERROR; } + + data->dci_is_1a = true; *y++ = data->type2_alloc.mode; // localized or distributed VRB assignment @@ -719,7 +721,7 @@ int dci_format1As_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t *y++ = 0; } msg->nof_bits = (y - msg->data); - + return SRSLTE_SUCCESS; } @@ -878,6 +880,8 @@ int dci_format1Cs_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t "Format 1C accepts distributed type2 resource allocation only\n"); return SRSLTE_ERROR; } + + data->dci_is_1c = true; if (nof_prb >= 50) { *y++ = data->type2_alloc.n_gap; From ed35015ff59ef3e8b9315adf2423f879fb35fbb8 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Tue, 27 Sep 2016 09:12:49 +0000 Subject: [PATCH 035/111] Adding -fPIC for all platforms --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c77a24fc6..124186060 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,9 @@ endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) ######################################################################## CMAKE_MINIMUM_REQUIRED (VERSION 2.6) PROJECT (SRSLTE) +MESSAGE( STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM} ) +MESSAGE( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR} ) +MESSAGE( STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER} ) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") include(SRSLTEVersion) #sets version information @@ -149,9 +152,7 @@ add_custom_target(uninstall # Macro to add -fPIC property to static libs ######################################################################## macro(SRSLTE_SET_PIC) - if( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) - set_target_properties(${ARGV} PROPERTIES COMPILE_FLAGS -fPIC) - endif( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) + set_target_properties(${ARGV} PROPERTIES COMPILE_FLAGS -fPIC) endmacro(SRSLTE_SET_PIC) ######################################################################## From 45609b1c70ba5170c10e5d71061314f3431dce97 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 28 Sep 2016 13:14:24 +0200 Subject: [PATCH 036/111] pdsch: data not needed in encode. enb: changed rnti_idx to int --- srslte/include/srslte/enb/enb_dl.h | 4 ++-- srslte/include/srslte/enb/enb_ul.h | 2 +- srslte/lib/phch/pdsch.c | 1 - srslte/lib/phch/prach.c | 5 +---- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/srslte/include/srslte/enb/enb_dl.h b/srslte/include/srslte/enb/enb_dl.h index 7f3b034e0..a95c6f824 100644 --- a/srslte/include/srslte/enb/enb_dl.h +++ b/srslte/include/srslte/enb/enb_dl.h @@ -92,7 +92,7 @@ typedef struct SRSLTE_API { } srslte_enb_dl_t; typedef struct { - uint32_t rnti_idx; + int rnti_idx; srslte_ra_dl_dci_t grant; srslte_dci_location_t location; srslte_softbuffer_tx_t *softbuffer; @@ -101,7 +101,7 @@ typedef struct { typedef struct { uint8_t ack; - uint32_t rnti_idx; + int rnti_idx; } srslte_enb_dl_phich_t; /* This function shall be called just after the initial synchronization */ diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index bd1f0c908..c636c994b 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -77,7 +77,7 @@ typedef struct SRSLTE_API { } srslte_enb_ul_t; typedef struct { - uint32_t rnti_idx; + int rnti_idx; srslte_ra_ul_dci_t grant; srslte_dci_location_t location; uint32_t rv_idx; diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index 174b8715a..56089cefb 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -562,7 +562,6 @@ int srslte_pdsch_encode_seq(srslte_pdsch_t *q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && - data != NULL && cfg != NULL) { diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index 39114ec8e..4406297c2 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -600,10 +600,7 @@ int srslte_prach_detect_offset(srslte_prach_t *p, for (int j=0;jpeak_values[j] > p->detect_factor*corr_ave) { - printf("ncs=%d, nzc=%d, nwins=%d, Nroot=%d, i=%d, j=%d, start=%d, peak_value=%f, peak_offset=%d, tseq=%f\n", - p->N_cs, p->N_zc, n_wins, p->N_roots, i, j, (p->N_zc-(j*p->N_cs))%p->N_zc, p->peak_values[j], - p->peak_offsets[j], p->T_seq*1e6); - memcpy(save_corr, p->corr, p->N_zc*sizeof(float)); + //memcpy(save_corr, p->corr, p->N_zc*sizeof(float)); if (indices) { indices[*n_indices] = (i*n_wins)+j; } From 811ad420efd336a7ad75224d395e9d0114587731 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 4 Oct 2016 11:19:24 +0200 Subject: [PATCH 037/111] ue_ul: set cfo tol to 0 --- matlab/tests/pusch_encode_test.m | 6 +++--- srslte/lib/ue/ue_ul.c | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/matlab/tests/pusch_encode_test.m b/matlab/tests/pusch_encode_test.m index 13a94a7b5..5d09e88f5 100644 --- a/matlab/tests/pusch_encode_test.m +++ b/matlab/tests/pusch_encode_test.m @@ -3,11 +3,11 @@ puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'NBundled',0); addpath('../../build//srslte/lib/phch/test') -cqilen=[0 4 20]; +cqilen=0;%[0 4 20]; mods={'64QAM'}; rvs=0; -betas=[0 5.0, 20.0]; -for p=1:ueConfig.NULRB +betas=0;%[0 5.0, 20.0]; +for p=1 for i=0:26 for m=1:length(mods) for r=1:length(rvs) diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index 1d8a371e4..a8e717311 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -65,6 +65,8 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q, goto clean_exit; } + srslte_cfo_set_tol(&q->cfo, 0); + if (srslte_pusch_init(&q->pusch, q->cell)) { fprintf(stderr, "Error creating PUSCH object\n"); goto clean_exit; From 1f6e63ae4fdf96ce153eedc61b5d37199aac8e08 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 4 Oct 2016 19:11:04 +0200 Subject: [PATCH 038/111] cfo: srslte_sync_get_cfo() returns PSS-based CFO estimation. Gives better results than CP-based --- srslte/examples/pdsch_ue.c | 6 ------ srslte/include/srslte/sync/sync.h | 2 ++ srslte/lib/rf/rf_blade_imp.c | 7 +++++++ srslte/lib/sync/sync.c | 35 +++++++++++++++++++++++-------- srslte/lib/ue/ue_dl.c | 7 +++++++ srslte/lib/ue/ue_sync.c | 10 ++++----- 6 files changed, 46 insertions(+), 21 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 15254697d..a9f48b941 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -511,12 +511,6 @@ int main(int argc, char **argv) { if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); } else if (n > 0) { - - /* - printf("Saving signal...\n"); - srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti); - exit(-1); - */ /* Send data if socket active */ if (prog_args.net_port > 0) { diff --git a/srslte/include/srslte/sync/sync.h b/srslte/include/srslte/sync/sync.h index de13244df..b5eccbb88 100644 --- a/srslte/include/srslte/sync/sync.h +++ b/srslte/include/srslte/sync/sync.h @@ -76,6 +76,7 @@ typedef struct SRSLTE_API { uint32_t max_offset; bool enable_cfo_corr; float mean_cfo; + float mean_cfo2; int cfo_i; bool find_cfo_i; bool find_cfo_i_initiated; @@ -93,6 +94,7 @@ typedef struct SRSLTE_API { float m1_value; float M_norm_avg; float M_ext_avg; + cf_t *temp; }srslte_sync_t; diff --git a/srslte/lib/rf/rf_blade_imp.c b/srslte/lib/rf/rf_blade_imp.c index 031ef6fe9..fbe9b3fc6 100644 --- a/srslte/lib/rf/rf_blade_imp.c +++ b/srslte/lib/rf/rf_blade_imp.c @@ -341,6 +341,10 @@ double rf_blade_set_rx_freq(void *h, double freq) (uint32_t) freq, bladerf_strerror(status)); return -1; } + f_int=0; + bladerf_get_frequency(handler->dev, BLADERF_MODULE_RX, &f_int); + printf("set RX frequency to %u\n", f_int); + return freq; } @@ -355,6 +359,9 @@ double rf_blade_set_tx_freq(void *h, double freq) return -1; } + f_int=0; + bladerf_get_frequency(handler->dev, BLADERF_MODULE_TX, &f_int); + printf("set TX frequency to %u\n", f_int); return freq; } diff --git a/srslte/lib/sync/sync.c b/srslte/lib/sync/sync.c index df44ed77b..12bde29f1 100644 --- a/srslte/lib/sync/sync.c +++ b/srslte/lib/sync/sync.c @@ -61,6 +61,7 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, q->detect_cp = true; q->sss_en = true; q->mean_cfo = 0; + q->mean_cfo2 = 0; q->N_id_2 = 1000; q->N_id_1 = 1000; q->cfo_i = 0; @@ -78,8 +79,8 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, goto clean_exit; } - // Set a CFO tolerance of approx 100 Hz - srslte_cfo_set_tol(&q->cfocorr, 100.0/(15000.0*q->fft_size)); + // Set a CFO tolerance of approx 50 Hz + srslte_cfo_set_tol(&q->cfocorr, 50.0/(15000.0*q->fft_size)); for (int i=0;i<2;i++) { q->cfo_i_corr[i] = srslte_vec_malloc(sizeof(cf_t)*q->frame_size); @@ -89,6 +90,12 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, } } + q->temp = srslte_vec_malloc(sizeof(cf_t)*2*q->frame_size); + if (!q->temp) { + perror("malloc"); + goto clean_exit; + } + srslte_sync_set_cp(q, SRSLTE_CP_NORM); if (srslte_pss_synch_init_fft(&q->pss, max_offset, fft_size)) { @@ -131,6 +138,9 @@ void srslte_sync_free(srslte_sync_t *q) { } srslte_pss_synch_free(&q->pss_i[i]); } + if (q->temp) { + free(q->temp); + } } } @@ -185,7 +195,7 @@ uint32_t srslte_sync_get_sf_idx(srslte_sync_t *q) { } float srslte_sync_get_cfo(srslte_sync_t *q) { - return q->mean_cfo + q->cfo_i; + return q->mean_cfo2 + q->cfo_i; } void srslte_sync_set_cfo(srslte_sync_t *q, float cfo) { @@ -413,6 +423,8 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t if (peak_position) { *peak_position = 0; } + + cf_t *input_cfo = input; if (q->enable_cfo_corr) { float cfo = cfo_estimate(q, input); @@ -421,19 +433,21 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha); /* Correct CFO with the averaged CFO estimation */ - srslte_cfo_correct(&q->cfocorr, input, input, -q->mean_cfo / q->fft_size); + srslte_cfo_correct(&q->cfocorr, input, q->temp, -q->mean_cfo / q->fft_size); + + input_cfo = q->temp; } /* If integer CFO is enabled, find max PSS correlation for shifted +1/0/-1 integer versions */ if (q->find_cfo_i && q->enable_cfo_corr) { - q->cfo_i = cfo_i_estimate(q, input, find_offset, &peak_pos); + q->cfo_i = cfo_i_estimate(q, input_cfo, find_offset, &peak_pos); if (q->cfo_i != 0) { - srslte_vec_prod_ccc(input, q->cfo_i_corr[q->cfo_i<0?0:1], input, q->frame_size); + srslte_vec_prod_ccc(input_cfo, q->cfo_i_corr[q->cfo_i<0?0:1], input_cfo, q->frame_size); INFO("Compensating cfo_i=%d\n", q->cfo_i); } } else { srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); - peak_pos = srslte_pss_synch_find_pss(&q->pss, &input[find_offset], &q->peak_value); + peak_pos = srslte_pss_synch_find_pss(&q->pss, &input_cfo[find_offset], &q->peak_value); if (peak_pos < 0) { fprintf(stderr, "Error calling finding PSS sequence\n"); return SRSLTE_ERROR; @@ -449,7 +463,7 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t // Set an invalid N_id_1 indicating SSS is yet to be detected q->N_id_1 = 1000; - if (sync_sss(q, input, find_offset + peak_pos, q->cp) < 0) { + if (sync_sss(q, input_cfo, find_offset + peak_pos, q->cp) < 0) { DEBUG("No space for SSS processing. Frame starts at %d\n", peak_pos); } } @@ -459,13 +473,16 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t if (q->detect_cp) { if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { - srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input, peak_pos + find_offset)); + srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input_cfo, peak_pos + find_offset)); } else { DEBUG("Not enough room to detect CP length. Peak position: %d\n", peak_pos); } } if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { + float cfo2 = srslte_pss_synch_cfo_compute(&q->pss, &input[find_offset + peak_pos - q->fft_size]); + q->mean_cfo2 = SRSLTE_VEC_EMA(cfo2, q->mean_cfo2, q->cfo_ema_alpha); + ret = SRSLTE_SYNC_FOUND; } else { ret = SRSLTE_SYNC_FOUND_NOSPACE; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index a26242da9..11014b963 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -302,6 +302,13 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); } } + + printf("Saving signal...\n"); + srslte_vec_save_file("input", input, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + srslte_ue_dl_save_signal(q, &q->softbuffer, sf_idx, rvidx, rnti, cfi); + //exit(-1); + + } q->pkts_total++; diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index aef15e342..603eb9e15 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -605,14 +605,12 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { } q->frame_total_cnt++; - } else { - if (q->correct_cfo) { - srslte_cfo_correct(&q->sfind.cfocorr, + } + if (q->correct_cfo) { + srslte_cfo_correct(&q->sfind.cfocorr, input_buffer, input_buffer, - -srslte_sync_get_cfo(&q->strack) / q->fft_size); - - } + -srslte_sync_get_cfo(&q->strack) / q->fft_size); } break; } From cbade7d29c02b49a89099a8ca946c9eb484ce993 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 5 Oct 2016 21:36:51 +0200 Subject: [PATCH 039/111] rf_uhd: device familiy detection when device_args are supplied --- srslte/lib/rf/rf_uhd_imp.c | 16 ++++++++++++++-- srslte/lib/ue/ue_dl.c | 5 +++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index e03d7d346..57b61cc98 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -258,7 +258,7 @@ int rf_uhd_open(char *args, void **h) if (args == NULL) { args = ""; } - handler->devname = "uhd_unknown"; + handler->devname = NULL; /* If device type or name not given in args, choose a B200 */ if (args[0]=='\0') { @@ -291,7 +291,19 @@ int rf_uhd_open(char *args, void **h) fprintf(stderr, "Error opening UHD: code %d\n", error); return -1; } - + + if (!handler->devname) { + char dev_str[1024]; + uhd_usrp_get_mboard_name(handler->usrp, 0, dev_str, 1024); + if (strstr(dev_str, "B2") || strstr(dev_str, "B2")) { + handler->devname = DEVNAME_B200; + } else if (strstr(dev_str, "X3") || strstr(dev_str, "X3")) { + handler->devname = DEVNAME_X300; + } + } + if (!handler->devname) { + handler->devname = "uhd_unknown"; + } size_t channel = 0; uhd_stream_args_t stream_args = { .cpu_format = "fc32", diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 11014b963..8f4ad9afa 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -302,12 +302,13 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); } } - + + /* printf("Saving signal...\n"); srslte_vec_save_file("input", input, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); srslte_ue_dl_save_signal(q, &q->softbuffer, sf_idx, rvidx, rnti, cfi); //exit(-1); - + */ } From 91645c8d6577e29683dc3c86d38cdd22dfd9f8c1 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 5 Oct 2016 21:45:12 +0200 Subject: [PATCH 040/111] sync: added new cfocorr object to avoid rebuilding table based on tolerance --- srslte/include/srslte/sync/sync.h | 1 + srslte/lib/sync/sync.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/srslte/include/srslte/sync/sync.h b/srslte/include/srslte/sync/sync.h index b5eccbb88..364baed19 100644 --- a/srslte/include/srslte/sync/sync.h +++ b/srslte/include/srslte/sync/sync.h @@ -84,6 +84,7 @@ typedef struct SRSLTE_API { uint32_t nof_symbols; uint32_t cp_len; srslte_cfo_t cfocorr; + srslte_cfo_t cfocorr2; sss_alg_t sss_alg; bool detect_cp; bool sss_en; diff --git a/srslte/lib/sync/sync.c b/srslte/lib/sync/sync.c index 12bde29f1..f7ddddd84 100644 --- a/srslte/lib/sync/sync.c +++ b/srslte/lib/sync/sync.c @@ -78,10 +78,18 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; } + + if (srslte_cfo_init(&q->cfocorr2, q->frame_size)) { + fprintf(stderr, "Error initiating CFO\n"); + goto clean_exit; + } // Set a CFO tolerance of approx 50 Hz srslte_cfo_set_tol(&q->cfocorr, 50.0/(15000.0*q->fft_size)); + // Set a CFO tolerance of approx 50 Hz + srslte_cfo_set_tol(&q->cfocorr2, 50.0/(15000.0*q->fft_size)); + for (int i=0;i<2;i++) { q->cfo_i_corr[i] = srslte_vec_malloc(sizeof(cf_t)*q->frame_size); if (!q->cfo_i_corr[i]) { @@ -131,6 +139,7 @@ void srslte_sync_free(srslte_sync_t *q) { srslte_pss_synch_free(&q->pss); srslte_sss_synch_free(&q->sss); srslte_cfo_free(&q->cfocorr); + srslte_cfo_free(&q->cfocorr2); srslte_cp_synch_free(&q->cp_synch); for (int i=0;i<2;i++) { if (q->cfo_i_corr[i]) { @@ -433,7 +442,7 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha); /* Correct CFO with the averaged CFO estimation */ - srslte_cfo_correct(&q->cfocorr, input, q->temp, -q->mean_cfo / q->fft_size); + srslte_cfo_correct(&q->cfocorr2, input, q->temp, -q->mean_cfo / q->fft_size); input_cfo = q->temp; } From 3ff153f06a6582ca004772dee3b372577208e033 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 6 Oct 2016 20:29:34 +0200 Subject: [PATCH 041/111] minor print formatting --- srslte/examples/cell_measurement.c | 2 +- srslte/lib/ue/ue_sync.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index 616d77df0..de9962513 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -356,7 +356,7 @@ int main(int argc, char **argv) { printf("CFO: %+8.4f kHz, SFO: %+8.4f kHz, RSSI: %5.1f dBm, RSSI/ref-symbol: %+5.1f dBm, " "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r", - srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000, + srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync), 10*log10(rssi*1000) - rx_gain_offset, 10*log10(rssi_utra*1000)- rx_gain_offset, 10*log10(rsrp*1000) - rx_gain_offset, diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 603eb9e15..6ef05daff 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -451,7 +451,7 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { if (q->next_rf_sample_offset < 0) { q->next_rf_sample_offset = -q->next_rf_sample_offset; } - + /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ if (q->recv_callback(q->stream, &input_buffer[q->next_rf_sample_offset], q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { return SRSLTE_ERROR; @@ -529,7 +529,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { break; case SRSLTE_SYNC_FOUND_NOSPACE: /* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */ - printf("No space for SSS/CP detection. Realigning frame...\n"); + INFO("No space for SSS/CP detection. Realigning frame...\n",0); q->recv_callback(q->stream, dummy_offset_buffer, q->frame_len/2, NULL); srslte_sync_reset(&q->sfind); ret = SRSLTE_SUCCESS; From 383dfa63fe989c2229eb1e26fca2b8fd748e0bc9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 18 Oct 2016 10:39:32 +0200 Subject: [PATCH 042/111] rf_uhd: added option for external clock reference --- srslte/lib/rf/rf_uhd_imp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index 57b61cc98..5ada6165a 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -245,7 +245,7 @@ int rf_uhd_open(char *args, void **h) /* Set priority to UHD threads */ uhd_set_thread_priority(uhd_default_thread_priority, true); - /* Set correct options for the USRP device */ + /* Find available devices */ uhd_string_vector_handle devices_str; uhd_string_vector_make(&devices_str); uhd_usrp_find("", &devices_str); @@ -312,6 +312,11 @@ int rf_uhd_open(char *args, void **h) .channel_list = &channel, .n_channels = 1 }; + + // Set external clock reference + if (strstr(args, "clock=external")) { + uhd_usrp_set_clock_source(handler->usrp, "external", 0); + } handler->has_rssi = get_has_rssi(handler); if (handler->has_rssi) { From ea4a81c8d02524c06127edd300d0fd9e73d5c9a6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 18 Oct 2016 10:39:49 +0200 Subject: [PATCH 043/111] added pucch enodeb receiver --- .../include/srslte/ch_estimation/chest_ul.h | 8 + .../srslte/ch_estimation/refsignal_ul.h | 24 +- srslte/include/srslte/enb/enb_ul.h | 26 +- srslte/include/srslte/phch/prach.h | 3 +- srslte/include/srslte/phch/pucch.h | 31 ++- srslte/lib/ch_estimation/chest_ul.c | 62 +++++ srslte/lib/ch_estimation/refsignal_ul.c | 58 +++-- srslte/lib/enb/enb_ul.c | 100 +++++++- srslte/lib/phch/pucch.c | 236 ++++++++++++++---- srslte/lib/phch/test/CMakeLists.txt | 2 +- 10 files changed, 463 insertions(+), 87 deletions(-) diff --git a/srslte/include/srslte/ch_estimation/chest_ul.h b/srslte/include/srslte/ch_estimation/chest_ul.h index 37800d02a..90a706cc7 100644 --- a/srslte/include/srslte/ch_estimation/chest_ul.h +++ b/srslte/include/srslte/ch_estimation/chest_ul.h @@ -57,6 +57,7 @@ typedef struct { cf_t *pilot_estimates; cf_t *pilot_recv_signal; + cf_t *pilot_known_signal; cf_t *tmp_noise; #ifdef FREQ_SEL_SNR @@ -99,6 +100,13 @@ SRSLTE_API int srslte_chest_ul_estimate(srslte_chest_ul_t *q, uint32_t cyclic_shift_for_dmrs, uint32_t n_prb[2]); +SRSLTE_API int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, + cf_t *input, + cf_t *ce, + srslte_pucch_format_t format, + uint32_t n_pucch, + uint32_t sf_idx); + SRSLTE_API float srslte_chest_ul_get_noise_estimate(srslte_chest_ul_t *q); SRSLTE_API float srslte_chest_ul_get_snr(srslte_chest_ul_t *q); diff --git a/srslte/include/srslte/ch_estimation/refsignal_ul.h b/srslte/include/srslte/ch_estimation/refsignal_ul.h index 0d8b7f5fb..1c6814b63 100644 --- a/srslte/include/srslte/ch_estimation/refsignal_ul.h +++ b/srslte/include/srslte/ch_estimation/refsignal_ul.h @@ -46,6 +46,7 @@ #define SRSLTE_REFSIGNAL_UL_L(ns_idx, cp) ((ns_idx+1)*SRSLTE_CP_NSYMB(cp)-4) +/* PUSCH DMRS common configuration (received in SIB2) */ typedef struct SRSLTE_API { uint32_t cyclic_shift; uint32_t delta_ss; @@ -53,15 +54,19 @@ typedef struct SRSLTE_API { bool sequence_hopping_en; }srslte_refsignal_dmrs_pusch_cfg_t; + typedef struct SRSLTE_API { + // Common Configuration uint32_t subframe_config; - uint32_t I_srs; uint32_t bw_cfg; + + // Dedicated configuration + uint32_t B; + uint32_t b_hop; uint32_t n_srs; + uint32_t I_srs; uint32_t k_tc; uint32_t n_rrc; - uint32_t B; - uint32_t b_hop; bool configured; }srslte_refsignal_srs_cfg_t; @@ -101,6 +106,13 @@ SRSLTE_API void srslte_refsignal_ul_set_cfg(srslte_refsignal_ul_t *q, SRSLTE_API void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u); +SRSLTE_API uint32_t srslte_refsignal_dmrs_N_rs(srslte_pucch_format_t format, + srslte_cp_t cp); + +SRSLTE_API uint32_t srslte_refsignal_dmrs_pucch_symbol(uint32_t m, + srslte_pucch_format_t format, + srslte_cp_t cp); + SRSLTE_API bool srslte_refsignal_dmrs_pusch_cfg_isvalid(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t nof_prb); @@ -150,6 +162,12 @@ SRSLTE_API int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t* q, cf_t *r_pucch, cf_t *output); +SRSLTE_API int srslte_refsignal_dmrs_pucch_get(srslte_refsignal_ul_t* q, + srslte_pucch_format_t format, + uint32_t n_pucch, + cf_t *input, + cf_t *r_pucch); + SRSLTE_API int srslte_refsignal_srs_pregen(srslte_refsignal_ul_t *q, srslte_refsignal_srs_pregen_t *pregen); diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index c636c994b..59fd02065 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -73,7 +73,15 @@ typedef struct SRSLTE_API { srslte_prach_t prach; srslte_pusch_cfg_t pusch_cfg; - + + srslte_pusch_hopping_cfg_t hopping_cfg; + + // Configuration for each user + bool *uci_cfg_en; + bool *srs_cfg_en; + srslte_uci_cfg_t *uci_cfg; + srslte_refsignal_srs_cfg_t *srs_cfg; + } srslte_enb_ul_t; typedef struct { @@ -85,6 +93,7 @@ typedef struct { bool needs_pdcch; uint8_t *data; srslte_softbuffer_rx_t *softbuffer; + } srslte_enb_ul_pusch_t; /* This function shall be called just after the initial synchronization */ @@ -92,6 +101,7 @@ SRSLTE_API int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, srslte_prach_cfg_t* prach_cfg, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_pucch_cfg_t *pucch_cfg, uint32_t nof_rntis); @@ -101,12 +111,24 @@ SRSLTE_API int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, uint32_t idx, uint16_t rnti); +SRSLTE_API int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, + srslte_uci_cfg_t *uci_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg); + + SRSLTE_API int srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, uint32_t idx); SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer); +SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, + srslte_pucch_format_t format, + uint32_t n_pucch, + uint32_t rnti_idx, + srslte_uci_data_t *uci_data, + uint32_t tti); + SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer, @@ -123,7 +145,7 @@ SRSLTE_API int srslte_enb_ul_detect_prach(srslte_enb_ul_t *q, cf_t *signal, uint32_t *indices, float *offsets, - float *peak2avg); + float *peak2avg); #endif diff --git a/srslte/include/srslte/phch/prach.h b/srslte/include/srslte/phch/prach.h index 8221fc434..346447e8b 100644 --- a/srslte/include/srslte/phch/prach.h +++ b/srslte/include/srslte/phch/prach.h @@ -110,7 +110,8 @@ typedef enum SRSLTE_API { typedef struct { uint32_t config_idx; uint32_t root_seq_idx; - uint32_t zero_corr_zone; + uint32_t zero_corr_zone; + uint32_t freq_offset; bool hs_flag; } srslte_prach_cfg_t; diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index 92b493fa4..66062b057 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -64,15 +64,18 @@ typedef struct SRSLTE_API { }srslte_pucch_sched_t; typedef struct SRSLTE_API { + // Common configuration uint32_t delta_pucch_shift; uint32_t n_rb_2; uint32_t N_cs; + + // SRS configuration bool srs_configured; uint32_t srs_cs_subf_cfg; bool srs_simul_ack; } srslte_pucch_cfg_t; -/* PUSCH object */ +/* PUCCH object */ typedef struct SRSLTE_API { srslte_cell_t cell; srslte_pucch_cfg_t pucch_cfg; @@ -85,9 +88,15 @@ typedef struct SRSLTE_API { uint32_t f_gh[SRSLTE_NSLOTS_X_FRAME]; float tmp_arg[SRSLTE_PUCCH_N_SEQ]; cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS]; + cf_t z_tmp[SRSLTE_PUCCH_MAX_SYMBOLS]; + cf_t ce[SRSLTE_PUCCH_MAX_SYMBOLS]; bool rnti_is_set; bool shortened; bool group_hopping_en; + + float threshold_format1; + float threshold_format1a; + }srslte_pucch_t; @@ -100,6 +109,10 @@ SRSLTE_API bool srslte_pucch_set_cfg(srslte_pucch_t* q, srslte_pucch_cfg_t* cfg, bool group_hopping_en); +SRSLTE_API void srslte_pucch_set_threshold(srslte_pucch_t *q, + float format1, + float format1a); + SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q, uint16_t c_rnti); @@ -114,6 +127,15 @@ SRSLTE_API int srslte_pucch_encode(srslte_pucch_t *q, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t *sf_symbols); +SRSLTE_API int srslte_pucch_decode(srslte_pucch_t *q, + srslte_pucch_format_t format, + uint32_t n_pucch, // n_pucch_1 or n_pucch_2 depending on format + uint32_t sf_idx, + cf_t *sf_symbols, + cf_t *ce, + float noise_estimate, + uint8_t bits[SRSLTE_PUCCH_MAX_BITS]); + SRSLTE_API float srslte_pucch_alpha_format1(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB], srslte_pucch_cfg_t *cfg, uint32_t n_pucch, @@ -135,6 +157,13 @@ SRSLTE_API uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, uint32_t n_pucch, srslte_cp_t cp); +SRSLTE_API uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, + srslte_pucch_format_t format, + uint32_t n_pucch, + uint32_t nof_prb, + srslte_cp_t cp, + uint32_t ns); + SRSLTE_API int srslte_pucch_n_cs_cell(srslte_cell_t cell, uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB]); diff --git a/srslte/lib/ch_estimation/chest_ul.c b/srslte/lib/ch_estimation/chest_ul.c index c61e88c7d..a75d2a7a3 100644 --- a/srslte/lib/ch_estimation/chest_ul.c +++ b/srslte/lib/ch_estimation/chest_ul.c @@ -84,6 +84,12 @@ int srslte_chest_ul_init(srslte_chest_ul_t *q, srslte_cell_t cell) goto clean_exit; } + q->pilot_known_signal = srslte_vec_malloc(sizeof(cf_t) * (NOF_REFS_SF+1)); + if (!q->pilot_known_signal) { + perror("malloc"); + goto clean_exit; + } + if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, NOF_REFS_SYM)) { fprintf(stderr, "Error initializing vector interpolator\n"); goto clean_exit; @@ -122,6 +128,9 @@ void srslte_chest_ul_free(srslte_chest_ul_t *q) if (q->pilot_recv_signal) { free(q->pilot_recv_signal); } + if (q->pilot_known_signal) { + free(q->pilot_known_signal); + } bzero(q, sizeof(srslte_chest_ul_t)); } @@ -252,6 +261,59 @@ int srslte_chest_ul_estimate(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, return 0; } +int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, + srslte_pucch_format_t format, uint32_t n_pucch, uint32_t sf_idx) +{ + if (!q->dmrs_signal_configured) { + fprintf(stderr, "Error must call srslte_chest_ul_set_cfg() before using the UL estimator\n"); + return SRSLTE_ERROR; + } + + int n_rs = srslte_refsignal_dmrs_N_rs(format, q->cell.cp); + int nrefs_sf = SRSLTE_NRE*n_rs*2; + + /* Get references from the input signal */ + srslte_refsignal_dmrs_pucch_get(&q->dmrs_signal, format, n_pucch, input, q->pilot_recv_signal); + + /* Generate known pilots */ + uint8_t pucch2_bits[2] = {0, 0}; + srslte_refsignal_dmrs_pucch_gen(&q->dmrs_signal, format, n_pucch, sf_idx, pucch2_bits, q->pilot_known_signal), + + /* Use the known DMRS signal to compute Least-squares estimates */ + srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates, nrefs_sf); + + if (ce != NULL) { + /* FIXME: Currently averaging entire slot, performance good enough? */ + for (int ns=0;ns<2;ns++) { + // Average all slot + for (int i=1;ipilot_estimates[ns*n_rs*SRSLTE_NRE], &q->pilot_estimates[(i+ns*n_rs)*SRSLTE_NRE], + &q->pilot_estimates[ns*n_rs*SRSLTE_NRE], + SRSLTE_NRE); + } + srslte_vec_sc_prod_ccc(&q->pilot_estimates[ns*n_rs*SRSLTE_NRE], (float) 1.0/n_rs, + &q->pilot_estimates[ns*n_rs*SRSLTE_NRE], + SRSLTE_NRE); + + // Average in freq domain + srslte_chest_average_pilots(&q->pilot_estimates[ns*n_rs*SRSLTE_NRE], &q->pilot_recv_signal[ns*n_rs*SRSLTE_NRE], + q->smooth_filter, SRSLTE_NRE, 1, q->smooth_filter_len); + + // Determine n_prb + uint32_t n_prb = srslte_pucch_n_prb(&q->dmrs_signal.pucch_cfg, format, n_pucch, q->cell.nof_prb, q->cell.cp, ns); + + // copy estimates to slot + for (int i=0;icell.cp);i++) { + memcpy(&ce[SRSLTE_RE_IDX(q->cell.nof_prb, i+ns*SRSLTE_CP_NSYMB(q->cell.cp), n_prb*SRSLTE_NRE)], + &q->pilot_recv_signal[ns*n_rs*SRSLTE_NRE], sizeof(cf_t)*SRSLTE_NRE); + } + } + } + + return 0; +} + + float srslte_chest_ul_get_noise_estimate(srslte_chest_ul_t *q) { return q->noise_estimate; } diff --git a/srslte/lib/ch_estimation/refsignal_ul.c b/srslte/lib/ch_estimation/refsignal_ul.c index 30aa7da08..f85b33c19 100644 --- a/srslte/lib/ch_estimation/refsignal_ul.c +++ b/srslte/lib/ch_estimation/refsignal_ul.c @@ -452,7 +452,7 @@ int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, uint32_t nof_prb, } /* Number of PUCCH demodulation reference symbols per slot N_rs_pucch tABLE 5.5.2.2.1-1 36.211 */ -static uint32_t get_N_rs(srslte_pucch_format_t format, srslte_cp_t cp) { +uint32_t srslte_refsignal_dmrs_N_rs(srslte_pucch_format_t format, srslte_cp_t cp) { switch (format) { case SRSLTE_PUCCH_FORMAT_1: case SRSLTE_PUCCH_FORMAT_1A: @@ -476,7 +476,7 @@ static uint32_t get_N_rs(srslte_pucch_format_t format, srslte_cp_t cp) { } /* Table 5.5.2.2.2-1: Demodulation reference signal location for different PUCCH formats. 36.211 */ -static uint32_t get_pucch_dmrs_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t cp) { +uint32_t srslte_refsignal_dmrs_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t cp) { switch (format) { case SRSLTE_PUCCH_FORMAT_1: case SRSLTE_PUCCH_FORMAT_1A: @@ -523,7 +523,7 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma if (q && r_pucch) { ret = SRSLTE_ERROR; - uint32_t N_rs=get_N_rs(format, q->cell.cp); + uint32_t N_rs=srslte_refsignal_dmrs_N_rs(format, q->cell.cp); cf_t z_m_1 = 1.0; if (format == SRSLTE_PUCCH_FORMAT_2A || format == SRSLTE_PUCCH_FORMAT_2B) { @@ -543,7 +543,7 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma for (uint32_t m=0;mcell.cp); + uint32_t l = srslte_refsignal_dmrs_pucch_symbol(m, format, q->cell.cp); // Add cyclic prefix alpha float alpha = 0.0; if (format < SRSLTE_PUCCH_FORMAT_2) { @@ -594,36 +594,48 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma return ret; } -/* Maps PUCCH DMRS to the physical resources as defined in 5.5.2.2.2 in 36.211 */ -int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *r_pucch, cf_t *output) +int srslte_refsignal_dmrs_pucch_cp(srslte_refsignal_ul_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *source, cf_t *dest, bool source_is_grid) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - if (q && output && r_pucch) { + if (q && source && dest) { ret = SRSLTE_ERROR; uint32_t nsymbols = SRSLTE_CP_ISNORM(q->cell.cp)?SRSLTE_CP_NORM_NSYMB:SRSLTE_CP_EXT_NSYMB; - - // Determine m - uint32_t m = srslte_pucch_m(&q->pucch_cfg, format, n_pucch, q->cell.cp); - - uint32_t N_rs = get_N_rs(format, q->cell.cp); + + uint32_t N_rs = srslte_refsignal_dmrs_N_rs(format, q->cell.cp); for (uint32_t ns=0;ns<2;ns++) { - // Determine n_prb - uint32_t n_prb = m/2; - if ((m+ns)%2) { - n_prb = q->cell.nof_prb-1-m/2; - } - + + // Determine n_prb + uint32_t n_prb = srslte_pucch_n_prb(&q->pucch_cfg, format, n_pucch, q->cell.nof_prb, q->cell.cp, ns); + for (uint32_t i=0;icell.cp); - memcpy(&output[SRSLTE_RE_IDX(q->cell.nof_prb, l+ns*nsymbols, n_prb*SRSLTE_NRE)], - &r_pucch[ns*N_rs*SRSLTE_NRE+i*SRSLTE_NRE], - SRSLTE_NRE*sizeof(cf_t)); + uint32_t l = srslte_refsignal_dmrs_pucch_symbol(i, format, q->cell.cp); + if (!source_is_grid) { + memcpy(&dest[SRSLTE_RE_IDX(q->cell.nof_prb, l+ns*nsymbols, n_prb*SRSLTE_NRE)], + &source[ns*N_rs*SRSLTE_NRE+i*SRSLTE_NRE], + SRSLTE_NRE*sizeof(cf_t)); + } else { + memcpy(&dest[ns*N_rs*SRSLTE_NRE+i*SRSLTE_NRE], + &source[SRSLTE_RE_IDX(q->cell.nof_prb, l+ns*nsymbols, n_prb*SRSLTE_NRE)], + SRSLTE_NRE*sizeof(cf_t)); + } } } ret = SRSLTE_SUCCESS; } - return ret; + return ret; +} + +/* Maps PUCCH DMRS to the physical resources as defined in 5.5.2.2.2 in 36.211 */ +int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *r_pucch, cf_t *output) +{ + return srslte_refsignal_dmrs_pucch_cp(q, format, n_pucch, r_pucch, output, false); +} + +/* Gets PUCCH DMRS from the physical resources as defined in 5.5.2.2.2 in 36.211 */ +int srslte_refsignal_dmrs_pucch_get(srslte_refsignal_ul_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *input, cf_t *r_pucch) +{ + return srslte_refsignal_dmrs_pucch_cp(q, format, n_pucch, input, r_pucch, true); } diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 01940f5b0..a5b16ea3f 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -42,6 +42,7 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, srslte_prach_cfg_t *prach_cfg, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_pucch_cfg_t *pucch_cfg, uint32_t nof_rnti) { @@ -57,6 +58,16 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, q->cell = cell; q->nof_rnti = nof_rnti; + if (hopping_cfg) { + memcpy(&q->hopping_cfg, hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t)); + } + + q->uci_cfg_en = calloc(sizeof(bool),nof_rnti); + q->srs_cfg_en = calloc(sizeof(bool),nof_rnti); + + q->uci_cfg = calloc(sizeof(srslte_uci_cfg_t),nof_rnti); + q->srs_cfg = calloc(sizeof(srslte_refsignal_srs_cfg_t),nof_rnti); + if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); goto clean_exit; @@ -91,6 +102,9 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, goto clean_exit; } + // Configure common PUCCH configuration + srslte_pucch_set_cfg(&q->pucch, pucch_cfg, pusch_cfg->group_hopping_en); + // SRS is a dedicated configuration srslte_chest_ul_set_cfg(&q->chest, pusch_cfg, pucch_cfg, NULL); @@ -123,6 +137,20 @@ clean_exit: void srslte_enb_ul_free(srslte_enb_ul_t *q) { if (q) { + + if (q->uci_cfg) { + free(q->uci_cfg); + } + if (q->uci_cfg_en) { + free(q->uci_cfg_en); + } + if (q->srs_cfg) { + free(q->srs_cfg); + } + if (q->srs_cfg_en) { + free(q->srs_cfg_en); + } + srslte_prach_free(&q->prach); srslte_ofdm_rx_free(&q->fft); srslte_pucch_free(&q->pucch); @@ -143,6 +171,30 @@ int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, uint32_t idx, uint16_t rnti) return srslte_pusch_set_rnti_multi(&q->pusch, idx, rnti); } +int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, + srslte_uci_cfg_t *uci_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg) +{ + if (idx < q->nof_rnti) { + if (uci_cfg) { + memcpy(&q->uci_cfg[idx], uci_cfg, sizeof(srslte_uci_cfg_t)); + q->uci_cfg_en[idx] = true; + } else { + q->uci_cfg_en[idx] = false; + } + if (srs_cfg) { + memcpy(&q->srs_cfg[idx], srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); + q->srs_cfg_en[idx] = true; + } else { + q->srs_cfg_en[idx] = false; + } + return SRSLTE_SUCCESS; + } else { + fprintf(stderr, "Error configuring UE: Invalid idx=%d, max users=%d\n", idx, q->nof_rnti); + return SRSLTE_ERROR; + } +} + int srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, uint32_t idx) { return srslte_pusch_set_rnti_multi(&q->pusch, idx, 0); @@ -153,12 +205,58 @@ void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); } +int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, uint32_t n_pucch, + uint32_t rnti_idx, srslte_uci_data_t *uci_data, uint32_t tti) +{ + + if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, tti%10)) { + fprintf(stderr,"Error estimating PUCCH DMRS\n"); + return SRSLTE_ERROR; + } + + float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); + + uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; + if (srslte_pucch_decode(&q->pucch, format, n_pucch, tti%10, q->sf_symbols, q->ce, noise_power, bits)) { + fprintf(stderr,"Error decoding PUCCH\n"); + return SRSLTE_ERROR; + } + + switch(format) { + case SRSLTE_PUCCH_FORMAT_1: + if (bits[0]) { + uci_data->scheduling_request = true; + } + break; + case SRSLTE_PUCCH_FORMAT_1A: + case SRSLTE_PUCCH_FORMAT_1B: + uci_data->uci_ack = bits[0]; + uci_data->uci_ack_len = 1; + if (format == SRSLTE_PUCCH_FORMAT_1B) { + uci_data->uci_ack_2 = bits[0]; + uci_data->uci_ack_len = 2; + } + break; + default: + fprintf(stderr, "Error getting PUCCH format %d not supported\n"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer, uint32_t rnti_idx, uint32_t rv_idx, uint32_t current_tx_nb, uint8_t *data, srslte_uci_data_t *uci_data, uint32_t tti) { - if (srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, grant, NULL, NULL, NULL, tti, rv_idx, current_tx_nb)) { + if (srslte_pusch_cfg(&q->pusch, + &q->pusch_cfg, + grant, + q->uci_cfg_en[rnti_idx]?&q->uci_cfg[rnti_idx]:NULL, + &q->hopping_cfg, + q->srs_cfg_en[rnti_idx]?&q->srs_cfg[rnti_idx]:NULL, + tti, rv_idx, current_tx_nb)) { fprintf(stderr, "Error configuring PDSCH\n"); return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index fb2419be0..30fdb66b7 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -38,6 +38,7 @@ #include "srslte/phch/pucch.h" #include "srslte/common/sequence.h" #include "srslte/common/phy_common.h" +#include "srslte/mimo/precoding.h" #include "srslte/scrambling/scrambling.h" #include "srslte/utils/debug.h" #include "srslte/utils/vector.h" @@ -159,6 +160,17 @@ uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t return 0; } +uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, + uint32_t nof_prb, srslte_cp_t cp, uint32_t ns) +{ + uint32_t m = srslte_pucch_m(cfg, format, n_pucch, cp); + // Determine n_prb + uint32_t n_prb = m/2; + if ((m+ns)%2) { + n_prb = nof_prb-1-m/2; + } + return n_prb; +} // Compute m according to Section 5.4.3 of 36.211 uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, srslte_cp_t cp) { @@ -250,6 +262,9 @@ float srslte_pucch_alpha_format1(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLT n_cs = (n_cs_cell[ns][l]+(n_prime*cfg->delta_pucch_shift+n_oc/n_oc_div)%N_prime)%SRSLTE_NRE; } + DEBUG("n_cs=%d, N_prime=%d, delta_pucch=%d, n_prime=%d, ns=%d, l=%d, ns_cs_cell=%d\n", + n_cs, N_prime, cfg->delta_pucch_shift, n_prime, ns, l, n_cs_cell[ns][l]); + return 2 * M_PI * (n_cs) / SRSLTE_NRE; } @@ -281,40 +296,55 @@ float srslte_pucch_alpha_format2(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLT } /* Map PUCCH symbols to physical resources according to 5.4.3 in 36.211 */ -static int pucch_put(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *output) { +static int pucch_cp(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *source, cf_t *dest, bool source_is_grid) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - if (q && output) { + if (q && source && dest) { ret = SRSLTE_ERROR; uint32_t nsymbols = SRSLTE_CP_ISNORM(q->cell.cp)?SRSLTE_CP_NORM_NSYMB:SRSLTE_CP_EXT_NSYMB; - // Determine m - uint32_t m = srslte_pucch_m(&q->pucch_cfg, format, n_pucch, q->cell.cp); - + uint32_t n_re = 0; uint32_t N_sf_0 = get_N_sf(format, 0, q->shortened); for (uint32_t ns=0;ns<2;ns++) { uint32_t N_sf = get_N_sf(format, ns%2, q->shortened); - // Determine n_prb - uint32_t n_prb = m/2; - if ((m+ns)%2) { - n_prb = q->cell.nof_prb-1-m/2; - } + + // Determine n_prb + uint32_t n_prb = srslte_pucch_n_prb(&q->pucch_cfg, format, n_pucch, q->cell.nof_prb, q->cell.cp, ns); if (n_prb < q->cell.nof_prb) { for (uint32_t i=0;icell.cp); - memcpy(&output[SRSLTE_RE_IDX(q->cell.nof_prb, l+ns*nsymbols, n_prb*SRSLTE_NRE)], - &q->z[i*SRSLTE_NRE+ns*N_sf_0*SRSLTE_NRE], - SRSLTE_NRE*sizeof(cf_t)); + if (!source_is_grid) { + memcpy(&dest[SRSLTE_RE_IDX(q->cell.nof_prb, l+ns*nsymbols, n_prb*SRSLTE_NRE)], + &source[i*SRSLTE_NRE+ns*N_sf_0*SRSLTE_NRE], + SRSLTE_NRE*sizeof(cf_t)); + } else { + memcpy(&dest[i*SRSLTE_NRE+ns*N_sf_0*SRSLTE_NRE], + &source[SRSLTE_RE_IDX(q->cell.nof_prb, l+ns*nsymbols, n_prb*SRSLTE_NRE)], + SRSLTE_NRE*sizeof(cf_t)); + } + n_re += SRSLTE_NRE; } } else { return SRSLTE_ERROR; } } - ret = SRSLTE_SUCCESS; + ret = n_re; } return ret; } +static int pucch_put(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *z, cf_t *output) { + return pucch_cp(q, format, n_pucch, z, output, false); +} + +static int pucch_get(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n_pucch, cf_t *input, cf_t *z) { + return pucch_cp(q, format, n_pucch, input, z, true); +} + +void srslte_pucch_set_threshold(srslte_pucch_t *q, float format1, float format1a) { + q->threshold_format1 = format1; + q->threshold_format1a = format1a; +} /** Initializes the PDCCH transmitter and receiver */ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) { @@ -470,9 +500,59 @@ static int uci_mod_bits(srslte_pucch_t *q, srslte_pucch_format_t format, uint8_t // Declare this here, since we can not include refsignal_ul.h void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u); +static int pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, + uint32_t n_pucch, uint32_t sf_idx, + uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS]) +{ + if (uci_mod_bits(q, format, bits, sf_idx)) { + fprintf(stderr, "Error encoding PUCCH bits\n"); + return SRSLTE_ERROR; + } + uint32_t N_sf_0 = get_N_sf(format, 0, q->shortened); + for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) { + uint32_t N_sf = get_N_sf(format, ns%2, q->shortened); + DEBUG("ns=%d, N_sf=%d\n", ns, N_sf); + // Get group hopping number u + uint32_t f_gh=0; + if (q->group_hopping_en) { + f_gh = q->f_gh[ns]; + } + uint32_t u = (f_gh + (q->cell.id%30))%30; + + srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u); + uint32_t N_sf_widx = N_sf==3?1:0; + for (uint32_t m=0;mcell.cp); + float alpha=0; + if (format >= SRSLTE_PUCCH_FORMAT_2) { + alpha = srslte_pucch_alpha_format2(q->n_cs_cell, &q->pucch_cfg, n_pucch, ns, l); + for (uint32_t n=0;nd[(ns%2)*N_sf+m]*cexpf(I*(q->tmp_arg[n]+alpha*n)); + } + } else { + uint32_t n_prime_ns=0; + uint32_t n_oc=0; + alpha = srslte_pucch_alpha_format1(q->n_cs_cell, &q->pucch_cfg, n_pucch, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns); + float S_ns = 0; + if (n_prime_ns%2) { + S_ns = M_PI/2; + } + DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n", + __real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2); + for (uint32_t n=0;nd[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns)); + } + } + } + } + return SRSLTE_SUCCESS; +} + /* Encode, modulate and resource mapping of PUCCH bits according to Section 5.4.1 of 36.211 */ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, - uint32_t n_pucch, uint32_t sf_idx, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t *sf_symbols) + uint32_t n_pucch, uint32_t sf_idx, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], + cf_t *sf_symbols) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && @@ -496,56 +576,102 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, fprintf(stderr, "Error encoding PUCCH: C-RNTI must be set before encoding PUCCH Format 2/2a/2b\n"); return SRSLTE_ERROR; } - if (uci_mod_bits(q, format, bits, sf_idx)) { - fprintf(stderr, "Error encoding PUCCH bits\n"); + if (pucch_encode(q, format, n_pucch, sf_idx, bits, q->z)) { return SRSLTE_ERROR; } - uint32_t N_sf_0 = get_N_sf(format, 0, q->shortened); - for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) { - uint32_t N_sf = get_N_sf(format, ns%2, q->shortened); - DEBUG("ns=%d, N_sf=%d\n", ns, N_sf); - // Get group hopping number u - uint32_t f_gh=0; - if (q->group_hopping_en) { - f_gh = q->f_gh[ns]; + if (pucch_put(q, format, n_pucch, q->z, sf_symbols) < 0) { + fprintf(stderr, "Error putting PUCCH symbols\n"); + return SRSLTE_ERROR; + } + ret = SRSLTE_SUCCESS; + } + + return ret; +} + + +/* Equalize, demodulate and decode PUCCH bits according to Section 5.4.1 of 36.211 */ +int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, + uint32_t n_pucch, uint32_t sf_idx, cf_t *sf_symbols, cf_t *ce, float noise_estimate, + uint8_t bits[SRSLTE_PUCCH_MAX_BITS]) +{ + int ret = SRSLTE_ERROR_INVALID_INPUTS; + if (q != NULL && + ce != NULL && + sf_symbols != NULL) + { + ret = SRSLTE_ERROR; + + // Shortened PUCCH happen in every cell-specific SRS subframes for Format 1/1a/1b + if (q->pucch_cfg.srs_configured && format < SRSLTE_PUCCH_FORMAT_2) { + q->shortened = false; + // If CQI is not transmitted, PUCCH will be normal unless ACK/NACK and SRS simultaneous transmission is enabled + if (q->pucch_cfg.srs_simul_ack) { + // If simultaneous ACK and SRS is enabled, PUCCH is shortened in cell-specific SRS subframes + if (srslte_refsignal_srs_send_cs(q->pucch_cfg.srs_cs_subf_cfg, sf_idx) == 1) { + q->shortened = true; + } } - uint32_t u = (f_gh + (q->cell.id%30))%30; - - srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u); - uint32_t N_sf_widx = N_sf==3?1:0; - for (uint32_t m=0;mcell.cp); - float alpha=0; - if (format >= SRSLTE_PUCCH_FORMAT_2) { - alpha = srslte_pucch_alpha_format2(q->n_cs_cell, &q->pucch_cfg, n_pucch, ns, l); - for (uint32_t n=0;nz[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->d[(ns%2)*N_sf+m]*cexpf(I*(q->tmp_arg[n]+alpha*n)); - } + } + + if (format >= SRSLTE_PUCCH_FORMAT_2 && !q->rnti_is_set) { + fprintf(stderr, "Error decoding PUCCH: C-RNTI must be set before encoding PUCCH Format 2/2a/2b\n"); + return SRSLTE_ERROR; + } + int nof_re = pucch_get(q, format, n_pucch, sf_symbols, q->z_tmp); + if (nof_re < 0) { + fprintf(stderr, "Error getting PUCCH symbols\n"); + return SRSLTE_ERROR; + } + + if (pucch_get(q, format, n_pucch, ce, q->ce) < 0) { + fprintf(stderr, "Error getting PUCCH symbols\n"); + return SRSLTE_ERROR; + } + + // Equalization + srslte_predecoding_single(q->z_tmp, q->ce, q->z, nof_re, noise_estimate); + + // Perform ML-decoding + float corr=0, corr_max=-1e9; + int b_max = 0; // default bit value, eg. HI is NACK + switch(format) { + case SRSLTE_PUCCH_FORMAT_1: + bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); + pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); + corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; + if (corr >= q->threshold_format1) { + bits[0] = 1; } else { - uint32_t n_prime_ns=0; - uint32_t n_oc=0; - alpha = srslte_pucch_alpha_format1(q->n_cs_cell, &q->pucch_cfg, n_pucch, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns); - float S_ns = 0; - if (n_prime_ns%2) { - S_ns = M_PI/2; + bits[0] = 0; + } + printf("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, q->threshold_format1); + break; + case SRSLTE_PUCCH_FORMAT_1A: + bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); + + for (int b=0;b<2;b++) { + bits[0] = b; + pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); + corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; + if (corr > corr_max && corr >= q->threshold_format1a) { + corr_max = corr; + b_max = b; } - DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n", - __real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2); - for (uint32_t n=0;nz[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = - q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns)); - } + DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1); } - } - } - if (pucch_put(q, format, n_pucch, sf_symbols)) { - fprintf(stderr, "Error putting PUCCH symbols\n"); - return SRSLTE_ERROR; + bits[0] = b_max; + break; + default: + fprintf(stderr, "Error decoding PUCCH: Format %d not supported\n", format); + break; } + ret = SRSLTE_SUCCESS; } return ret; } - + + \ No newline at end of file diff --git a/srslte/lib/phch/test/CMakeLists.txt b/srslte/lib/phch/test/CMakeLists.txt index 90c658e66..6675e0faf 100644 --- a/srslte/lib/phch/test/CMakeLists.txt +++ b/srslte/lib/phch/test/CMakeLists.txt @@ -146,7 +146,7 @@ target_link_libraries(pucch_test srslte) add_test(pucch_test pucch_test) BuildMex(MEXNAME pucch_encode SOURCES pucch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) - +BuildMex(MEXNAME pucch SOURCES pucch_test_mex.c LIBRARIES srslte_static srslte_mex) From 6b20636b63a84052682de696ed34f375680201ca Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 18 Oct 2016 10:56:07 +0200 Subject: [PATCH 044/111] add matlab pucch tests --- matlab/tests/pucch_bler.m | 133 +++++++++++++++ srslte/lib/enb/enb_ul.c | 2 +- srslte/lib/phch/test/pucch_test_mex.c | 225 ++++++++++++++++++++++++++ srslte/lib/rf/rf_uhd_imp.c | 2 +- 4 files changed, 360 insertions(+), 2 deletions(-) create mode 100644 matlab/tests/pucch_bler.m create mode 100644 srslte/lib/phch/test/pucch_test_mex.c diff --git a/matlab/tests/pucch_bler.m b/matlab/tests/pucch_bler.m new file mode 100644 index 000000000..4bac59411 --- /dev/null +++ b/matlab/tests/pucch_bler.m @@ -0,0 +1,133 @@ +clear +ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',25,'NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off'); +pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',2); + +format_str={'1','1a'}; + +threshold=[0.5 0]; +formats=[1]; +pucchConfig.ResourceIdx= 0; +pucchConfig.DeltaShift = 1; +pucchConfig.CyclicShifts = 0; +ueConfig.NSubframe=0; + +enable_fading=false; + +SNR_values=-5;%linspace(-8,0,8); +Nreal=50; + +% Setup Fading channel model +cfg.Seed = 8; % Random channel seed +cfg.NRxAnts = 1; % 1 receive antenna +cfg.DelayProfile = 'EVA'; % EVA delay spread +cfg.DopplerFreq = 5; % 120Hz Doppler frequency +cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation +cfg.InitTime = 0; % Initialize at time zero +cfg.NTerms = 16; % Oscillators used in fading model +cfg.ModelType = 'GMEDS'; % Rayleigh fading model type +cfg.InitPhase = 'Random'; % Random initial phases +cfg.NormalizePathGains = 'On'; % Normalize delay profile power +cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas + +% Setup matlab channel equalizer +cec.PilotAverage = 'UserDefined'; % Type of pilot averaging +cec.FreqWindow = 9; % Frequency window size +cec.TimeWindow = 9; % Time window size +cec.InterpType = 'linear'; % 2D interpolation type +cec.InterpWindow = 'Causal'; % Interpolation window type +cec.InterpWinSize = 1; % Interpolation window size + + +addpath('../../debug/srslte/lib/phch/test') + + +ber=zeros(length(formats),length(SNR_values)); +ber2=zeros(length(formats),length(SNR_values)); +for f=1:length(formats) + nb=formats(f); + for s=1:length(SNR_values) + SNRdB=SNR_values(s); + SNR = 10^(SNRdB/10); % Linear SNR + + errors = 0; + errors2 = 0; + for n=1:Nreal + bits=randi(2,nb-1,1)-1; + + [sym_mat, info]=ltePUCCH1(ueConfig,pucchConfig,bits); + idx=ltePUCCH1Indices(ueConfig,pucchConfig); + [dmrs_mat, info_dmrs]=ltePUCCH1DRS(ueConfig,pucchConfig); + idx_dmrs=ltePUCCH1DRSIndices(ueConfig,pucchConfig); + + % Resource mapping + subframe_tx = lteULResourceGrid(ueConfig); + subframe_tx(idx)=sym_mat; + subframe_tx(idx_dmrs)=dmrs_mat; + + [txWaveform, info] = lteSCFDMAModulate(ueConfig,subframe_tx); + cfg.SamplingRate = info.SamplingRate; + + % Fading + if (enable_fading) + rxWaveform = lteFadingChannel(cfg,txWaveform); + else + rxWaveform = txWaveform; + end + + % Noise Addition + N0 = 1/(sqrt(2.0*double(info.Nfft))*SNR); + noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise + rxWaveform = rxWaveform + noise; + + % Demodulate + subframe_rx = lteSCFDMADemodulate(ueConfig, rxWaveform); + + % Perform channel estimation + [hest, nest] = lteULChannelEstimatePUCCH1(ueConfig, pucchConfig, cec, subframe_rx); + + % Equalize + pucchSymbols = lteEqualizeMMSE(subframe_rx(idx), hest(idx), nest); + + % Decoding + bits_rx = ltePUCCH1Decode(ueConfig, pucchConfig, length(bits), pucchSymbols); + + % Check errors + a=size(bits_rx); + if (a(2) ~= 1) + errors = errors + 1; + elseif (formats(f) == 2) + if (a(1) ~= 1) + errors = errors + 1; + elseif (bits_rx(1) ~= bits(1)) + errors = errors + 1; + end + end + + % Decoding srsLTE + [bits_rx,z,ce]= srslte_pucch(ueConfig, pucchConfig, length(bits), subframe_rx, threshold); + + % Check errors + a=size(bits_rx); + if (a(2) ~= 1) + errors2 = errors2 + 1; + elseif (formats(f) == 2) + if (a(1) ~= 1) + errors2 = errors2 + 1; + elseif (bits_rx(1) ~= bits(1)) + errors2 = errors2 + 1; + end + end + + end + ber(f,s)=errors/Nreal; + ber2(f,s)=errors2/Nreal; + fprintf('Format %s, SNR=%.1f dB, errors=%d, errors2=%d\n', format_str{formats(f)},SNRdB,errors,errors2); + end +end + +semilogy(SNR_values,ber,SNR_values,ber2) +xlabel('SNR (dB)') +ylabel('BER') +grid on +legend(format_str(formats)) + diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index a5b16ea3f..a558b28e7 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -238,7 +238,7 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, ui } break; default: - fprintf(stderr, "Error getting PUCCH format %d not supported\n"); + fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/test/pucch_test_mex.c b/srslte/lib/phch/test/pucch_test_mex.c new file mode 100644 index 000000000..c65097b11 --- /dev/null +++ b/srslte/lib/phch/test/pucch_test_mex.c @@ -0,0 +1,225 @@ +/** + * + * \section COPYRIGHT + * +* Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include +#include "srslte/srslte.h" +#include "srslte/mex/mexutils.h" + +/** MEX function to be called from MATLAB to test the channel estimator + */ + +#define UECFG prhs[0] +#define PUCCHCFG prhs[1] +#define N_BITS prhs[2] +#define INPUT prhs[3] +#define THRESHOLD prhs[4] +#define NOF_INPUTS 4 + +void help() +{ + mexErrMsgTxt + ("[data, symbols, ce]=srslte_pucch(ue, chs, n_bits, input)\n\n"); +} + +/* the gateway function */ +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + + if (nrhs < NOF_INPUTS) { + help(); + return; + } + srslte_verbose = SRSLTE_VERBOSE_NONE; + + srslte_cell_t cell; + bzero(&cell, sizeof(srslte_cell_t)); + cell.nof_ports = 1; + cell.cp = SRSLTE_CP_NORM; + if (mexutils_read_uint32_struct(UECFG, "NCellID", &cell.id)) { + mexErrMsgTxt("Field NCellID not found in UE config\n"); + return; + } + if (mexutils_read_uint32_struct(UECFG, "NULRB", &cell.nof_prb)) { + mexErrMsgTxt("Field NULRB not found in UE config\n"); + return; + } + srslte_pucch_t pucch; + if (srslte_pucch_init(&pucch, cell)) { + mexErrMsgTxt("Error initiating PUSCH\n"); + return; + } + + uint32_t sf_idx = 0; + if (mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx)) { + mexErrMsgTxt("Field NSubframe not found in UE config\n"); + return; + } + uint32_t rnti; + if (mexutils_read_uint32_struct(UECFG, "RNTI", &rnti)) { + mexErrMsgTxt("Field NSubframe not found in UE config\n"); + return; + } + if (srslte_pucch_set_crnti(&pucch, (uint16_t) rnti&0xffff)) { + mexErrMsgTxt("Error setting C-RNTI\n"); + return; + } + uint32_t n_pucch; + if (mexutils_read_uint32_struct(PUCCHCFG, "ResourceIdx", &n_pucch)) { + mexErrMsgTxt("Field ResourceIdx not found in PUCCHCFG\n"); + return; + } + srslte_pucch_cfg_t pucch_cfg; + bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); + + if (mexutils_read_uint32_struct(PUCCHCFG, "DeltaShift", &pucch_cfg.delta_pucch_shift)) { + mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n"); + return; + } + if (mexutils_read_uint32_struct(PUCCHCFG, "ResourceSize", &pucch_cfg.n_rb_2)) { + mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n"); + return; + } + if (mexutils_read_uint32_struct(PUCCHCFG, "CyclicShifts", &pucch_cfg.N_cs)) { + mexErrMsgTxt("Field CyclicShifts not found in PUCCHCFG\n"); + return; + } + bool group_hopping_en = false; + char *hop = mexutils_get_char_struct(UECFG, "Hopping"); + if (hop) { + if (!strcmp(hop, "Group")) { + group_hopping_en = true; + } + mxFree(hop); + } + + pucch.shortened = false; + uint32_t sh = 0; + mexutils_read_uint32_struct(PUCCHCFG, "Shortened", &sh); + if (sh == 1) { + pucch.shortened = true; + } + + float *thresholds; + int th_len = 0; + + if (nrhs > NOF_INPUTS) { + th_len = mexutils_read_f(THRESHOLD, &thresholds); + if (th_len == 2) { + srslte_pucch_set_threshold(&pucch, thresholds[0], thresholds[1]); + } + } + + uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; + int nof_bits = (int) mxGetScalar(N_BITS); + + srslte_pucch_format_t format; + switch(nof_bits) { + case 0: + format = SRSLTE_PUCCH_FORMAT_1; + break; + case 1: + format = SRSLTE_PUCCH_FORMAT_1A; + break; + case 2: + format = SRSLTE_PUCCH_FORMAT_1B; + break; + case 20: + format = SRSLTE_PUCCH_FORMAT_2; + break; + case 21: + format = SRSLTE_PUCCH_FORMAT_2A; + break; + case 22: + format = SRSLTE_PUCCH_FORMAT_2B; + break; + default: + mexErrMsgTxt("Invalid number of bits in parameter ack\n"); + return; + } + if (nof_bits > 20) { + nof_bits = 20; + } + + cf_t *sf_symbols = NULL; + int nof_re = mexutils_read_cf(INPUT, &sf_symbols); + if (nof_re < 0) { + mexErrMsgTxt("Error reading input\n"); + return; + } + cf_t *ce = srslte_vec_malloc(nof_re*sizeof(cf_t)); + if (!ce) { + perror("malloc"); + return; + } + bzero(ce, nof_re*sizeof(cf_t)); + srslte_chest_ul_t chest_ul; + if (srslte_chest_ul_init(&chest_ul, cell)) { + mexErrMsgTxt("Error initiating PUCCH DMRS\n"); + return; + } + srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; + pusch_cfg.group_hopping_en = group_hopping_en; + pusch_cfg.sequence_hopping_en = false; + srslte_chest_ul_set_cfg(&chest_ul, &pusch_cfg, &pucch_cfg, NULL); + + srslte_pucch_set_cfg(&pucch, &pucch_cfg, group_hopping_en); + + if (srslte_chest_ul_estimate_pucch(&chest_ul, sf_symbols, ce, format, n_pucch, sf_idx)) { + mexErrMsgTxt("Error estimating PUCCH DMRS\n"); + return; + } + + if (srslte_pucch_decode(&pucch, format, n_pucch, sf_idx, sf_symbols, ce, 0, bits)) { + mexErrMsgTxt("Error decoding PUCCH\n"); + return; + } + + if (nlhs >= 1) { + if (format != SRSLTE_PUCCH_FORMAT_1) { + mexutils_write_uint8(bits, &plhs[0], nof_bits, 1); + } else { + if (bits[0] == 1) { + mexutils_write_uint8(bits, &plhs[0], 0, 1); + } else { + mexutils_write_uint8(bits, &plhs[0], 0, 0); + } + } + } + + if (nlhs >= 2) { + mexutils_write_cf(pucch.z, &plhs[1], 2*srslte_refsignal_dmrs_N_rs(format, cell.cp)*SRSLTE_NRE*2, 1); + } + + if (nlhs >= 3) { + mexutils_write_cf(ce, &plhs[2], nof_re, 1); + } + + srslte_pucch_free(&pucch); + free(sf_symbols); + + return; +} + diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index 5ada6165a..d9683424d 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -315,7 +315,7 @@ int rf_uhd_open(char *args, void **h) // Set external clock reference if (strstr(args, "clock=external")) { - uhd_usrp_set_clock_source(handler->usrp, "external", 0); + uhd_usrp_set_clock_source(handler->usrp, "external", 0); } handler->has_rssi = get_has_rssi(handler); From 25398ec0893a22eef5e6b64f4f7f8aae716b3710 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 20 Oct 2016 11:27:15 +0200 Subject: [PATCH 045/111] Added comment to clarify cross-correlation in PSS --- srslte/lib/sync/pss.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/srslte/lib/sync/pss.c b/srslte/lib/sync/pss.c index f7edbb353..46c02414e 100644 --- a/srslte/lib/sync/pss.c +++ b/srslte/lib/sync/pss.c @@ -304,7 +304,12 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe return SRSLTE_ERROR; } - /* Correlate input with PSS sequence */ + /* Correlate input with PSS sequence + * + * We do not reverse time-domain PSS signal because it's conjugate is symmetric. + * The conjugate operation on pss_signal_time has been done in srslte_pss_synch_init_N_id_2 + * This is why we can use FFT-based convolution + */ if (q->frame_size >= q->fft_size) { #ifdef CONVOLUTION_FFT memcpy(q->tmp_input, input, q->frame_size * sizeof(cf_t)); From 4cdbed47f23dbcc331351d76c621b7639d96f6ee Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 20 Oct 2016 11:57:59 +0200 Subject: [PATCH 046/111] pucch receiver tested --- srslte/include/srslte/enb/enb_ul.h | 6 +- srslte/include/srslte/phch/pucch.h | 11 +-- srslte/lib/enb/enb_ul.c | 110 +++++++++++++++++++---------- srslte/lib/phch/pucch.c | 19 ++++- 4 files changed, 98 insertions(+), 48 deletions(-) diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index 59fd02065..8c1af2eea 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -81,6 +81,7 @@ typedef struct SRSLTE_API { bool *srs_cfg_en; srslte_uci_cfg_t *uci_cfg; srslte_refsignal_srs_cfg_t *srs_cfg; + srslte_pucch_sched_t *pucch_sched; } srslte_enb_ul_t; @@ -113,6 +114,7 @@ SRSLTE_API int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, srslte_uci_cfg_t *uci_cfg, + srslte_pucch_sched_t *pucch_sched, srslte_refsignal_srs_cfg_t *srs_cfg); @@ -124,10 +126,10 @@ SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, - uint32_t n_pucch, + uint32_t pdcch_n_cce, uint32_t rnti_idx, srslte_uci_data_t *uci_data, - uint32_t tti); + uint32_t sf_rx); SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index 66062b057..4c7921dea 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -43,7 +43,7 @@ #define SRSLTE_PUCCH_N_SEQ 12 #define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS -#define SRSLTE_PUCCH_MAX_SYMBOLS 120 +#define SRSLTE_PUCCH_MAX_SYMBOLS 120 typedef enum SRSLTE_API { SRSLTE_PUCCH_FORMAT_1 = 0, @@ -68,6 +68,7 @@ typedef struct SRSLTE_API { uint32_t delta_pucch_shift; uint32_t n_rb_2; uint32_t N_cs; + uint32_t n1_pucch_an; // SRS configuration bool srs_configured; @@ -87,9 +88,11 @@ typedef struct SRSLTE_API { uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB]; uint32_t f_gh[SRSLTE_NSLOTS_X_FRAME]; float tmp_arg[SRSLTE_PUCCH_N_SEQ]; - cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS]; - cf_t z_tmp[SRSLTE_PUCCH_MAX_SYMBOLS]; - cf_t ce[SRSLTE_PUCCH_MAX_SYMBOLS]; + + cf_t *z; + cf_t *z_tmp; + cf_t *ce; + bool rnti_is_set; bool shortened; bool group_hopping_en; diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index a558b28e7..64679fc1b 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -62,11 +62,12 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, memcpy(&q->hopping_cfg, hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t)); } - q->uci_cfg_en = calloc(sizeof(bool),nof_rnti); - q->srs_cfg_en = calloc(sizeof(bool),nof_rnti); + q->uci_cfg_en = calloc(sizeof(bool), nof_rnti); + q->srs_cfg_en = calloc(sizeof(bool), nof_rnti); - q->uci_cfg = calloc(sizeof(srslte_uci_cfg_t),nof_rnti); - q->srs_cfg = calloc(sizeof(srslte_refsignal_srs_cfg_t),nof_rnti); + q->uci_cfg = calloc(sizeof(srslte_uci_cfg_t), nof_rnti); + q->srs_cfg = calloc(sizeof(srslte_refsignal_srs_cfg_t), nof_rnti); + q->pucch_sched = calloc(sizeof(srslte_pucch_sched_t), nof_rnti); if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -97,6 +98,8 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, srslte_prach_set_detect_factor(&q->prach, 60); + srslte_pucch_set_threshold(&q->pucch, 0.5, 0.5); + if (srslte_chest_ul_init(&q->chest, cell)) { fprintf(stderr, "Error initiating channel estimator\n"); goto clean_exit; @@ -150,6 +153,9 @@ void srslte_enb_ul_free(srslte_enb_ul_t *q) if (q->srs_cfg_en) { free(q->srs_cfg_en); } + if (q->pucch_sched) { + free(q->pucch_sched); + } srslte_prach_free(&q->prach); srslte_ofdm_rx_free(&q->fft); @@ -173,6 +179,7 @@ int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, uint32_t idx, uint16_t rnti) int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, srslte_uci_cfg_t *uci_cfg, + srslte_pucch_sched_t *pucch_sched, srslte_refsignal_srs_cfg_t *srs_cfg) { if (idx < q->nof_rnti) { @@ -182,6 +189,10 @@ int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, } else { q->uci_cfg_en[idx] = false; } + if (pucch_sched) { + printf("saving sched for idx=%d, N_pucch_1=%d\n", idx, pucch_sched->N_pucch_1); + memcpy(&q->pucch_sched[idx], pucch_sched, sizeof(srslte_pucch_sched_t)); + } if (srs_cfg) { memcpy(&q->srs_cfg[idx], srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); q->srs_cfg_en[idx] = true; @@ -205,44 +216,65 @@ void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); } -int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, uint32_t n_pucch, - uint32_t rnti_idx, srslte_uci_data_t *uci_data, uint32_t tti) +int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, uint32_t pdcch_n_cce, + uint32_t rnti_idx, srslte_uci_data_t *uci_data, uint32_t sf_rx) { - - if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, tti%10)) { - fprintf(stderr,"Error estimating PUCCH DMRS\n"); - return SRSLTE_ERROR; - } - - float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); - - uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; - if (srslte_pucch_decode(&q->pucch, format, n_pucch, tti%10, q->sf_symbols, q->ce, noise_power, bits)) { - fprintf(stderr,"Error decoding PUCCH\n"); + + if (rnti_idx < q->nof_rnti) { + uint32_t n_pucch = 0; + switch(format) { + case SRSLTE_PUCCH_FORMAT_1: + n_pucch = q->pucch_sched[rnti_idx].n_pucch_sr; + break; + case SRSLTE_PUCCH_FORMAT_1A: + case SRSLTE_PUCCH_FORMAT_1B: + n_pucch = pdcch_n_cce + q->pucch_sched[rnti_idx].N_pucch_1; + break; + default: + fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); + return SRSLTE_ERROR; + } + + if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { + fprintf(stderr,"Error estimating PUCCH DMRS\n"); + return SRSLTE_ERROR; + } + + float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); + + uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; + if (srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits)) { + fprintf(stderr,"Error decoding PUCCH\n"); + return SRSLTE_ERROR; + } + + switch(format) { + case SRSLTE_PUCCH_FORMAT_1: + if (bits[0]) { + uci_data->scheduling_request = true; + } else { + uci_data->scheduling_request = false; + } + break; + case SRSLTE_PUCCH_FORMAT_1A: + case SRSLTE_PUCCH_FORMAT_1B: + uci_data->uci_ack = bits[0]; + uci_data->uci_ack_len = 1; + if (format == SRSLTE_PUCCH_FORMAT_1B) { + uci_data->uci_ack_2 = bits[0]; + uci_data->uci_ack_len = 2; + } + break; + default: + fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; + } else { + fprintf(stderr, "Invalid rnti_idx=%d\n", rnti_idx); return SRSLTE_ERROR; } - - switch(format) { - case SRSLTE_PUCCH_FORMAT_1: - if (bits[0]) { - uci_data->scheduling_request = true; - } - break; - case SRSLTE_PUCCH_FORMAT_1A: - case SRSLTE_PUCCH_FORMAT_1B: - uci_data->uci_ack = bits[0]; - uci_data->uci_ack_len = 1; - if (format == SRSLTE_PUCCH_FORMAT_1B) { - uci_data->uci_ack_2 = bits[0]; - uci_data->uci_ack_len = 2; - } - break; - default: - fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); - return SRSLTE_ERROR; - } - - return SRSLTE_SUCCESS; } int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer, diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index 30fdb66b7..b066f337a 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -370,6 +370,10 @@ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) { if (srslte_pucch_n_cs_cell(q->cell, q->n_cs_cell)) { return SRSLTE_ERROR; } + + q->z = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS); + q->z_tmp = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS); + q->ce = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS); ret = SRSLTE_SUCCESS; } @@ -382,6 +386,16 @@ void srslte_pucch_free(srslte_pucch_t *q) { srslte_sequence_free(&q->seq_f2[sf_idx]); } } + if (q->z) { + free(q->z); + } + if (q->z_tmp) { + free(q->z_tmp); + } + if (q->ce) { + free(q->ce); + } + srslte_modem_table_free(&q->mod); bzero(q, sizeof(srslte_pucch_t)); } @@ -645,7 +659,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, } else { bits[0] = 0; } - printf("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, q->threshold_format1); + DEBUG("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, q->threshold_format1); break; case SRSLTE_PUCCH_FORMAT_1A: bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); @@ -658,7 +672,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, corr_max = corr; b_max = b; } - DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1); + DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a); } bits[0] = b_max; break; @@ -666,7 +680,6 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, fprintf(stderr, "Error decoding PUCCH: Format %d not supported\n", format); break; } - ret = SRSLTE_SUCCESS; } From 17d5ebca7ede758b759fc6fb2ce531c20369dcc4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 20 Oct 2016 17:49:51 +0200 Subject: [PATCH 047/111] isolated common tx/rx pucch functions --- srslte/include/srslte/enb/enb_ul.h | 7 +-- srslte/include/srslte/phch/pucch.h | 12 +++- srslte/lib/enb/enb_ul.c | 54 ++++++------------ srslte/lib/phch/pucch.c | 66 ++++++++++++++++++++- srslte/lib/ue/ue_ul.c | 92 ++++++------------------------ 5 files changed, 113 insertions(+), 118 deletions(-) diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index 8c1af2eea..60eb0e50f 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -125,11 +125,10 @@ SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer); SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, - srslte_pucch_format_t format, - uint32_t pdcch_n_cce, uint32_t rnti_idx, - srslte_uci_data_t *uci_data, - uint32_t sf_rx); + uint32_t pdcch_n_cce, + uint32_t sf_rx, + srslte_uci_data_t *uci_data); SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index 4c7921dea..c5f9f7ea5 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -40,6 +40,7 @@ #include "srslte/common/sequence.h" #include "srslte/modem/mod.h" #include "srslte/phch/cqi.h" +#include "srslte/phch/uci.h" #define SRSLTE_PUCCH_N_SEQ 12 #define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS @@ -51,7 +52,8 @@ typedef enum SRSLTE_API { SRSLTE_PUCCH_FORMAT_1B, SRSLTE_PUCCH_FORMAT_2, SRSLTE_PUCCH_FORMAT_2A, - SRSLTE_PUCCH_FORMAT_2B + SRSLTE_PUCCH_FORMAT_2B, + SRSLTE_PUCCH_FORMAT_ERROR, } srslte_pucch_format_t; typedef struct SRSLTE_API { @@ -160,6 +162,14 @@ SRSLTE_API uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, uint32_t n_pucch, srslte_cp_t cp); +SRSLTE_API srslte_pucch_format_t srslte_pucch_get_format(srslte_uci_data_t *uci_data, + srslte_cp_t cp); + +SRSLTE_API uint32_t srslte_pucch_get_npucch(uint32_t n_cce, + srslte_pucch_format_t format, + bool has_scheduling_request, + srslte_pucch_sched_t *pucch_sched); + SRSLTE_API uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 64679fc1b..7732b30ed 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -216,24 +216,16 @@ void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); } -int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, uint32_t pdcch_n_cce, - uint32_t rnti_idx, srslte_uci_data_t *uci_data, uint32_t sf_rx) +int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, + uint32_t pdcch_n_cce, uint32_t sf_rx, + srslte_uci_data_t *uci_data) { if (rnti_idx < q->nof_rnti) { - uint32_t n_pucch = 0; - switch(format) { - case SRSLTE_PUCCH_FORMAT_1: - n_pucch = q->pucch_sched[rnti_idx].n_pucch_sr; - break; - case SRSLTE_PUCCH_FORMAT_1A: - case SRSLTE_PUCCH_FORMAT_1B: - n_pucch = pdcch_n_cce + q->pucch_sched[rnti_idx].N_pucch_1; - break; - default: - fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); - return SRSLTE_ERROR; - } + + srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp); + + uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->pucch_sched[rnti_idx]); if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { fprintf(stderr,"Error estimating PUCCH DMRS\n"); @@ -243,33 +235,21 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, ui float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; - if (srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits)) { + int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits); + if (ret_val < 0) { fprintf(stderr,"Error decoding PUCCH\n"); return SRSLTE_ERROR; } - switch(format) { - case SRSLTE_PUCCH_FORMAT_1: - if (bits[0]) { - uci_data->scheduling_request = true; - } else { - uci_data->scheduling_request = false; - } - break; - case SRSLTE_PUCCH_FORMAT_1A: - case SRSLTE_PUCCH_FORMAT_1B: - uci_data->uci_ack = bits[0]; - uci_data->uci_ack_len = 1; - if (format == SRSLTE_PUCCH_FORMAT_1B) { - uci_data->uci_ack_2 = bits[0]; - uci_data->uci_ack_len = 2; - } - break; - default: - fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); - return SRSLTE_ERROR; + // update schedulign request + if (uci_data->scheduling_request) { + uci_data->scheduling_request = ret_val; + } + + // Save ACK bits + if (uci_data->uci_ack_len > 0) { + uci_data->uci_ack = bits[0]; } - return SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid rnti_idx=%d\n", rnti_idx); diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index b066f337a..86e8bbcda 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -160,6 +160,64 @@ uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t return 0; } +/* Choose PUCCH format based on pending transmission as described in 10.1 of 36.213 */ +srslte_pucch_format_t srslte_pucch_get_format(srslte_uci_data_t *uci_data, srslte_cp_t cp) +{ + srslte_pucch_format_t format = SRSLTE_PUCCH_FORMAT_ERROR; + // No CQI data + if (uci_data->uci_cqi_len == 0) { + // 1-bit ACK + optional SR + if (uci_data->uci_ack_len == 1) { + format = SRSLTE_PUCCH_FORMAT_1A; + } + // 2-bit ACK + optional SR + else if (uci_data->uci_ack_len == 2) { + format = SRSLTE_PUCCH_FORMAT_1B; + } + // SR only + else if (uci_data->scheduling_request) { + format = SRSLTE_PUCCH_FORMAT_1; + } + } + // CQI data + else { + // CQI and no ack + if (uci_data->uci_ack_len == 0) { + format = SRSLTE_PUCCH_FORMAT_2; + } + // CQI + 1-bit ACK + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1) { + format = SRSLTE_PUCCH_FORMAT_2A; + } + // CQI + 2-bit ACK + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 2) { + format = SRSLTE_PUCCH_FORMAT_2B; + } + // CQI + 2-bit ACK + cyclic prefix + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { + format = SRSLTE_PUCCH_FORMAT_2B; + } + } + return format; +} + +/** Choose PUCCH resource as desribed in 10.1 of 36.213 */ +uint32_t srslte_pucch_get_npucch(uint32_t n_cce, srslte_pucch_format_t format, bool has_scheduling_request, srslte_pucch_sched_t *pucch_sched) +{ + uint32_t n_pucch = 0; + if (has_scheduling_request) { + n_pucch = pucch_sched->n_pucch_sr; + } else if (format != SRSLTE_PUCCH_FORMAT_2) { + if (pucch_sched->sps_enabled) { + n_pucch = pucch_sched->n_pucch_1[pucch_sched->tpc_for_pucch%4]; + } else { + n_pucch = n_cce + pucch_sched->N_pucch_1; + } + } else { + n_pucch = pucch_sched->n_pucch_2; + } +} + uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, uint32_t nof_prb, srslte_cp_t cp, uint32_t ns) { @@ -655,15 +713,15 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; if (corr >= q->threshold_format1) { - bits[0] = 1; + ret = 1; } else { - bits[0] = 0; + ret = 0; } DEBUG("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, q->threshold_format1); break; case SRSLTE_PUCCH_FORMAT_1A: bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); - + ret = 0; for (int b=0;b<2;b++) { bits[0] = b; pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); @@ -671,6 +729,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, if (corr > corr_max && corr >= q->threshold_format1a) { corr_max = corr; b_max = b; + ret = 1; } DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a); } @@ -678,6 +737,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, break; default: fprintf(stderr, "Error decoding PUCCH: Format %d not supported\n", format); + ret = SRSLTE_ERROR; break; } ret = SRSLTE_SUCCESS; diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index a8e717311..d4a97aaa9 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -220,64 +220,19 @@ int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, grant, &q->uci_cfg, &q->hopping_cfg, &q->srs_cfg, tti, rvidx, current_tx_nb); } -int pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t *format, - uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS], uint8_t pucch2_bits[2], - srslte_cp_t cp) +// Encode bits from uci_data +void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format, + uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS], + uint8_t pucch2_bits[SRSLTE_PUCCH_MAX_BITS]) { - int ret = SRSLTE_SUCCESS; - - // No CQI data - if (uci_data->uci_cqi_len == 0) { - // 1-bit ACK + optional SR - if (uci_data->uci_ack_len == 1) { - *format = SRSLTE_PUCCH_FORMAT_1A; - pucch_bits[0] = uci_data->uci_ack; - } - // 2-bit ACK + optional SR - else if (uci_data->uci_ack_len == 2) { - *format = SRSLTE_PUCCH_FORMAT_1B; - pucch_bits[0] = uci_data->uci_ack; - pucch_bits[1] = uci_data->uci_ack_2; - } - // SR only - else if (uci_data->scheduling_request) { - *format = SRSLTE_PUCCH_FORMAT_1; - } else { - ret = SRSLTE_ERROR; - } - } - // CQI data - else { - srslte_uci_encode_cqi_pucch(uci_data->uci_cqi, uci_data->uci_cqi_len, pucch_bits); - // CQI and no ack - if (uci_data->uci_ack_len == 0) { - *format = SRSLTE_PUCCH_FORMAT_2; - } - // CQI + 1-bit ACK - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1) { - *format = SRSLTE_PUCCH_FORMAT_2A; - pucch2_bits[0] = uci_data->uci_ack; - } - // CQI + 2-bit ACK - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 2) { - *format = SRSLTE_PUCCH_FORMAT_2B; - pucch2_bits[0] = uci_data->uci_ack; - pucch2_bits[1] = uci_data->uci_ack_2; - } - // CQI + 2-bit ACK + cyclic prefix - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { - *format = SRSLTE_PUCCH_FORMAT_2B; - pucch2_bits[0] = uci_data->uci_ack; - pucch2_bits[1] = uci_data->uci_ack_2; - } else { - ret = SRSLTE_ERROR; - } + if (format == SRSLTE_PUCCH_FORMAT_1A || format == SRSLTE_PUCCH_FORMAT_1B) { + pucch_bits[0] = uci_data->uci_ack; + pucch_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 1a } - if (ret) { - fprintf(stderr, "Unsupported combination of UCI parameters: ack_len=%d, cqi_len=%d\n", - uci_data->uci_ack, uci_data->uci_cqi_len); + if (format == SRSLTE_PUCCH_FORMAT_2A || format == SRSLTE_PUCCH_FORMAT_2B) { + pucch2_bits[0] = uci_data->uci_ack; + pucch2_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 2a } - return ret; } /* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal @@ -303,35 +258,24 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, bzero(pucch_bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); bzero(pucch2_bits, 2*sizeof(uint8_t)); + srslte_pucch_format_t format = srslte_pucch_get_format(&uci_data, q->cell.cp); + // Encode UCI information - if (pucch_encode_bits(&uci_data, &q->last_pucch_format, pucch_bits, pucch2_bits, q->cell.cp)) { - return SRSLTE_ERROR; - } + pucch_encode_bits(&uci_data, format, pucch_bits, pucch2_bits); // Choose n_pucch - uint32_t n_pucch = 0; - if (uci_data.scheduling_request) { - n_pucch = q->pucch_sched.n_pucch_sr; - } else if (q->last_pucch_format < SRSLTE_PUCCH_FORMAT_2) { - if (q->pucch_sched.sps_enabled) { - n_pucch = q->pucch_sched.n_pucch_1[q->pucch_sched.tpc_for_pucch%4]; - } else { - n_pucch = pdcch_n_cce + q->pucch_sched.N_pucch_1; - } - } else { - n_pucch = q->pucch_sched.n_pucch_2; - } - if (srslte_pucch_encode(&q->pucch, q->last_pucch_format, n_pucch, sf_idx, pucch_bits, q->sf_symbols)) { + uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data.scheduling_request, &q->pucch_sched); + if (srslte_pucch_encode(&q->pucch, format, n_pucch, sf_idx, pucch_bits, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); return ret; } - if (srslte_refsignal_dmrs_pucch_gen(&q->signals, q->last_pucch_format, n_pucch, sf_idx, pucch2_bits, q->refsignal)) + if (srslte_refsignal_dmrs_pucch_gen(&q->signals, format, n_pucch, sf_idx, pucch2_bits, q->refsignal)) { fprintf(stderr, "Error generating PUSCH DRMS signals\n"); return ret; } - srslte_refsignal_dmrs_pucch_put(&q->signals, q->last_pucch_format, n_pucch, q->refsignal, q->sf_symbols); + srslte_refsignal_dmrs_pucch_put(&q->signals, format, n_pucch, q->refsignal, q->sf_symbols); if (srslte_ue_ul_srs_tx_enabled(&q->signals.srs_cfg, tti) && q->pucch.shortened) { if (q->signals_pregenerated) { @@ -341,6 +285,8 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, srslte_refsignal_srs_put(&q->signals, tti, q->srs_signal, q->sf_symbols); } } + + q->last_pucch_format = format; srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); From c732c5c5f094d5a0c75f0d70520b7dfe1bff0818 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 27 Oct 2016 17:27:08 +0200 Subject: [PATCH 048/111] viterbi: fixed incorrect initialization --- srslte/lib/fec/viterbi37_port.c | 16 +++++++++++++++- srslte/lib/fec/viterbi37_sse.c | 13 +++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/srslte/lib/fec/viterbi37_port.c b/srslte/lib/fec/viterbi37_port.c index cf05b3c53..caa2f26db 100644 --- a/srslte/lib/fec/viterbi37_port.c +++ b/srslte/lib/fec/viterbi37_port.c @@ -33,13 +33,25 @@ struct v37 { decision_t *dp; /* Pointer to current decision */ metric_t *old_metrics, *new_metrics; /* Pointers to path metrics, swapped on every bit */ decision_t *decisions; /* Beginning of decisions for block */ + uint32_t len; }; +void clear_v37(struct v37 *vp) { + bzero(vp->decisions, sizeof(decision_t)*vp->len); + vp->dp = NULL; + bzero(&vp->metrics1, sizeof(metric_t)); + bzero(&vp->metrics2, sizeof(metric_t)); + vp->old_metrics = NULL; + vp->new_metrics = NULL; +} + /* Initialize Viterbi decoder for start of new frame */ int init_viterbi37_port(void *p, int starting_state) { struct v37 *vp = p; uint32_t i; - + + clear_v37(vp); + if (p == NULL) return -1; for (i = 0; i < 64; i++) @@ -81,6 +93,8 @@ void *create_viterbi37_port(int polys[3], uint32_t len) { free(vp); return NULL ; } + + vp->len = len+6; return vp; } diff --git a/srslte/lib/fec/viterbi37_sse.c b/srslte/lib/fec/viterbi37_sse.c index 3ecbfeefc..cf7cefd26 100644 --- a/srslte/lib/fec/viterbi37_sse.c +++ b/srslte/lib/fec/viterbi37_sse.c @@ -42,6 +42,7 @@ struct v37 { decision_t *dp; /* Pointer to current decision */ metric_t *old_metrics,*new_metrics; /* Pointers to path metrics, swapped on every bit */ decision_t *decisions; /* Beginning of decisions for block */ + uint32_t len; }; void set_viterbi37_polynomial_sse(int polys[3]) { @@ -54,12 +55,23 @@ void set_viterbi37_polynomial_sse(int polys[3]) { } } +void clear_v37_sse(struct v37 *vp) { + bzero(vp->decisions, sizeof(decision_t)*vp->len); + vp->dp = NULL; + bzero(&vp->metrics1, sizeof(metric_t)); + bzero(&vp->metrics2, sizeof(metric_t)); + vp->old_metrics = NULL; + vp->new_metrics = NULL; +} + /* Initialize Viterbi decoder for start of new frame */ int init_viterbi37_sse(void *p, int starting_state) { struct v37 *vp = p; uint32_t i; + clear_v37_sse(vp); + for(i=0;i<64;i++) vp->metrics1.c[i] = 63; @@ -89,6 +101,7 @@ void *create_viterbi37_sse(int polys[3], uint32_t len) { return NULL; } vp->decisions = (decision_t *)p; + vp->len = len+6; return vp; } From ffd4fb7d93f09074adce48a06d0d6c8f8dd48bd7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 27 Oct 2016 17:27:59 +0200 Subject: [PATCH 049/111] minor fixes in pucch rx --- CMakeLists.txt | 9 +++- matlab/tests/prach_detect_test.m | 11 +++-- srslte/lib/ch_estimation/chest_ul.c | 8 +++- srslte/lib/ch_estimation/refsignal_ul.c | 6 +++ srslte/lib/enb/enb_ul.c | 63 ++++++++++++++++--------- srslte/lib/phch/dci.c | 6 +-- srslte/lib/phch/prach.c | 1 + srslte/lib/phch/pucch.c | 17 +++++-- srslte/lib/ue/ue_ul.c | 1 + 9 files changed, 86 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c77a24fc6..fd5dc5631 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,8 +97,15 @@ if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE -g") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") + find_package(SSE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") + if(HAVE_AVX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") + elseif(HAVE_SSE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfpmath=sse -msse4.1 -DLV_HAVE_SSE") + endif(HAVE_AVX) else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") find_package(SSE) if(HAVE_AVX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") diff --git a/matlab/tests/prach_detect_test.m b/matlab/tests/prach_detect_test.m index 7a2fc1802..51bda6c21 100644 --- a/matlab/tests/prach_detect_test.m +++ b/matlab/tests/prach_detect_test.m @@ -1,13 +1,13 @@ %% PRACH Detection Conformance Test %clear -d=50;%linspace(4,14,6); +d=80;%linspace(4,14,6); pDetection2 = zeros(2,length(d)); for dd=1:length(d) detect_factor=d(dd); numSubframes = 1; % Number of subframes frames to simulate at each SNR -SNRdB = 10;%linspace(-14,10,8); % SNR points to simulate +SNRdB = 50;%linspace(-14,10,8); % SNR points to simulate foffset = 0.0; % Frequency offset in Hertz delay=0; add_fading=false; @@ -26,7 +26,7 @@ ue.NTxAnts = 1; % Number of transmission antennas prach.Format = 0; % PRACH format: TS36.104, Table 8.4.2.1-1 prach.HighSpeed = 0; % Normal mode: TS36.104, Table 8.4.2.1-1 -prach.FreqOffset = 4; % Default frequency location +prach.FreqOffset = 2; % Default frequency location info = ltePRACHInfo(ue, prach); % PRACH information %% Propagation Channel Configuration @@ -67,9 +67,10 @@ for nSNR = 1:length(SNRdB) % Loop for each subframe for nsf = 1:numSubframes - prach.SeqIdx = 0;%randi(838,1,1)-1; % Logical sequence index: TS36.141, Table A.6-1 + prach.SeqIdx = 41;%randi(838,1,1)-1; % Logical sequence index: TS36.141, Table A.6-1 prach.CyclicShiftIdx = 11;%randi(16,1,1)-1; % Cyclic shift index: TS36.141, Table A.6-1 prach.PreambleIdx = 1;%randi(64,1,1)-1; % Preamble index: TS36.141, Table A.6-1 + prach.TimingOffset = 0; info = ltePRACHInfo(ue, prach); % PRACH information % PRACH transmission @@ -99,7 +100,7 @@ for nSNR = 1:length(SNRdB) rxwave = rxwave((fadinginfo.ChannelFilterDelay + 1):end, :); end - rxwave=x; + rxwave=lteFrequencyCorrect(ue, x, -20); % rxwave=[zeros(delay,1); txwave(1:end-delay)]; % Apply frequency offset diff --git a/srslte/lib/ch_estimation/chest_ul.c b/srslte/lib/ch_estimation/chest_ul.c index a75d2a7a3..75d816702 100644 --- a/srslte/lib/ch_estimation/chest_ul.c +++ b/srslte/lib/ch_estimation/chest_ul.c @@ -269,8 +269,12 @@ int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, return SRSLTE_ERROR; } - int n_rs = srslte_refsignal_dmrs_N_rs(format, q->cell.cp); - int nrefs_sf = SRSLTE_NRE*n_rs*2; + int n_rs = srslte_refsignal_dmrs_N_rs(format, q->cell.cp); + if (!n_rs) { + fprintf(stderr, "Error computing N_rs\n"); + return SRSLTE_ERROR; + } + int nrefs_sf = SRSLTE_NRE*n_rs*2; /* Get references from the input signal */ srslte_refsignal_dmrs_pucch_get(&q->dmrs_signal, format, n_pucch, input, q->pilot_recv_signal); diff --git a/srslte/lib/ch_estimation/refsignal_ul.c b/srslte/lib/ch_estimation/refsignal_ul.c index f85b33c19..f203d6250 100644 --- a/srslte/lib/ch_estimation/refsignal_ul.c +++ b/srslte/lib/ch_estimation/refsignal_ul.c @@ -471,6 +471,9 @@ uint32_t srslte_refsignal_dmrs_N_rs(srslte_pucch_format_t format, srslte_cp_t cp case SRSLTE_PUCCH_FORMAT_2A: case SRSLTE_PUCCH_FORMAT_2B: return 2; + default: + fprintf(stderr, "Unsupported format %d\n", format); + return 0; } return 0; } @@ -575,6 +578,9 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma case SRSLTE_PUCCH_FORMAT_2B: w=w_arg_pucch_format2_cpnorm; break; + default: + fprintf(stderr, "Unsupported format %d\n", format); + return SRSLTE_ERROR; } cf_t z_m = 1.0; if (m == 1) { diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 7732b30ed..146d36830 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -190,7 +190,6 @@ int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, q->uci_cfg_en[idx] = false; } if (pucch_sched) { - printf("saving sched for idx=%d, N_pucch_1=%d\n", idx, pucch_sched->N_pucch_1); memcpy(&q->pucch_sched[idx], pucch_sched, sizeof(srslte_pucch_sched_t)); } if (srs_cfg) { @@ -216,39 +215,59 @@ void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); } +int get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, + uint32_t pdcch_n_cce, uint32_t sf_rx, + srslte_uci_data_t *uci_data, uint8_t bits[SRSLTE_PUCCH_MAX_BITS]) +{ + float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); + + srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp); + + uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->pucch_sched[rnti_idx]); + + if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { + fprintf(stderr,"Error estimating PUCCH DMRS\n"); + return SRSLTE_ERROR; + } + + + int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits); + if (ret_val < 0) { + fprintf(stderr,"Error decoding PUCCH\n"); + return SRSLTE_ERROR; + } + return ret_val; +} + int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, uint32_t pdcch_n_cce, uint32_t sf_rx, srslte_uci_data_t *uci_data) { - + uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; + if (rnti_idx < q->nof_rnti) { - - srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp); - - uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->pucch_sched[rnti_idx]); - - if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { - fprintf(stderr,"Error estimating PUCCH DMRS\n"); - return SRSLTE_ERROR; - } - - float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); - - uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; - int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits); - if (ret_val < 0) { - fprintf(stderr,"Error decoding PUCCH\n"); - return SRSLTE_ERROR; + + int ret_val = get_pucch(q, rnti_idx, pdcch_n_cce, sf_rx, uci_data, bits); + + // If we are looking for SR and ACK at the same time and ret=0, means there is no SR. + // try again to decode ACK only + if (uci_data->scheduling_request && uci_data->uci_ack_len && ret_val != 1) { + uci_data->scheduling_request = false; + ret_val = get_pucch(q, rnti_idx, pdcch_n_cce, sf_rx, uci_data, bits); } - + // update schedulign request if (uci_data->scheduling_request) { - uci_data->scheduling_request = ret_val; + uci_data->scheduling_request = (ret_val==1); } // Save ACK bits if (uci_data->uci_ack_len > 0) { - uci_data->uci_ack = bits[0]; + if (ret_val > 0) { + uci_data->uci_ack = bits[0]; + } else { + uci_data->uci_ack = 0; + } } return SRSLTE_SUCCESS; } else { diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index fbe7d6b45..66a1b218f 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -65,7 +65,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { - fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); + //fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); return ret; } @@ -754,13 +754,13 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 while(inof_bits-1 && y[i] == 0) { i++; } if (i == msg->nof_bits-1) { - printf("Received a Format1A RA PDCCH order. Not implemented!\n"); + //printf("Received a Format1A RA PDCCH order. Not implemented!\n"); return SRSLTE_ERROR; } } diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index 4406297c2..1cfedd3c6 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -600,6 +600,7 @@ int srslte_prach_detect_offset(srslte_prach_t *p, for (int j=0;jpeak_values[j] > p->detect_factor*corr_ave) { + //printf("saving prach correlation\n"); //memcpy(save_corr, p->corr, p->N_zc*sizeof(float)); if (indices) { indices[*n_indices] = (i*n_wins)+j; diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index 86e8bbcda..cce37fc38 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -99,8 +99,10 @@ uint32_t get_N_sf(srslte_pucch_format_t format, uint32_t slot_idx, bool shortene } case SRSLTE_PUCCH_FORMAT_2: case SRSLTE_PUCCH_FORMAT_2A: - case SRSLTE_PUCCH_FORMAT_2B: + case SRSLTE_PUCCH_FORMAT_2B: return 5; + default: + return 0; } return 0; } @@ -128,6 +130,8 @@ uint32_t srslte_pucch_nbits_format(srslte_pucch_format_t format) { return 21; case SRSLTE_PUCCH_FORMAT_2B: return 22; + default: + return 0; } return 0; } @@ -156,6 +160,8 @@ uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t } } break; + default: + return 0; } return 0; } @@ -216,6 +222,7 @@ uint32_t srslte_pucch_get_npucch(uint32_t n_cce, srslte_pucch_format_t format, b } else { n_pucch = pucch_sched->n_pucch_2; } + return n_pucch; } uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, @@ -248,7 +255,10 @@ uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, u case SRSLTE_PUCCH_FORMAT_2: case SRSLTE_PUCCH_FORMAT_2A: case SRSLTE_PUCCH_FORMAT_2B: - m = n_pucch/SRSLTE_NRE; + m = n_pucch/SRSLTE_NRE; + break; + default: + m = 0; break; } return m; @@ -729,6 +739,8 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, if (corr > corr_max && corr >= q->threshold_format1a) { corr_max = corr; b_max = b; + } + if (corr_max > q->threshold_format1a) { ret = 1; } DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a); @@ -740,7 +752,6 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, ret = SRSLTE_ERROR; break; } - ret = SRSLTE_SUCCESS; } return ret; diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index d4a97aaa9..40a0e3adc 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -265,6 +265,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, // Choose n_pucch uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data.scheduling_request, &q->pucch_sched); + if (srslte_pucch_encode(&q->pucch, format, n_pucch, sf_idx, pucch_bits, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); return ret; From 64621b51662d54c21fad81579a20a7c7490632c2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 27 Oct 2016 18:03:37 +0200 Subject: [PATCH 050/111] fixed coverty issues --- srslte/lib/ch_estimation/refsignal_ul.c | 10 +++------- srslte/lib/fec/viterbi37_port.c | 5 +++-- srslte/lib/fec/viterbi37_sse.c | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/srslte/lib/ch_estimation/refsignal_ul.c b/srslte/lib/ch_estimation/refsignal_ul.c index f203d6250..e2316e1dd 100644 --- a/srslte/lib/ch_estimation/refsignal_ul.c +++ b/srslte/lib/ch_estimation/refsignal_ul.c @@ -586,13 +586,9 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma if (m == 1) { z_m = z_m_1; } - if (w) { - for (uint32_t n=0;ntmp_arg[n]+alpha*n)); - } - } else { - return SRSLTE_ERROR; - } + for (uint32_t n=0;ntmp_arg[n]+alpha*n)); + } } } ret = SRSLTE_SUCCESS; diff --git a/srslte/lib/fec/viterbi37_port.c b/srslte/lib/fec/viterbi37_port.c index caa2f26db..db2acc7e7 100644 --- a/srslte/lib/fec/viterbi37_port.c +++ b/srslte/lib/fec/viterbi37_port.c @@ -50,10 +50,11 @@ int init_viterbi37_port(void *p, int starting_state) { struct v37 *vp = p; uint32_t i; - clear_v37(vp); - if (p == NULL) return -1; + + clear_v37(vp); + for (i = 0; i < 64; i++) vp->metrics1.w[i] = 63; diff --git a/srslte/lib/fec/viterbi37_sse.c b/srslte/lib/fec/viterbi37_sse.c index cf7cefd26..d6dc6a9e2 100644 --- a/srslte/lib/fec/viterbi37_sse.c +++ b/srslte/lib/fec/viterbi37_sse.c @@ -69,12 +69,12 @@ void clear_v37_sse(struct v37 *vp) { int init_viterbi37_sse(void *p, int starting_state) { struct v37 *vp = p; uint32_t i; - - clear_v37_sse(vp); for(i=0;i<64;i++) vp->metrics1.c[i] = 63; + clear_v37_sse(vp); + vp->old_metrics = &vp->metrics1; vp->new_metrics = &vp->metrics2; vp->dp = vp->decisions; From 3ad996cf90a88e707a1c17a55f56c26a7fbd0a41 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 28 Oct 2016 13:27:03 +0200 Subject: [PATCH 051/111] pucch2: missing cqi encoding bits --- srslte/lib/ue/ue_ul.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index 40a0e3adc..483c83820 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -229,9 +229,12 @@ void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format pucch_bits[0] = uci_data->uci_ack; pucch_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 1a } - if (format == SRSLTE_PUCCH_FORMAT_2A || format == SRSLTE_PUCCH_FORMAT_2B) { - pucch2_bits[0] = uci_data->uci_ack; - pucch2_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 2a + if (format >= SRSLTE_PUCCH_FORMAT_2) { + srslte_uci_encode_cqi_pucch(uci_data->uci_cqi, uci_data->uci_cqi_len, pucch_bits); + if (format > SRSLTE_PUCCH_FORMAT_2) { + pucch2_bits[0] = uci_data->uci_ack; + pucch2_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 2a + } } } From 3a8c813809ef435150d7a9a62ef0277a9171f364 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 8 Nov 2016 17:01:14 +0100 Subject: [PATCH 052/111] pregenerate dci locations --- srslte/include/srslte/ue/ue_dl.h | 15 +++++ srslte/lib/enb/enb_dl.c | 2 +- srslte/lib/enb/enb_ul.c | 2 +- srslte/lib/phch/test/pdcch_file_test.c | 2 - srslte/lib/phch/test/pdcch_test_mex.c | 1 - srslte/lib/phch/test/pdsch_pdcch_file_test.c | 2 - srslte/lib/ue/ue_dl.c | 69 +++++++++++++------- 7 files changed, 62 insertions(+), 31 deletions(-) diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 9624acdea..0efe89ada 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -60,6 +60,18 @@ #include "srslte/config.h" + +#define MAX_CANDIDATES_UE 16 // From 36.213 Table 9.1.1-1 +#define MAX_CANDIDATES_COM 6 // From 36.213 Table 9.1.1-1 +#define MAX_CANDIDATES (MAX_CANDIDATES_UE + MAX_CANDIDATES_COM) + + +typedef struct { + srslte_dci_format_t format; + srslte_dci_location_t loc[MAX_CANDIDATES]; + uint32_t nof_locations; +} dci_blind_search_t; + typedef struct SRSLTE_API { srslte_pcfich_t pcfich; srslte_pdcch_t pdcch; @@ -85,7 +97,10 @@ typedef struct SRSLTE_API { uint64_t nof_detected; uint16_t current_rnti; + dci_blind_search_t current_ss_ue[3][10]; + dci_blind_search_t current_ss_common[3]; srslte_dci_location_t last_location; + srslte_dci_location_t last_location_ul; srslte_dci_msg_t pending_ul_dci_msg; uint16_t pending_ul_dci_rnti; diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index 958133ea5..7d42145e5 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -37,7 +37,7 @@ #define CURRENT_SLOTLEN_RE SRSLTE_SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp) #define CURRENT_SFLEN_RE SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp) -#define SRSLTE_ENB_RF_AMP 0.8 +#define SRSLTE_ENB_RF_AMP 0.5 int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti) { diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 146d36830..cf6f63c99 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -73,7 +73,7 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, fprintf(stderr, "Error initiating FFT\n"); goto clean_exit; } - srslte_ofdm_set_normalize(&q->fft, true); + srslte_ofdm_set_normalize(&q->fft, false); srslte_ofdm_set_freq_shift(&q->fft, -0.5); if (srslte_pucch_init(&q->pucch, q->cell)) { diff --git a/srslte/lib/phch/test/pdcch_file_test.c b/srslte/lib/phch/test/pdcch_file_test.c index a53dd7afc..ed3aafdf4 100644 --- a/srslte/lib/phch/test/pdcch_file_test.c +++ b/srslte/lib/phch/test/pdcch_file_test.c @@ -34,8 +34,6 @@ char *input_file_name = NULL; -#define MAX_CANDIDATES 16 - srslte_cell_t cell = { 6, // cell.cell.cell.nof_prb 1, // cell.cell.nof_ports diff --git a/srslte/lib/phch/test/pdcch_test_mex.c b/srslte/lib/phch/test/pdcch_test_mex.c index e2728be2c..e30ef900f 100644 --- a/srslte/lib/phch/test/pdcch_test_mex.c +++ b/srslte/lib/phch/test/pdcch_test_mex.c @@ -36,7 +36,6 @@ #define INPUT prhs[2] #define NOF_INPUTS 3 -#define MAX_CANDIDATES 16 srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FORMAT1}; // SRSLTE_DCI_FORMAT1B should go here also diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index 9ee136c86..372683a36 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -32,8 +32,6 @@ #include "srslte/srslte.h" -#define MAX_CANDIDATES 16 - char *input_file_name = NULL; srslte_cell_t cell = { diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 8f4ad9afa..057a911cf 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -37,7 +37,6 @@ #define CURRENT_SLOTLEN_RE SRSLTE_SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp) #define CURRENT_SFLEN_RE SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp) -#define MAX_LOCATIONS 64 static srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1}; // Only TM1 and TM2 are currently supported const uint32_t nof_ue_formats = 2; @@ -159,6 +158,15 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { */ void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q, uint16_t rnti) { srslte_pdsch_set_rnti(&q->pdsch, rnti); + + // Compute UE-specific and Common search space for this RNTI + for (int cfi=0;cfi<3;cfi++) { + for (int sf_idx=0;sf_idx<10;sf_idx++) { + q->current_ss_ue[cfi][sf_idx].nof_locations = srslte_pdcch_ue_locations(&q->pdcch, q->current_ss_ue[cfi][sf_idx].loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + } + q->current_ss_common[cfi].nof_locations = srslte_pdcch_common_locations(&q->pdcch, q->current_ss_common[cfi].loc, MAX_CANDIDATES_COM, cfi); + } + q->current_rnti = rnti; } @@ -325,15 +333,6 @@ uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { return q->last_location.ncce; } -#define MAX_CANDIDATES_UE 16 // From 36.213 Table 9.1.1-1 -#define MAX_CANDIDATES_COM 6 // From 36.213 Table 9.1.1-1 -#define MAX_CANDIDATES (MAX_CANDIDATES_UE + MAX_CANDIDATES_COM) -typedef struct { - srslte_dci_format_t format; - srslte_dci_location_t loc[MAX_CANDIDATES]; - uint32_t nof_locations; -} dci_blind_search_t; - static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, uint16_t rnti, srslte_dci_msg_t *dci_msg) { int ret = SRSLTE_ERROR; @@ -354,10 +353,15 @@ static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, { q->pending_ul_dci_rnti = crc_rem; memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); + memcpy(&q->last_location_ul, &search_space->loc[i], sizeof(srslte_dci_location_t)); // Else if we found it, save location and leave } else if (dci_msg->format == search_space->format) { ret = 1; - memcpy(&q->last_location, &search_space->loc[i], sizeof(srslte_dci_location_t)); + if (search_space->format == SRSLTE_DCI_FORMAT0) { + memcpy(&q->last_location_ul, &search_space->loc[i], sizeof(srslte_dci_location_t)); + } else { + memcpy(&q->last_location, &search_space->loc[i], sizeof(srslte_dci_location_t)); + } } } i++; @@ -380,10 +384,16 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, u // Configure and run DCI blind search dci_blind_search_t search_space; - search_space.format = SRSLTE_DCI_FORMAT0; - search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + dci_blind_search_t *current_ss = &search_space; + if (q->current_rnti == rnti) { + current_ss = &q->current_ss_ue[cfi-1][sf_idx]; + } else { + // If locations are not pre-generated, generate them now + current_ss->nof_locations = srslte_pdcch_ue_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + } + current_ss->format = SRSLTE_DCI_FORMAT0; INFO("Searching UL C-RNTI in %d ue locations\n", search_space.nof_locations); - return dci_blind_search(q, &search_space, rnti, dci_msg); + return dci_blind_search(q, current_ss, rnti, dci_msg); } else { return 0; } @@ -428,25 +438,36 @@ static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, uint32_t cfi, uint16_t static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, srslte_dci_msg_t *dci_msg) { int ret = SRSLTE_SUCCESS; + dci_blind_search_t search_space; + dci_blind_search_t *current_ss = &search_space; // Search UE-specific search space - dci_blind_search_t search_space; - search_space.nof_locations = srslte_pdcch_ue_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); - INFO("Searching DL C-RNTI in %d ue locations, %d formats\n", search_space.nof_locations, nof_ue_formats); + if (q->current_rnti == rnti) { + current_ss = &q->current_ss_ue[cfi-1][sf_idx]; + } else { + // If locations are not pre-generated, generate them now + current_ss->nof_locations = srslte_pdcch_ue_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + } + INFO("Searching DL C-RNTI in %d ue locations, %d formats\n", current_ss->nof_locations, nof_ue_formats); for (int f=0;fformat = ue_formats[f]; + if ((ret = dci_blind_search(q, current_ss, rnti, dci_msg))) { return ret; } } // Search Format 1A in the Common SS also - search_space.format = SRSLTE_DCI_FORMAT1A; - search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, cfi); + if (q->current_rnti == rnti) { + current_ss = &q->current_ss_common[cfi-1]; + } else { + // If locations are not pre-generated, generate them now + current_ss->nof_locations = srslte_pdcch_common_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_COM, cfi); + } // Search for RNTI only if there is room for the common search space - if (search_space.nof_locations > 0) { - INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", search_space.nof_locations, nof_ue_formats); - return dci_blind_search(q, &search_space, rnti, dci_msg); + if (current_ss->nof_locations > 0) { + current_ss->format = SRSLTE_DCI_FORMAT1A; + INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", current_ss->nof_locations, nof_ue_formats); + return dci_blind_search(q, current_ss, rnti, dci_msg); } return SRSLTE_SUCCESS; } From dd694be141f1c050b5ed5a78dfab31e70aa1d3ec Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 9 Nov 2016 10:47:28 +0100 Subject: [PATCH 053/111] added interface to pdcch_set_cfi --- srslte/include/srslte/phch/pdcch.h | 3 +++ srslte/lib/phch/dci.c | 2 +- srslte/lib/phch/pdcch.c | 6 +++++- srslte/lib/ue/ue_dl.c | 25 ++++++++++++++++++------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/srslte/include/srslte/phch/pdcch.h b/srslte/include/srslte/phch/pdcch.h index b0f09a898..a2c6deb7f 100644 --- a/srslte/include/srslte/phch/pdcch.h +++ b/srslte/include/srslte/phch/pdcch.h @@ -90,6 +90,9 @@ SRSLTE_API int srslte_pdcch_init(srslte_pdcch_t *q, SRSLTE_API void srslte_pdcch_free(srslte_pdcch_t *q); +SRSLTE_API void srslte_pdcch_set_cfi(srslte_pdcch_t *q, + uint32_t cfi); + /* Encoding function */ SRSLTE_API int srslte_pdcch_encode(srslte_pdcch_t *q, srslte_dci_msg_t *msg, diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 66a1b218f..9bb8c96be 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -65,7 +65,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { - //fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); + fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); return ret; } diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 5e03b9fbf..4ab576287 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -52,6 +52,9 @@ static void set_cfi(srslte_pdcch_t *q, uint32_t cfi) { } } +void srslte_pdcch_set_cfi(srslte_pdcch_t *q, uint32_t cfi) { + set_cfi(q, cfi); +} /** Initializes the PDCCH transmitter and receiver */ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell) { @@ -217,7 +220,8 @@ uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t } } - DEBUG("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x\n", k, rnti); + DEBUG("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x, nsubframe=%d, nof_cce=%d\n", + k, rnti, nsubframe, nof_cce); return k; } diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 057a911cf..a3e3783d7 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -162,9 +162,9 @@ void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q, uint16_t rnti) { // Compute UE-specific and Common search space for this RNTI for (int cfi=0;cfi<3;cfi++) { for (int sf_idx=0;sf_idx<10;sf_idx++) { - q->current_ss_ue[cfi][sf_idx].nof_locations = srslte_pdcch_ue_locations(&q->pdcch, q->current_ss_ue[cfi][sf_idx].loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); + q->current_ss_ue[cfi][sf_idx].nof_locations = srslte_pdcch_ue_locations(&q->pdcch, q->current_ss_ue[cfi][sf_idx].loc, MAX_CANDIDATES_UE, sf_idx, cfi+1, rnti); } - q->current_ss_common[cfi].nof_locations = srslte_pdcch_common_locations(&q->pdcch, q->current_ss_common[cfi].loc, MAX_CANDIDATES_COM, cfi); + q->current_ss_common[cfi].nof_locations = srslte_pdcch_common_locations(&q->pdcch, q->current_ss_common[cfi].loc, MAX_CANDIDATES_COM, cfi+1); } q->current_rnti = rnti; @@ -341,8 +341,10 @@ static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, ret = 0; int i=0; while (!ret && i < search_space->nof_locations) { - INFO("Searching format %s in %d,%d\n", - srslte_dci_format_string(search_space->format), search_space->loc[i].ncce, search_space->loc[i].L); + DEBUG("Searching format %s in %d,%d (%d/%d)\n", + srslte_dci_format_string(search_space->format), search_space->loc[i].ncce, search_space->loc[i].L, + i, search_space->nof_locations); + if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &search_space->loc[i], search_space->format, &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; @@ -357,7 +359,7 @@ static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, // Else if we found it, save location and leave } else if (dci_msg->format == search_space->format) { ret = 1; - if (search_space->format == SRSLTE_DCI_FORMAT0) { + if (dci_msg->format == SRSLTE_DCI_FORMAT0) { memcpy(&q->last_location_ul, &search_space->loc[i], sizeof(srslte_dci_location_t)); } else { memcpy(&q->last_location, &search_space->loc[i], sizeof(srslte_dci_location_t)); @@ -385,12 +387,15 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, u // Configure and run DCI blind search dci_blind_search_t search_space; dci_blind_search_t *current_ss = &search_space; - if (q->current_rnti == rnti) { + if (q->current_rnti == rnti) { current_ss = &q->current_ss_ue[cfi-1][sf_idx]; } else { // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_ue_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); - } + } + + srslte_pdcch_set_cfi(&q->pdcch, cfi); + current_ss->format = SRSLTE_DCI_FORMAT0; INFO("Searching UL C-RNTI in %d ue locations\n", search_space.nof_locations); return dci_blind_search(q, current_ss, rnti, dci_msg); @@ -448,6 +453,9 @@ static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_i // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_ue_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); } + + srslte_pdcch_set_cfi(&q->pdcch, cfi); + INFO("Searching DL C-RNTI in %d ue locations, %d formats\n", current_ss->nof_locations, nof_ue_formats); for (int f=0;fformat = ue_formats[f]; @@ -463,6 +471,9 @@ static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_i // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_common_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_COM, cfi); } + + srslte_pdcch_set_cfi(&q->pdcch, cfi); + // Search for RNTI only if there is room for the common search space if (current_ss->nof_locations > 0) { current_ss->format = SRSLTE_DCI_FORMAT1A; From 82e4b37d401508ba4efc90d9410f5e2f7d021d78 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 9 Nov 2016 11:21:42 +0100 Subject: [PATCH 054/111] PUCCH: fixed incorrect allocation for format2a --- srslte/lib/phch/pucch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index cce37fc38..c810f8b2a 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -192,15 +192,15 @@ srslte_pucch_format_t srslte_pucch_get_format(srslte_uci_data_t *uci_data, srslt format = SRSLTE_PUCCH_FORMAT_2; } // CQI + 1-bit ACK - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1) { + else if (uci_data->uci_ack_len == 1 && SRSLTE_CP_ISNORM(cp)) { format = SRSLTE_PUCCH_FORMAT_2A; } // CQI + 2-bit ACK - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 2) { + else if (uci_data->uci_ack_len == 2) { format = SRSLTE_PUCCH_FORMAT_2B; } // CQI + 2-bit ACK + cyclic prefix - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { + else if (uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { format = SRSLTE_PUCCH_FORMAT_2B; } } @@ -213,7 +213,7 @@ uint32_t srslte_pucch_get_npucch(uint32_t n_cce, srslte_pucch_format_t format, b uint32_t n_pucch = 0; if (has_scheduling_request) { n_pucch = pucch_sched->n_pucch_sr; - } else if (format != SRSLTE_PUCCH_FORMAT_2) { + } else if (format < SRSLTE_PUCCH_FORMAT_2) { if (pucch_sched->sps_enabled) { n_pucch = pucch_sched->n_pucch_1[pucch_sched->tpc_for_pucch%4]; } else { From b5554ce9267782679ada6849187151e1b5547694 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 11 Nov 2016 12:45:03 +0100 Subject: [PATCH 055/111] minor printf change --- srslte/lib/ue/ue_dl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index a3e3783d7..9444be773 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -477,7 +477,7 @@ static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_i // Search for RNTI only if there is room for the common search space if (current_ss->nof_locations > 0) { current_ss->format = SRSLTE_DCI_FORMAT1A; - INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", current_ss->nof_locations, nof_ue_formats); + INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", current_ss->nof_locations); return dci_blind_search(q, current_ss, rnti, dci_msg); } return SRSLTE_SUCCESS; From f0e0a717923847b7292560e952393e31d4708fe6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 16 Nov 2016 12:07:56 +0100 Subject: [PATCH 056/111] pucch: added function to get last correlation --- srslte/include/srslte/phch/pucch.h | 3 +++ srslte/lib/phch/pucch.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index c5f9f7ea5..f99ecfe51 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -101,6 +101,7 @@ typedef struct SRSLTE_API { float threshold_format1; float threshold_format1a; + float last_corr; }srslte_pucch_t; @@ -125,6 +126,8 @@ SRSLTE_API uint32_t srslte_pucch_nof_symbols(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, bool shortened); +SRSLTE_API float srslte_pucch_get_last_corr(srslte_pucch_t* q); + SRSLTE_API int srslte_pucch_encode(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n_pucch, // n_pucch_1 or n_pucch_2 depending on format diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index c810f8b2a..6beb4afc4 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -671,6 +671,10 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, return ret; } +float srslte_pucch_get_last_corr(srslte_pucch_t* q) +{ + return q->last_corr; +} /* Equalize, demodulate and decode PUCCH bits according to Section 5.4.1 of 36.211 */ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, @@ -752,6 +756,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, ret = SRSLTE_ERROR; break; } + q->last_corr = corr; } return ret; From d51cc4b6a620da7d7f0a55a662406569a4355cf7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 16 Nov 2016 13:08:28 +0100 Subject: [PATCH 057/111] Updated to version 1.4 --- CHANGELOG | 5 +++++ cmake/modules/SRSLTEVersion.cmake | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 57aba3f80..3aa324c0a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ Change Log for Releases ============================== +## 001.004.000 + * Fixed issue in rv for format1C causing incorrect SIB1 decoding in some networks + * Improved PDCCH decoding BER (fixed incorrect trellis initialization) + * Improved PUCCH RX performance + ## 001.003.000 * Bugfixes: diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index 39937c1d8..07959f188 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -19,6 +19,6 @@ # SET(SRSLTE_VERSION_MAJOR 001) -SET(SRSLTE_VERSION_MINOR 003) -SET(SRSLTE_VERSION_PATCH 001) +SET(SRSLTE_VERSION_MINOR 004) +SET(SRSLTE_VERSION_PATCH 000) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") From fd4eb44bfcf4dfcd4b0904cc7eeb56bc19bf8bfb Mon Sep 17 00:00:00 2001 From: Agmagor Date: Wed, 16 Nov 2016 16:46:22 +0100 Subject: [PATCH 058/111] memleak: free cellsearch buffer after scan --- srslte/examples/cell_search.c | 1 + 1 file changed, 1 insertion(+) diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index fb4933ebd..02c3d8ada 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -218,6 +218,7 @@ int main(int argc, char **argv) { srslte_rf_start_rx_stream(&rf); n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL); + srslte_ue_cellsearch_free(&cs); if (n < 0) { fprintf(stderr, "Error searching cell\n"); exit(-1); From 388eb35e6703153c56d96cdbf52c103e8e1dd701 Mon Sep 17 00:00:00 2001 From: Agmagor Date: Thu, 17 Nov 2016 17:14:08 +0100 Subject: [PATCH 059/111] memleak: free FFT plan upon pss_synch_free --- srslte/lib/sync/pss.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/srslte/lib/sync/pss.c b/srslte/lib/sync/pss.c index 46c02414e..647baa838 100644 --- a/srslte/lib/sync/pss.c +++ b/srslte/lib/sync/pss.c @@ -202,6 +202,8 @@ void srslte_pss_synch_free(srslte_pss_synch_t *q) { if (q->conv_output_avg) { free(q->conv_output_avg); } + + srslte_dft_plan_free(&q->dftp_input); bzero(q, sizeof(srslte_pss_synch_t)); } From a98f19a05e794118aa09708786ab3021445fb0db Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 17 Nov 2016 20:04:54 +0100 Subject: [PATCH 060/111] Added CQI unpacking functions --- srslte/include/srslte/phch/cqi.h | 19 ++++++++ srslte/lib/phch/cqi.c | 83 +++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/srslte/include/srslte/phch/cqi.h b/srslte/include/srslte/phch/cqi.h index 68ed8ca2a..931f09566 100644 --- a/srslte/include/srslte/phch/cqi.h +++ b/srslte/include/srslte/phch/cqi.h @@ -104,6 +104,8 @@ typedef struct { } srslte_cqi_value_t; +SRSLTE_API int srslte_cqi_size(srslte_cqi_value_t *value); + SRSLTE_API int srslte_cqi_value_pack(srslte_cqi_value_t *value, uint8_t buff[SRSLTE_CQI_MAX_BITS]); @@ -119,11 +121,28 @@ SRSLTE_API int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *m SRSLTE_API int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS]); +SRSLTE_API int srslte_cqi_value_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], + srslte_cqi_value_t *value); + +SRSLTE_API int srslte_cqi_hl_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], + srslte_cqi_hl_subband_t *msg); + +SRSLTE_API int srslte_cqi_ue_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], + srslte_cqi_ue_subband_t *msg); + +SRSLTE_API int srslte_cqi_format2_wideband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], + srslte_cqi_format2_wideband_t *msg); + +SRSLTE_API int srslte_cqi_format2_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], + srslte_cqi_format2_subband_t *msg); + SRSLTE_API bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti); SRSLTE_API uint8_t srslte_cqi_from_snr(float snr); +SRSLTE_API float srslte_cqi_to_coderate(uint32_t cqi); + SRSLTE_API int srslte_cqi_hl_get_subband_size(int num_prbs); SRSLTE_API int srslte_cqi_hl_get_no_subbands(int num_prbs); diff --git a/srslte/lib/phch/cqi.c b/srslte/lib/phch/cqi.c index df46152b0..5ac536341 100644 --- a/srslte/lib/phch/cqi.c +++ b/srslte/lib/phch/cqi.c @@ -39,7 +39,9 @@ #include "srslte/utils/vector.h" #include "srslte/utils/debug.h" - +/******************************************************* + * PACKING FUNCTIONS * + *******************************************************/ int srslte_cqi_hl_subband_pack(srslte_cqi_hl_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS]) { uint8_t *body_ptr = buff; @@ -89,6 +91,74 @@ int srslte_cqi_value_pack(srslte_cqi_value_t *value, uint8_t buff[SRSLTE_CQI_MAX return -1; } + +/******************************************************* + * UNPACKING FUNCTIONS * + *******************************************************/ + +int srslte_cqi_hl_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_hl_subband_t *msg) +{ + uint8_t *body_ptr = buff; + msg->wideband_cqi = srslte_bit_pack(&body_ptr, 4); + msg->subband_diff_cqi = srslte_bit_pack(&body_ptr, 2*msg->N); + + return 4+2*msg->N; +} + +int srslte_cqi_ue_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_ue_subband_t *msg) +{ + uint8_t *body_ptr = buff; + msg->wideband_cqi = srslte_bit_pack(&body_ptr, 4); + msg->subband_diff_cqi = srslte_bit_pack(&body_ptr, 2); + msg->subband_diff_cqi = srslte_bit_pack(&body_ptr, msg->L); + + return 4+2+msg->L; +} + +int srslte_cqi_format2_wideband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_format2_wideband_t *msg) +{ + uint8_t *body_ptr = buff; + msg->wideband_cqi = srslte_bit_pack(&body_ptr, 4); + return 4; +} + +int srslte_cqi_format2_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_format2_subband_t *msg) +{ + uint8_t *body_ptr = buff; + msg->subband_cqi = srslte_bit_pack(&body_ptr, 4); + msg->subband_label = srslte_bit_pack(&body_ptr, msg->subband_label_2_bits?2:1); + return 4+(msg->subband_label_2_bits)?2:1; +} + +int srslte_cqi_value_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_value_t *value) +{ + switch(value->type) { + case SRSLTE_CQI_TYPE_WIDEBAND: + return srslte_cqi_format2_wideband_unpack(buff, &value->wideband); + case SRSLTE_CQI_TYPE_SUBBAND: + return srslte_cqi_format2_subband_unpack(buff, &value->subband); + case SRSLTE_CQI_TYPE_SUBBAND_UE: + return srslte_cqi_ue_subband_unpack(buff, &value->subband_ue); + case SRSLTE_CQI_TYPE_SUBBAND_HL: + return srslte_cqi_hl_subband_unpack(buff, &value->subband_hl); + } + return -1; +} + +int srslte_cqi_size(srslte_cqi_value_t *value) { + switch(value->type) { + case SRSLTE_CQI_TYPE_WIDEBAND: + return 4; + case SRSLTE_CQI_TYPE_SUBBAND: + return 4+(value->subband.subband_label_2_bits)?2:1; + case SRSLTE_CQI_TYPE_SUBBAND_UE: + return 4+2+value->subband_ue.L; + case SRSLTE_CQI_TYPE_SUBBAND_HL: + return 4+2*value->subband_hl.N; + } + return -1; +} + bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) { uint32_t N_p = 0; @@ -138,6 +208,17 @@ bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) { } +// CQI-to-Spectral Efficiency: 36.213 Table 7.2.3-1 */ +static float cqi_to_coderate[16] = {0, 0.1523, 0.2344, 0.3770, 0.6016, 0.8770, 1.1758, 1.4766, 1.9141, 2.4063, 2.7305, 3.3223, 3.9023, 4.5234, 5.1152, 5.5547}; + +float srslte_cqi_to_coderate(uint32_t cqi) { + if (cqi < 16) { + return cqi_to_coderate[cqi]; + } else { + return 0; + } +} + /* SNR-to-CQI conversion, got from "Downlink SNR to CQI Mapping for Different Multiple Antenna Techniques in LTE" * Table III. */ From bb5e511513f474614ae1b5a2223c98c6c2ca8974 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 17 Nov 2016 20:05:34 +0100 Subject: [PATCH 061/111] Fixed ULSCH CQI receiver --- srslte/include/srslte/phch/pdsch.h | 5 +++++ srslte/include/srslte/utils/vector.h | 1 + srslte/lib/phch/pdsch.c | 4 ++++ srslte/lib/phch/sch.c | 6 ------ srslte/lib/phch/uci.c | 6 +++--- srslte/lib/utils/vector.c | 11 +++++++++++ 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/srslte/include/srslte/phch/pdsch.h b/srslte/include/srslte/phch/pdsch.h index b65260eac..3e6580763 100644 --- a/srslte/include/srslte/phch/pdsch.h +++ b/srslte/include/srslte/phch/pdsch.h @@ -95,6 +95,11 @@ SRSLTE_API int srslte_pdsch_set_rnti_multi(srslte_pdsch_t *q, SRSLTE_API uint16_t srslte_pdsch_get_rnti_multi(srslte_pdsch_t *q, uint32_t idx); +SRSLTE_API float srslte_pdsch_coderate(uint32_t tbs, + uint32_t nof_re); + +SRSLTE_API void print_pdsch_coderate(); + SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, diff --git a/srslte/include/srslte/utils/vector.h b/srslte/include/srslte/utils/vector.h index 027487818..7d6c04cba 100644 --- a/srslte/include/srslte/utils/vector.h +++ b/srslte/include/srslte/utils/vector.h @@ -156,6 +156,7 @@ SRSLTE_API float srslte_vec_avg_power_cf(cf_t *x, uint32_t len); SRSLTE_API uint32_t srslte_vec_max_fi(float *x, uint32_t len); SRSLTE_API uint32_t srslte_vec_max_abs_ci(cf_t *x, uint32_t len); SRSLTE_API int16_t srslte_vec_max_star_si(int16_t *x, uint32_t len); +SRSLTE_API int16_t srslte_vec_max_abs_star_si(int16_t *x, uint32_t len); /* maximum between two vectors */ SRSLTE_API void srslte_vec_max_fff(float *x, float *y, float *z, uint32_t len); diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index 56089cefb..3e8aeb660 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -57,6 +57,10 @@ extern int indices[100000]; extern int indices_ptr; #endif +float srslte_pdsch_coderate(uint32_t tbs, uint32_t nof_re) +{ + return (float) (tbs + 24)/(nof_re); +} int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant, uint32_t lstart_grant, uint32_t nsubframe, bool put) { diff --git a/srslte/lib/phch/sch.c b/srslte/lib/phch/sch.c index 5b0c6c266..c144f1265 100644 --- a/srslte/lib/phch/sch.c +++ b/srslte/lib/phch/sch.c @@ -646,16 +646,10 @@ int srslte_ulsch_uci_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_sof // Decode CQI (multiplexed at the front of ULSCH) if (uci_data->uci_cqi_len > 0) { - struct timeval t[3]; - gettimeofday(&t[1], NULL); ret = srslte_uci_decode_cqi_pusch(&q->uci_cqi, cfg, g_bits, beta_cqi_offset[cfg->uci_cfg.I_offset_cqi], Q_prime_ri, uci_data->uci_cqi_len, uci_data->uci_cqi, &uci_data->cqi_ack); - gettimeofday(&t[2], NULL); - get_time_interval(t); - printf("texec=%d us\n", t[0].tv_usec); - if (ret < 0) { return ret; } diff --git a/srslte/lib/phch/uci.c b/srslte/lib/phch/uci.c index ece0702c2..8861749e2 100644 --- a/srslte/lib/phch/uci.c +++ b/srslte/lib/phch/uci.c @@ -298,10 +298,10 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q, srslte_rm_conv_rx_s(q_bits, Q, q->encoded_cqi_s, 3 * (nof_bits + 8)); // Set viterbi normalization based on amplitude - int16_t max = srslte_vec_max_star_si(q->encoded_cqi_s, 3 * (nof_bits + 8)); - srslte_viterbi_set_gain_quant_s(&q->viterbi, max/36); + int16_t max = srslte_vec_max_abs_star_si(q->encoded_cqi_s, 3 * (nof_bits + 8)); + srslte_viterbi_set_gain_quant_s(&q->viterbi, (float) abs(max)/36); - DEBUG("cconv_rx=", 0); + DEBUG("cconv_rx=", 0); if (SRSLTE_VERBOSE_ISDEBUG()) { srslte_vec_fprint_s(stdout, q->encoded_cqi_s, 3 * (nof_bits + 8)); } diff --git a/srslte/lib/utils/vector.c b/srslte/lib/utils/vector.c index 77c674ba0..469320177 100644 --- a/srslte/lib/utils/vector.c +++ b/srslte/lib/utils/vector.c @@ -729,6 +729,17 @@ int16_t srslte_vec_max_star_si(int16_t *x, uint32_t len) { #endif } +int16_t srslte_vec_max_abs_star_si(int16_t *x, uint32_t len) { + uint32_t i; + int16_t m=-INT16_MIN; + for (i=0;im) { + m=abs(x[i]); + } + } + return m; +} + void srslte_vec_max_fff(float *x, float *y, float *z, uint32_t len) { #ifdef HAVE_VOLK_MAX_VEC_FUNCTION volk_32f_x2_max_32f(z,x,y,len); From 4a2d9d1776c88851462b91e3f24e12fd9f9496de Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 17 Nov 2016 20:05:56 +0100 Subject: [PATCH 062/111] Added functions for spectral efficiency computation --- srslte/include/srslte/phch/pdcch.h | 3 +++ srslte/include/srslte/phch/ra.h | 8 +++++++- srslte/lib/phch/pdcch.c | 4 ++++ srslte/lib/phch/ra.c | 18 ++++++++++++++---- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/srslte/include/srslte/phch/pdcch.h b/srslte/include/srslte/phch/pdcch.h index a2c6deb7f..5f080cbd8 100644 --- a/srslte/include/srslte/phch/pdcch.h +++ b/srslte/include/srslte/phch/pdcch.h @@ -93,6 +93,9 @@ SRSLTE_API void srslte_pdcch_free(srslte_pdcch_t *q); SRSLTE_API void srslte_pdcch_set_cfi(srslte_pdcch_t *q, uint32_t cfi); +SRSLTE_API float srslte_pdcch_coderate(uint32_t nof_bits, + uint32_t l); + /* Encoding function */ SRSLTE_API int srslte_pdcch_encode(srslte_pdcch_t *q, srslte_dci_msg_t *msg, diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index b32f759b2..5da9a191b 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -222,13 +222,19 @@ SRSLTE_API void srslte_ra_ul_grant_to_nbits(srslte_ra_ul_grant_t *grant, uint32_t N_srs, srslte_ra_nbits_t *nbits); -SRSLTE_API int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, +SRSLTE_API int srslte_ra_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t n_rb_ho, uint32_t nof_prb); +SRSLTE_API int srslte_ra_dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, + srslte_ra_dl_grant_t *grant, + uint32_t nof_prb); + SRSLTE_API int srslte_ra_tbs_idx_from_mcs(uint32_t mcs); +SRSLTE_API srslte_mod_t srslte_ra_mod_from_mcs(uint32_t mcs); + SRSLTE_API int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx); SRSLTE_API int srslte_ra_tbs_from_idx(uint32_t tbs_idx, diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 4ab576287..ae0d77517 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -56,6 +56,10 @@ void srslte_pdcch_set_cfi(srslte_pdcch_t *q, uint32_t cfi) { set_cfi(q, cfi); } +float srslte_pdcch_coderate(uint32_t nof_bits, uint32_t l) { + return (float) (nof_bits+16)/PDCCH_FORMAT_NOF_BITS(l); +} + /** Initializes the PDCCH transmitter and receiver */ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index 3a5b67a40..2f4db4074 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -106,7 +106,7 @@ uint32_t ra_re_x_prb(uint32_t subframe, uint32_t slot, uint32_t prb_idx, uint32_ return re; } -int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t n_rb_ho, uint32_t nof_prb) +int srslte_ra_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t n_rb_ho, uint32_t nof_prb) { bzero(grant, sizeof(srslte_ra_ul_grant_t)); @@ -228,7 +228,7 @@ int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, uint32_t nof_prb, uint32_ { // Compute PRB allocation - if (!srslte_ul_dci_to_grant_prb_allocation(dci, grant, n_rb_ho, nof_prb)) { + if (!srslte_ra_ul_dci_to_grant_prb_allocation(dci, grant, n_rb_ho, nof_prb)) { // Compute MCS if (!ul_dci_to_grant_mcs(dci, grant, harq_pid)) { @@ -269,7 +269,7 @@ uint32_t srslte_ra_dl_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t ce } /** Compute PRB allocation for Downlink as defined in 7.1.6 of 36.213 */ -static int dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, uint32_t nof_prb) { +int srslte_ra_dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, uint32_t nof_prb) { int i, j; uint32_t bitmask; uint32_t P = srslte_ra_type0_P(nof_prb); @@ -482,7 +482,7 @@ int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, crc_is_crnti = true; } // Compute PRB allocation - if (!dl_dci_to_grant_prb_allocation(dci, grant, nof_prb)) { + if (!srslte_ra_dl_dci_to_grant_prb_allocation(dci, grant, nof_prb)) { // Compute MCS if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) { // Apply Section 7.1.7.3. If RA-RNTI and Format1C rv_idx=0 @@ -592,6 +592,16 @@ int srslte_ra_tbs_idx_from_mcs(uint32_t mcs) { } } +srslte_mod_t srslte_ra_mod_from_mcs(uint32_t mcs) { + if (mcs <= 10 || mcs == 29) { + return SRSLTE_MOD_QPSK; + } else if (mcs <= 17 || mcs == 30) { + return SRSLTE_MOD_16QAM; + } else { + return SRSLTE_MOD_64QAM; + } +} + int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx) { for (int i=0;i<29;i++) { if (tbs_idx == mcs_tbs_idx_table[i]) { From 8b4fa3f8d9798fc5c6a11f40f20470e9be9eb069 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 17 Nov 2016 20:09:22 +0100 Subject: [PATCH 063/111] removed UHD recv/send_frame_size arguments --- srslte/lib/rf/rf_uhd_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index d9683424d..34b4f6000 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -264,7 +264,7 @@ int rf_uhd_open(char *args, void **h) if (args[0]=='\0') { if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { // If B200 is available, use it - args = "type=b200,recv_frame_size=9232,send_frame_size=9232"; + args = "type=b200"; handler->devname = DEVNAME_B200; } else if (find_string(devices_str, "type=x300")) { // Else if X300 is available, set master clock rate now (can't be changed later) From 6d93e4a1ea299bb8d368ab1ddf402c573d6b19a9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 17 Nov 2016 20:29:04 +0100 Subject: [PATCH 064/111] pdcch: fixed coderate computation --- srslte/lib/phch/pdcch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index ae0d77517..8fca3d91d 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -57,7 +57,7 @@ void srslte_pdcch_set_cfi(srslte_pdcch_t *q, uint32_t cfi) { } float srslte_pdcch_coderate(uint32_t nof_bits, uint32_t l) { - return (float) (nof_bits+16)/PDCCH_FORMAT_NOF_BITS(l); + return (float) (nof_bits+16)/(4*PDCCH_FORMAT_NOF_REGS(l)); } /** Initializes the PDCCH transmitter and receiver */ From e957bc8dc84b25638ac8a0293880635f9d537e52 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 18 Nov 2016 13:28:14 +0100 Subject: [PATCH 065/111] enb: not initializaing sequences when removing user --- srslte/lib/phch/pdsch.c | 14 ++++++++------ srslte/lib/phch/pusch.c | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index 3e8aeb660..b6184f0a6 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -387,12 +387,14 @@ int srslte_pdsch_set_rnti_multi(srslte_pdsch_t *q, uint32_t idx, uint16_t rnti) } q->rnti_multi[idx] = 0; } - q->rnti_multi[idx] = rnti; - q->rnti_is_set = true; - for (uint32_t i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pdsch(&q->seq_multi[i][idx], rnti, 0, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - return SRSLTE_ERROR; + if (rnti) { + q->rnti_multi[idx] = rnti; + q->rnti_is_set = true; + for (uint32_t i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + if (srslte_sequence_pdsch(&q->seq_multi[i][idx], rnti, 0, 2 * i, q->cell.id, + q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { + return SRSLTE_ERROR; + } } } return SRSLTE_SUCCESS; diff --git a/srslte/lib/phch/pusch.c b/srslte/lib/phch/pusch.c index 9cf66e8e9..8f73e71da 100644 --- a/srslte/lib/phch/pusch.c +++ b/srslte/lib/phch/pusch.c @@ -430,12 +430,14 @@ int srslte_pusch_set_rnti_multi(srslte_pusch_t *q, uint32_t idx, uint16_t rnti) } q->rnti_multi[idx] = 0; } - q->rnti_multi[idx] = rnti; - q->rnti_is_set = true; - for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pusch(&q->seq_multi[i][idx], rnti, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - return SRSLTE_ERROR; + if (rnti) { + q->rnti_multi[idx] = rnti; + q->rnti_is_set = true; + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + if (srslte_sequence_pusch(&q->seq_multi[i][idx], rnti, 2 * i, q->cell.id, + q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { + return SRSLTE_ERROR; + } } } return SRSLTE_SUCCESS; From 46ce82fd83d37843f20f3eaf6c1ebd7b7f9ae382 Mon Sep 17 00:00:00 2001 From: Agmagor Date: Fri, 18 Nov 2016 17:10:21 +0100 Subject: [PATCH 066/111] free UHD handles upon RF closure --- srslte/lib/rf/rf_uhd_imp.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index 34b4f6000..d16382f52 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -284,6 +284,8 @@ int rf_uhd_open(char *args, void **h) } } + uhd_string_vector_free(&devices_str); + /* Create UHD handler */ printf("Opening USRP with args: %s\n", args); uhd_error error = uhd_usrp_make(&handler->usrp, args); @@ -359,6 +361,19 @@ int rf_uhd_close(void *h) { rf_uhd_stop_rx_stream(h); + rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; + + uhd_tx_metadata_free(&handler->tx_md); + uhd_rx_metadata_free(&handler->rx_md_first); + uhd_rx_metadata_free(&handler->rx_md); + uhd_meta_range_free(&handler->rx_gain_range); + uhd_tx_streamer_free(&handler->tx_stream); + uhd_rx_streamer_free(&handler->rx_stream); + if (handler->has_rssi) { + uhd_sensor_value_free(&handler->rssi_value); + } + uhd_usrp_free(&handler->usrp); + /** Something else to close the USRP?? */ return 0; } From 7d119496120b7102a1ff47153caf9d6280ebd366 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 19 Nov 2016 14:22:10 +0100 Subject: [PATCH 067/111] fixed cqi max bits --- srslte/include/srslte/enb/enb_dl.h | 4 ++++ srslte/include/srslte/phch/cqi.h | 2 +- srslte/lib/enb/enb_dl.c | 10 ++++++++-- srslte/lib/phch/uci.c | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/srslte/include/srslte/enb/enb_dl.h b/srslte/include/srslte/enb/enb_dl.h index a95c6f824..eca63d6d3 100644 --- a/srslte/include/srslte/enb/enb_dl.h +++ b/srslte/include/srslte/enb/enb_dl.h @@ -88,6 +88,7 @@ typedef struct SRSLTE_API { float sss_signal5[SRSLTE_SSS_LEN]; uint32_t nof_rnti; + float tx_amp; } srslte_enb_dl_t; @@ -114,6 +115,9 @@ SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q, uint32_t cfi); +SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, + float amp); + SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q, diff --git a/srslte/include/srslte/phch/cqi.h b/srslte/include/srslte/phch/cqi.h index 931f09566..9a7b243be 100644 --- a/srslte/include/srslte/phch/cqi.h +++ b/srslte/include/srslte/phch/cqi.h @@ -40,7 +40,7 @@ #include "srslte/config.h" #include "srslte/common/phy_common.h" -#define SRSLTE_CQI_MAX_BITS 20 +#define SRSLTE_CQI_MAX_BITS 64 typedef struct { bool configured; diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index 7d42145e5..bbe122c96 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -37,7 +37,7 @@ #define CURRENT_SLOTLEN_RE SRSLTE_SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp) #define CURRENT_SFLEN_RE SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp) -#define SRSLTE_ENB_RF_AMP 0.5 +#define SRSLTE_ENB_RF_AMP 0.1 int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti) { @@ -53,6 +53,7 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti q->cell = cell; q->cfi = 3; q->nof_rnti = nof_rnti; + q->tx_amp = SRSLTE_ENB_RF_AMP; if (srslte_ofdm_tx_init(&q->ifft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -146,6 +147,11 @@ void srslte_enb_dl_free(srslte_enb_dl_t *q) } } +void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, float amp) +{ + q->tx_amp = amp; +} + void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q, uint32_t cfi) { q->cfi = cfi; @@ -214,7 +220,7 @@ void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, cf_t *signal_buffer) // TODO: PAPR control float norm_factor = (float) sqrt(q->cell.nof_prb)/15; - srslte_vec_sc_prod_cfc(signal_buffer, SRSLTE_ENB_RF_AMP*norm_factor, signal_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + srslte_vec_sc_prod_cfc(signal_buffer, q->tx_amp*norm_factor, signal_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } int srslte_enb_dl_cfg_rnti(srslte_enb_dl_t *q, uint32_t idx, uint16_t rnti) diff --git a/srslte/lib/phch/uci.c b/srslte/lib/phch/uci.c index 8861749e2..dd0633768 100644 --- a/srslte/lib/phch/uci.c +++ b/srslte/lib/phch/uci.c @@ -314,6 +314,7 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q, } ret = srslte_crc_checksum(&q->crc, q->tmp_cqi, nof_bits + 8); + printf("ret=%d, nof_bits=%d\n", ret, nof_bits); if (ret == 0) { memcpy(data, q->tmp_cqi, nof_bits*sizeof(uint8_t)); ret = 1; From b8a2ea8f3c5802f4876401f03e50e19e3336aabc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 19 Nov 2016 14:23:21 +0100 Subject: [PATCH 068/111] fixed cqi max bits --- srslte/include/srslte/enb/enb_dl.h | 4 ++++ srslte/include/srslte/phch/cqi.h | 2 +- srslte/lib/enb/enb_dl.c | 10 ++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/srslte/include/srslte/enb/enb_dl.h b/srslte/include/srslte/enb/enb_dl.h index a95c6f824..eca63d6d3 100644 --- a/srslte/include/srslte/enb/enb_dl.h +++ b/srslte/include/srslte/enb/enb_dl.h @@ -88,6 +88,7 @@ typedef struct SRSLTE_API { float sss_signal5[SRSLTE_SSS_LEN]; uint32_t nof_rnti; + float tx_amp; } srslte_enb_dl_t; @@ -114,6 +115,9 @@ SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q, uint32_t cfi); +SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, + float amp); + SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q, diff --git a/srslte/include/srslte/phch/cqi.h b/srslte/include/srslte/phch/cqi.h index 931f09566..9a7b243be 100644 --- a/srslte/include/srslte/phch/cqi.h +++ b/srslte/include/srslte/phch/cqi.h @@ -40,7 +40,7 @@ #include "srslte/config.h" #include "srslte/common/phy_common.h" -#define SRSLTE_CQI_MAX_BITS 20 +#define SRSLTE_CQI_MAX_BITS 64 typedef struct { bool configured; diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index 7d42145e5..bbe122c96 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -37,7 +37,7 @@ #define CURRENT_SLOTLEN_RE SRSLTE_SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp) #define CURRENT_SFLEN_RE SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp) -#define SRSLTE_ENB_RF_AMP 0.5 +#define SRSLTE_ENB_RF_AMP 0.1 int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti) { @@ -53,6 +53,7 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti q->cell = cell; q->cfi = 3; q->nof_rnti = nof_rnti; + q->tx_amp = SRSLTE_ENB_RF_AMP; if (srslte_ofdm_tx_init(&q->ifft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -146,6 +147,11 @@ void srslte_enb_dl_free(srslte_enb_dl_t *q) } } +void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, float amp) +{ + q->tx_amp = amp; +} + void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q, uint32_t cfi) { q->cfi = cfi; @@ -214,7 +220,7 @@ void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, cf_t *signal_buffer) // TODO: PAPR control float norm_factor = (float) sqrt(q->cell.nof_prb)/15; - srslte_vec_sc_prod_cfc(signal_buffer, SRSLTE_ENB_RF_AMP*norm_factor, signal_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + srslte_vec_sc_prod_cfc(signal_buffer, q->tx_amp*norm_factor, signal_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } int srslte_enb_dl_cfg_rnti(srslte_enb_dl_t *q, uint32_t idx, uint16_t rnti) From 015b0e4eb176d5858efca44941d9da211dec8e53 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 19 Nov 2016 14:24:02 +0100 Subject: [PATCH 069/111] remove printf --- srslte/lib/phch/uci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srslte/lib/phch/uci.c b/srslte/lib/phch/uci.c index dd0633768..10a4a99c1 100644 --- a/srslte/lib/phch/uci.c +++ b/srslte/lib/phch/uci.c @@ -314,8 +314,7 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q, } ret = srslte_crc_checksum(&q->crc, q->tmp_cqi, nof_bits + 8); - printf("ret=%d, nof_bits=%d\n", ret, nof_bits); - if (ret == 0) { + if (ret == 0) { memcpy(data, q->tmp_cqi, nof_bits*sizeof(uint8_t)); ret = 1; } else { From 62b63462c9556109a8b8396f777501244fa59f3e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 20 Nov 2016 17:36:21 +0100 Subject: [PATCH 070/111] Simplified API for PDSCH and PUSCH. Dynamically handle multiple RNTIs --- srslte/examples/pdsch_enodeb.c | 2 +- srslte/include/srslte/enb/enb_dl.h | 23 +- srslte/include/srslte/enb/enb_ul.h | 35 +-- srslte/include/srslte/phch/pdsch.h | 50 +--- srslte/include/srslte/phch/pusch.h | 73 +---- srslte/lib/enb/enb_dl.c | 37 +-- srslte/lib/enb/enb_ul.c | 156 ++++++----- srslte/lib/phch/pdsch.c | 217 ++++----------- srslte/lib/phch/pusch.c | 271 ++++++------------- srslte/lib/phch/test/pdsch_test.c | 6 +- srslte/lib/phch/test/pdsch_test_mex.c | 5 +- srslte/lib/phch/test/pusch_encode_test_mex.c | 7 +- srslte/lib/phch/test/pusch_test.c | 9 +- srslte/lib/phch/uci.c | 5 +- srslte/lib/ue/ue_dl.c | 4 +- srslte/lib/ue/ue_ul.c | 2 +- 16 files changed, 296 insertions(+), 606 deletions(-) diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index fdacde801..c68b4d125 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -624,7 +624,7 @@ int main(int argc, char **argv) { } /* Encode PDSCH */ - if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, sf_symbols)) { + if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, UE_CRNTI, sf_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); exit(-1); } diff --git a/srslte/include/srslte/enb/enb_dl.h b/srslte/include/srslte/enb/enb_dl.h index eca63d6d3..560441c70 100644 --- a/srslte/include/srslte/enb/enb_dl.h +++ b/srslte/include/srslte/enb/enb_dl.h @@ -87,13 +87,12 @@ typedef struct SRSLTE_API { float sss_signal0[SRSLTE_SSS_LEN]; float sss_signal5[SRSLTE_SSS_LEN]; - uint32_t nof_rnti; float tx_amp; } srslte_enb_dl_t; typedef struct { - int rnti_idx; + uint16_t rnti; srslte_ra_dl_dci_t grant; srslte_dci_location_t location; srslte_softbuffer_tx_t *softbuffer; @@ -101,14 +100,15 @@ typedef struct { } srslte_enb_dl_pdsch_t; typedef struct { + uint16_t rnti; uint8_t ack; - int rnti_idx; + uint32_t n_prb_lowest; + uint32_t n_dmrs; } srslte_enb_dl_phich_t; /* This function shall be called just after the initial synchronization */ SRSLTE_API int srslte_enb_dl_init(srslte_enb_dl_t *q, - srslte_cell_t cell, - uint32_t nof_rntis); + srslte_cell_t cell); SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q); @@ -144,17 +144,16 @@ SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, cf_t *signal_buffer); -SRSLTE_API int srslte_enb_dl_cfg_rnti(srslte_enb_dl_t *q, - uint32_t idx, +SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti); -SRSLTE_API int srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q, - uint32_t idx); +SRSLTE_API void srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q, + uint16_t rnti); SRSLTE_API int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer, - uint32_t rnti_idx, + uint16_t rnti, uint32_t rv_idx, uint32_t sf_idx, uint8_t *data); @@ -163,13 +162,13 @@ SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, srslte_dci_format_t format, srslte_dci_location_t location, - uint32_t rnti_idx, + uint16_t rnti, uint32_t sf_idx); SRSLTE_API int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, srslte_ra_ul_dci_t *grant, srslte_dci_location_t location, - uint32_t rnti_idx, + uint16_t rnti, uint32_t sf_idx); diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index 60eb0e50f..9a05436ba 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -58,9 +58,16 @@ typedef struct { uint32_t n_dmrs; } srslte_enb_ul_phich_info_t; +typedef struct { + bool uci_cfg_en; + bool srs_cfg_en; + srslte_uci_cfg_t uci_cfg; + srslte_refsignal_srs_cfg_t srs_cfg; + srslte_pucch_sched_t pucch_sched; +} srslte_enb_ul_user_t; + typedef struct SRSLTE_API { srslte_cell_t cell; - uint32_t nof_rnti; cf_t *sf_symbols; cf_t *ce; @@ -77,16 +84,12 @@ typedef struct SRSLTE_API { srslte_pusch_hopping_cfg_t hopping_cfg; // Configuration for each user - bool *uci_cfg_en; - bool *srs_cfg_en; - srslte_uci_cfg_t *uci_cfg; - srslte_refsignal_srs_cfg_t *srs_cfg; - srslte_pucch_sched_t *pucch_sched; + srslte_enb_ul_user_t **users; } srslte_enb_ul_t; typedef struct { - int rnti_idx; + uint16_t rnti; srslte_ra_ul_dci_t grant; srslte_dci_location_t location; uint32_t rv_idx; @@ -103,29 +106,27 @@ SRSLTE_API int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_prach_cfg_t* prach_cfg, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, srslte_pusch_hopping_cfg_t *hopping_cfg, - srslte_pucch_cfg_t *pucch_cfg, - uint32_t nof_rntis); + srslte_pucch_cfg_t *pucch_cfg); SRSLTE_API void srslte_enb_ul_free(srslte_enb_ul_t *q); -SRSLTE_API int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, - uint32_t idx, +SRSLTE_API int srslte_enb_ul_add_rnti(srslte_enb_ul_t *q, uint16_t rnti); -SRSLTE_API int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, +SRSLTE_API void srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, + uint16_t rnti); + +SRSLTE_API int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint16_t rnti, srslte_uci_cfg_t *uci_cfg, srslte_pucch_sched_t *pucch_sched, srslte_refsignal_srs_cfg_t *srs_cfg); -SRSLTE_API int srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, - uint32_t idx); - SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer); SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, - uint32_t rnti_idx, + uint16_t rnti, uint32_t pdcch_n_cce, uint32_t sf_rx, srslte_uci_data_t *uci_data); @@ -133,7 +134,7 @@ SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer, - uint32_t rnti_idx, + uint16_t rnti, uint32_t rv_idx, uint32_t current_tx_nb, uint8_t *data, diff --git a/srslte/include/srslte/phch/pdsch.h b/srslte/include/srslte/phch/pdsch.h index 3e6580763..305402de5 100644 --- a/srslte/include/srslte/phch/pdsch.h +++ b/srslte/include/srslte/phch/pdsch.h @@ -47,13 +47,15 @@ #include "srslte/phch/sch.h" #include "srslte/phch/pdsch_cfg.h" +typedef struct { + srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; +} srslte_pdsch_user_t; + /* PDSCH object */ typedef struct SRSLTE_API { srslte_cell_t cell; uint32_t max_re; - bool rnti_is_set; - uint16_t rnti; /* buffers */ // void buffers are shared for tx and rx @@ -66,12 +68,8 @@ typedef struct SRSLTE_API { /* tx & rx objects */ srslte_modem_table_t mod[4]; - srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; - // This is to generate the scrambling seq for multiple CRNTIs - uint32_t nof_crnti; - srslte_sequence_t *seq_multi[SRSLTE_NSUBFRAMES_X_FRAME]; - uint16_t *rnti_multi; + srslte_pdsch_user_t **users; srslte_sch_t dl_sch; @@ -85,21 +83,12 @@ SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q); SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti); -SRSLTE_API int srslte_pdsch_init_rnti_multi(srslte_pdsch_t *q, - uint32_t nof_rntis); - -SRSLTE_API int srslte_pdsch_set_rnti_multi(srslte_pdsch_t *q, - uint32_t idx, - uint16_t rnti); - -SRSLTE_API uint16_t srslte_pdsch_get_rnti_multi(srslte_pdsch_t *q, - uint32_t idx); +SRSLTE_API void srslte_pdsch_free_rnti(srslte_pdsch_t *q, + uint16_t rnti); SRSLTE_API float srslte_pdsch_coderate(uint32_t tbs, uint32_t nof_re); -SRSLTE_API void print_pdsch_coderate(); - SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, @@ -111,39 +100,18 @@ SRSLTE_API int srslte_pdsch_encode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, + uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS]); -SRSLTE_API int srslte_pdsch_encode_rnti_idx(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, - uint32_t rnti_idx, - cf_t *sf_symbols[SRSLTE_MAX_PORTS]); - -SRSLTE_API int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, - uint16_t rnti, - cf_t *sf_symbols[SRSLTE_MAX_PORTS]); - SRSLTE_API int srslte_pdsch_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, + uint16_t rnti, uint8_t *data); -SRSLTE_API int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, - cf_t *ce[SRSLTE_MAX_PORTS], - float noise_estimate, - uint16_t rnti, - uint8_t *data); - SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q); SRSLTE_API uint32_t srslte_pdsch_last_noi(srslte_pdsch_t *q); diff --git a/srslte/include/srslte/phch/pusch.h b/srslte/include/srslte/phch/pusch.h index d8a5f3f53..e75b83c63 100644 --- a/srslte/include/srslte/phch/pusch.h +++ b/srslte/include/srslte/phch/pusch.h @@ -51,9 +51,6 @@ #define SRSLTE_PUSCH_MAX_TDEC_ITERS 5 - - - typedef struct { enum { SRSLTE_PUSCH_HOP_MODE_INTER_SF = 1, @@ -63,13 +60,15 @@ typedef struct { uint32_t n_sb; } srslte_pusch_hopping_cfg_t; +typedef struct { + srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; +} srslte_pusch_user_t; + /* PUSCH object */ typedef struct SRSLTE_API { srslte_cell_t cell; uint32_t max_re; - bool rnti_is_set; - uint16_t rnti; srslte_dft_precoding_t dft_precoding; @@ -84,13 +83,10 @@ typedef struct SRSLTE_API { /* tx & rx objects */ srslte_modem_table_t mod[4]; - srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; srslte_sequence_t seq_type2_fo; // This is to generate the scrambling seq for multiple CRNTIs - uint32_t nof_crnti; - srslte_sequence_t *seq_multi[SRSLTE_NSUBFRAMES_X_FRAME]; - uint16_t *rnti_multi; + srslte_pusch_user_t **users; srslte_sch_t ul_sch; bool shortened; @@ -116,44 +112,16 @@ SRSLTE_API int srslte_pusch_cfg(srslte_pusch_t *q, SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti); -SRSLTE_API int srslte_pusch_init_rnti_multi(srslte_pusch_t *q, - uint32_t nof_rntis); - -SRSLTE_API int srslte_pusch_set_rnti_multi(srslte_pusch_t *q, - uint32_t idx, - uint16_t rnti); - -SRSLTE_API uint16_t srslte_pusch_get_rnti_multi(srslte_pusch_t *q, - uint32_t idx); - +SRSLTE_API void srslte_pusch_clear_rnti(srslte_pusch_t *q, + uint16_t rnti); SRSLTE_API int srslte_pusch_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, - cf_t *sf_symbols); - -SRSLTE_API int srslte_pusch_encode_rnti(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, - srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, - uint16_t rnti, - cf_t *sf_symbols); - -SRSLTE_API int srslte_pusch_uci_encode(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, - srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, srslte_uci_data_t uci_data, - cf_t *sf_symbols); - -SRSLTE_API int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, - srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, - srslte_uci_data_t uci_data, - uint16_t rnti, - cf_t *sf_symbols); + uint16_t rnti, + cf_t *sf_symbols); SRSLTE_API int srslte_pusch_decode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, @@ -161,26 +129,9 @@ SRSLTE_API int srslte_pusch_decode(srslte_pusch_t *q, cf_t *sf_symbols, cf_t *ce, float noise_estimate, - uint8_t *data); - -SRSLTE_API int srslte_pusch_uci_decode(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, - srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, - cf_t *ce, - float noise_estimate, - uint8_t *data, - srslte_uci_data_t *uci_data); - -SRSLTE_API int srslte_pusch_uci_decode_rnti_idx(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, - srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, - cf_t *ce, - float noise_estimate, - uint32_t rnti_idx, - uint8_t *data, - srslte_uci_data_t *uci_data); + uint16_t rnti, + uint8_t *data, + srslte_uci_data_t *uci_data); SRSLTE_API float srslte_pusch_average_noi(srslte_pusch_t *q); diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index bbe122c96..82fc8491e 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -39,7 +39,7 @@ #define SRSLTE_ENB_RF_AMP 0.1 -int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti) +int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -52,7 +52,6 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti q->cell = cell; q->cfi = 3; - q->nof_rnti = nof_rnti; q->tx_amp = SRSLTE_ENB_RF_AMP; if (srslte_ofdm_tx_init(&q->ifft, q->cell.cp, q->cell.nof_prb)) { @@ -89,11 +88,6 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti goto clean_exit; } - if (srslte_pdsch_init_rnti_multi(&q->pdsch, nof_rnti)) { - fprintf(stderr, "Error initiating multiple RNTIs in PDSCH\n"); - goto clean_exit; - } - if (srslte_refsignal_cs_init(&q->csr_signal, q->cell)) { fprintf(stderr, "Error initializing CSR signal (%d)\n",ret); goto clean_exit; @@ -223,23 +217,21 @@ void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, cf_t *signal_buffer) srslte_vec_sc_prod_cfc(signal_buffer, q->tx_amp*norm_factor, signal_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } -int srslte_enb_dl_cfg_rnti(srslte_enb_dl_t *q, uint32_t idx, uint16_t rnti) +int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti) { - return srslte_pdsch_set_rnti_multi(&q->pdsch, idx, rnti); + return srslte_pdsch_set_rnti(&q->pdsch, rnti); } -int srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q, uint32_t idx) +void srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q, uint16_t rnti) { - return srslte_pdsch_set_rnti_multi(&q->pdsch, idx, 0); + srslte_pdsch_free_rnti(&q->pdsch, rnti); } int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, srslte_dci_format_t format, srslte_dci_location_t location, - uint32_t rnti_idx, uint32_t sf_idx) + uint16_t rnti, uint32_t sf_idx) { srslte_dci_msg_t dci_msg; - - uint16_t rnti = srslte_pdsch_get_rnti_multi(&q->pdsch, rnti_idx); bool rnti_is_user = true; if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || (rnti >= SRSLTE_RARNTI_START && rnti <= SRSLTE_RARNTI_END)) { @@ -251,23 +243,16 @@ int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, fprintf(stderr, "Error encoding DCI message\n"); return SRSLTE_ERROR; } -/* printf("format: %s, sf_idx=%d, rnti=%d, location=%d,%d, cfi=%d\n", - srslte_dci_format_string(format), sf_idx, rnti, location.L, location.ncce, q->cfi); - srslte_ra_pdsch_fprint(stdout, grant, q->cell.nof_prb); - srslte_vec_fprint_hex(stdout, dci_msg.data, dci_msg.nof_bits); -*/ return SRSLTE_SUCCESS; } int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, srslte_ra_ul_dci_t *grant, srslte_dci_location_t location, - uint32_t rnti_idx, uint32_t sf_idx) + uint16_t rnti, uint32_t sf_idx) { srslte_dci_msg_t dci_msg; - uint16_t rnti = srslte_pdsch_get_rnti_multi(&q->pdsch, rnti_idx); - srslte_dci_msg_pack_pusch(grant, &dci_msg, q->cell.nof_prb); if (srslte_pdcch_encode(&q->pdcch, &dci_msg, location, rnti, q->sf_symbols, sf_idx, q->cfi)) { fprintf(stderr, "Error encoding DCI message\n"); @@ -278,11 +263,9 @@ int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, srslte_ra_ul_dci_t *grant, } int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer, - uint32_t rnti_idx, uint32_t rv_idx, uint32_t sf_idx, + uint16_t rnti, uint32_t rv_idx, uint32_t sf_idx, uint8_t *data) -{ - //srslte_ra_dl_grant_fprint(stdout, grant); - +{ /* Configure pdsch_cfg parameters */ if (srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, q->cfi, sf_idx, rv_idx)) { fprintf(stderr, "Error configuring PDSCH\n"); @@ -290,7 +273,7 @@ int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srs } /* Encode PDSCH */ - if (srslte_pdsch_encode_rnti_idx(&q->pdsch, &q->pdsch_cfg, softbuffer, data, rnti_idx, q->sf_symbols)) { + if (srslte_pdsch_encode(&q->pdsch, &q->pdsch_cfg, softbuffer, data, rnti, q->sf_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); return SRSLTE_ERROR; } diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index cf6f63c99..f966cd508 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -43,8 +43,7 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, srslte_prach_cfg_t *prach_cfg, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, srslte_pusch_hopping_cfg_t *hopping_cfg, - srslte_pucch_cfg_t *pucch_cfg, - uint32_t nof_rnti) + srslte_pucch_cfg_t *pucch_cfg) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -56,18 +55,16 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, bzero(q, sizeof(srslte_enb_ul_t)); q->cell = cell; - q->nof_rnti = nof_rnti; if (hopping_cfg) { memcpy(&q->hopping_cfg, hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t)); } - q->uci_cfg_en = calloc(sizeof(bool), nof_rnti); - q->srs_cfg_en = calloc(sizeof(bool), nof_rnti); - - q->uci_cfg = calloc(sizeof(srslte_uci_cfg_t), nof_rnti); - q->srs_cfg = calloc(sizeof(srslte_refsignal_srs_cfg_t), nof_rnti); - q->pucch_sched = calloc(sizeof(srslte_pucch_sched_t), nof_rnti); + q->users = calloc(sizeof(srslte_enb_ul_user_t*), SRSLTE_SIRNTI); + if (!q->users) { + perror("malloc"); + goto clean_exit; + } if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -86,18 +83,14 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, goto clean_exit; } - if (srslte_pusch_init_rnti_multi(&q->pusch, nof_rnti)) { - fprintf(stderr, "Error initiating multiple RNTIs in PUSCH\n"); - goto clean_exit; - } - - if (srslte_prach_init_cfg(&q->prach, prach_cfg, q->cell.nof_prb)) { - fprintf(stderr, "Error initiating PRACH\n"); - goto clean_exit; + if (prach_cfg) { + if (srslte_prach_init_cfg(&q->prach, prach_cfg, q->cell.nof_prb)) { + fprintf(stderr, "Error initiating PRACH\n"); + goto clean_exit; + } + srslte_prach_set_detect_factor(&q->prach, 60); } - srslte_prach_set_detect_factor(&q->prach, 60); - srslte_pucch_set_threshold(&q->pucch, 0.5, 0.5); if (srslte_chest_ul_init(&q->chest, cell)) { @@ -141,20 +134,13 @@ void srslte_enb_ul_free(srslte_enb_ul_t *q) { if (q) { - if (q->uci_cfg) { - free(q->uci_cfg); - } - if (q->uci_cfg_en) { - free(q->uci_cfg_en); - } - if (q->srs_cfg) { - free(q->srs_cfg); - } - if (q->srs_cfg_en) { - free(q->srs_cfg_en); - } - if (q->pucch_sched) { - free(q->pucch_sched); + if (q->users) { + for (int i=0;iusers[i]) { + free(q->users[i]); + } + } + free(q->users); } srslte_prach_free(&q->prach); @@ -172,50 +158,60 @@ void srslte_enb_ul_free(srslte_enb_ul_t *q) } } -int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, uint32_t idx, uint16_t rnti) +int srslte_enb_ul_add_rnti(srslte_enb_ul_t *q, uint16_t rnti) { - return srslte_pusch_set_rnti_multi(&q->pusch, idx, rnti); + if (!q->users[rnti]) { + q->users[rnti] = malloc(sizeof(srslte_enb_ul_user_t)); + return srslte_pusch_set_rnti(&q->pusch, rnti); + } else { + fprintf(stderr, "Error adding rnti=0x%x, already exists\n", rnti); + return -1; + } } -int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, +void srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, uint16_t rnti) +{ + if (q->users[rnti]) { + free(q->users[rnti]); + q->users[rnti] = NULL; + srslte_pusch_clear_rnti(&q->pusch, rnti); + } +} + +int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint16_t rnti, srslte_uci_cfg_t *uci_cfg, srslte_pucch_sched_t *pucch_sched, srslte_refsignal_srs_cfg_t *srs_cfg) { - if (idx < q->nof_rnti) { + if (q->users[rnti]) { if (uci_cfg) { - memcpy(&q->uci_cfg[idx], uci_cfg, sizeof(srslte_uci_cfg_t)); - q->uci_cfg_en[idx] = true; + memcpy(&q->users[rnti]->uci_cfg, uci_cfg, sizeof(srslte_uci_cfg_t)); + q->users[rnti]->uci_cfg_en = true; } else { - q->uci_cfg_en[idx] = false; + q->users[rnti]->uci_cfg_en = false; } if (pucch_sched) { - memcpy(&q->pucch_sched[idx], pucch_sched, sizeof(srslte_pucch_sched_t)); + memcpy(&q->users[rnti]->pucch_sched, pucch_sched, sizeof(srslte_pucch_sched_t)); } if (srs_cfg) { - memcpy(&q->srs_cfg[idx], srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); - q->srs_cfg_en[idx] = true; + memcpy(&q->users[rnti]->srs_cfg, srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); + q->users[rnti]->srs_cfg_en = true; } else { - q->srs_cfg_en[idx] = false; + q->users[rnti]->srs_cfg_en = false; } return SRSLTE_SUCCESS; } else { - fprintf(stderr, "Error configuring UE: Invalid idx=%d, max users=%d\n", idx, q->nof_rnti); + fprintf(stderr, "Error configuring UE: rnti=0x%x not found\n", rnti); return SRSLTE_ERROR; } } - -int srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, uint32_t idx) -{ - return srslte_pusch_set_rnti_multi(&q->pusch, idx, 0); -} void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) { srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); } -int get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, +int get_pucch(srslte_enb_ul_t *q, uint16_t rnti, uint32_t pdcch_n_cce, uint32_t sf_rx, srslte_uci_data_t *uci_data, uint8_t bits[SRSLTE_PUCCH_MAX_BITS]) { @@ -223,7 +219,7 @@ int get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp); - uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->pucch_sched[rnti_idx]); + uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->users[rnti]->pucch_sched); if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { fprintf(stderr,"Error estimating PUCCH DMRS\n"); @@ -239,21 +235,21 @@ int get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, return ret_val; } -int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, +int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti, uint32_t pdcch_n_cce, uint32_t sf_rx, srslte_uci_data_t *uci_data) { uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; - if (rnti_idx < q->nof_rnti) { + if (q->users[rnti]) { - int ret_val = get_pucch(q, rnti_idx, pdcch_n_cce, sf_rx, uci_data, bits); + int ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, bits); // If we are looking for SR and ACK at the same time and ret=0, means there is no SR. // try again to decode ACK only if (uci_data->scheduling_request && uci_data->uci_ack_len && ret_val != 1) { uci_data->scheduling_request = false; - ret_val = get_pucch(q, rnti_idx, pdcch_n_cce, sf_rx, uci_data, bits); + ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, bits); } // update schedulign request @@ -271,38 +267,50 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, } return SRSLTE_SUCCESS; } else { - fprintf(stderr, "Invalid rnti_idx=%d\n", rnti_idx); + fprintf(stderr, "Error getting PUCCH: rnti=0x%x not found\n", rnti); return SRSLTE_ERROR; } } int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer, - uint32_t rnti_idx, uint32_t rv_idx, uint32_t current_tx_nb, + uint16_t rnti, uint32_t rv_idx, uint32_t current_tx_nb, uint8_t *data, srslte_uci_data_t *uci_data, uint32_t tti) { - - if (srslte_pusch_cfg(&q->pusch, - &q->pusch_cfg, - grant, - q->uci_cfg_en[rnti_idx]?&q->uci_cfg[rnti_idx]:NULL, - &q->hopping_cfg, - q->srs_cfg_en[rnti_idx]?&q->srs_cfg[rnti_idx]:NULL, - tti, rv_idx, current_tx_nb)) { - fprintf(stderr, "Error configuring PDSCH\n"); - return SRSLTE_ERROR; + if (q->users[rnti]) { + if (srslte_pusch_cfg(&q->pusch, + &q->pusch_cfg, + grant, + q->users[rnti]->uci_cfg_en?&q->users[rnti]->uci_cfg:NULL, + &q->hopping_cfg, + q->users[rnti]->srs_cfg_en?&q->users[rnti]->srs_cfg:NULL, + tti, rv_idx, current_tx_nb)) { + fprintf(stderr, "Error configuring PDSCH\n"); + return SRSLTE_ERROR; + } + } else { + if (srslte_pusch_cfg(&q->pusch, + &q->pusch_cfg, + grant, + NULL, + &q->hopping_cfg, + NULL, + tti, rv_idx, current_tx_nb)) { + fprintf(stderr, "Error configuring PDSCH\n"); + return SRSLTE_ERROR; + } } - + uint32_t cyclic_shift_for_dmrs = 0; srslte_chest_ul_estimate(&q->chest, q->sf_symbols, q->ce, grant->L_prb, tti%10, cyclic_shift_for_dmrs, grant->n_prb); float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); - return srslte_pusch_uci_decode_rnti_idx(&q->pusch, &q->pusch_cfg, - softbuffer, q->sf_symbols, - q->ce, noise_power, - rnti_idx, data, - uci_data); + return srslte_pusch_decode(&q->pusch, &q->pusch_cfg, + softbuffer, q->sf_symbols, + q->ce, noise_power, + rnti, data, + uci_data); } diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index b6184f0a6..b4ae7621f 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -216,7 +216,6 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { q->cell = cell; q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); - q->nof_crnti = 0; INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports, q->cell.nof_prb, q->max_re); @@ -230,8 +229,6 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { srslte_sch_init(&q->dl_sch); - q->rnti_is_set = false; - // Allocate int16_t for reception (LLRs) q->e = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM)); if (!q->e) { @@ -257,7 +254,13 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { goto clean; } } - + + q->users = calloc(sizeof(srslte_pdsch_user_t*), 1+SRSLTE_SIRNTI); + if (!q->users) { + perror("malloc"); + goto clean; + } + ret = SRSLTE_SUCCESS; } clean: @@ -288,23 +291,14 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { } } - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - srslte_sequence_free(&q->seq[i]); - } - - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - for (int n=0;nnof_crnti;n++) { - srslte_sequence_free(&q->seq_multi[i][n]); - } - if (q->seq_multi[i]) { - free(q->seq_multi[i]); - } - } - - if (q->rnti_multi) { - free(q->rnti_multi); + if (q->users) { + for (uint16_t u=0;uusers[u]) { + srslte_pdsch_free_rnti(q, u); + } + } + free(q->users); } - for (i = 0; i < 4; i++) { srslte_modem_table_free(&q->mod[i]); } @@ -343,102 +337,38 @@ int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_g * to execute, so shall be called once the final C-RNTI has been allocated for the session. */ int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) { - uint32_t i; - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pdsch(&q->seq[i], rnti, 0, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - return SRSLTE_ERROR; - } - } - q->rnti_is_set = true; - q->rnti = rnti; - return SRSLTE_SUCCESS; -} - -/* Initializes the memory to support pre-calculation of multiple scrambling sequences */ -int srslte_pdsch_init_rnti_multi(srslte_pdsch_t *q, uint32_t nof_rntis) -{ - for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - q->seq_multi[i] = malloc(sizeof(srslte_sequence_t)*nof_rntis); - if (!q->seq_multi[i]) { - perror("malloc"); - return SRSLTE_ERROR; - } - } - - q->rnti_multi = srslte_vec_malloc(sizeof(uint16_t)*nof_rntis); - if (!q->rnti_multi) { - perror("malloc"); - return SRSLTE_ERROR; - } - bzero(q->rnti_multi, sizeof(uint16_t)*nof_rntis); - - q->nof_crnti = nof_rntis; - - return SRSLTE_SUCCESS; -} - -int srslte_pdsch_set_rnti_multi(srslte_pdsch_t *q, uint32_t idx, uint16_t rnti) -{ - if (idx < q->nof_crnti) { - if (q->rnti_multi[idx]) { - for (uint32_t i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - srslte_sequence_free(&q->seq_multi[i][idx]); - } - q->rnti_multi[idx] = 0; - } - if (rnti) { - q->rnti_multi[idx] = rnti; - q->rnti_is_set = true; - for (uint32_t i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pdsch(&q->seq_multi[i][idx], rnti, 0, 2 * i, q->cell.id, + uint32_t i; + if (!q->users[rnti]) { + q->users[rnti] = calloc(1, sizeof(srslte_pdsch_user_t)); + if (q->users[rnti]) { + for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + if (srslte_sequence_pdsch(&q->users[rnti]->seq[i], rnti, 0, 2 * i, q->cell.id, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { return SRSLTE_ERROR; } } } - return SRSLTE_SUCCESS; - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } -} - -uint16_t srslte_pdsch_get_rnti_multi(srslte_pdsch_t *q, uint32_t idx) -{ - if (idx < q->nof_crnti) { - return q->rnti_multi[idx]; - } else { - return SRSLTE_ERROR_INVALID_INPUTS; } + return SRSLTE_SUCCESS; } -int srslte_pdsch_decode(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint8_t *data) +void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) { - if (q != NULL && - sf_symbols != NULL && - data != NULL && - cfg != NULL) - { - if (q->rnti_is_set) { - return srslte_pdsch_decode_rnti(q, cfg, softbuffer, sf_symbols, ce, noise_estimate, q->rnti, data); - } else { - fprintf(stderr, "Must call srslte_pdsch_set_rnti() before calling srslte_pdsch_decode()\n"); - return SRSLTE_ERROR; + if (q->users[rnti]) { + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + srslte_sequence_free(&q->users[rnti]->seq[i]); } - } else { - return SRSLTE_ERROR_INVALID_INPUTS; + free(q->users[rnti]); + q->users[rnti] = NULL; } } /** Decodes the PDSCH from the received symbols */ -int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint16_t rnti, uint8_t *data) +int srslte_pdsch_decode(srslte_pdsch_t *q, + srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, + cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, + uint16_t rnti, uint8_t *data) { /* Set pointers for layermapping & precoding */ @@ -506,16 +436,8 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, */ srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re); - /* - printf("WARNING REMOVE ME!\n"); - int16_t *e=q->e; - for (int i=0;inbits.nof_bits;i++) { - e[i] = e[i]>0?10:-10; - } - */ - /* descramble */ - if (rnti != q->rnti) { + if (!q->users[rnti]) { srslte_sequence_t seq; if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { return SRSLTE_ERROR; @@ -523,7 +445,7 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, srslte_scrambling_s_offset(&seq, q->e, 0, cfg->nbits.nof_bits); srslte_sequence_free(&seq); } else { - srslte_scrambling_s_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->nbits.nof_bits); + srslte_scrambling_s_offset(&q->users[rnti]->seq[cfg->sf_idx], q->e, 0, cfg->nbits.nof_bits); } if (SRSLTE_VERBOSE_ISDEBUG()) { @@ -539,27 +461,8 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, } int srslte_pdsch_encode(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) -{ - if (q != NULL && - data != NULL && - cfg != NULL) - { - if (q->rnti_is_set) { - return srslte_pdsch_encode_rnti(q, cfg, softbuffer, data, q->rnti, sf_symbols); - } else { - fprintf(stderr, "Must call srslte_pdsch_set_rnti() to set the encoder/decoder RNTI\n"); - return SRSLTE_ERROR; - } - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } -} - -int srslte_pdsch_encode_seq(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, srslte_sequence_t *seq, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) + srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, + uint8_t *data, uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) { int i; @@ -603,8 +506,18 @@ int srslte_pdsch_encode_seq(srslte_pdsch_t *q, return SRSLTE_ERROR; } - srslte_scrambling_bytes(seq, (uint8_t*) q->e, cfg->nbits.nof_bits); - + /* scramble */ + if (!q->users[rnti]) { + srslte_sequence_t seq; + if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { + return SRSLTE_ERROR; + } + srslte_scrambling_bytes(&q->users[rnti]->seq[cfg->sf_idx], (uint8_t*) q->e, cfg->nbits.nof_bits); + srslte_sequence_free(&seq); + } else { + srslte_scrambling_bytes(&q->users[rnti]->seq[cfg->sf_idx], (uint8_t*) q->e, cfg->nbits.nof_bits); + } + srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits); /* TODO: only diversity supported */ @@ -626,42 +539,6 @@ int srslte_pdsch_encode_seq(srslte_pdsch_t *q, return ret; } -int srslte_pdsch_encode_rnti_idx(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, uint32_t rnti_idx, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) -{ - if (rnti_idx < q->nof_crnti) { - if (q->rnti_multi[rnti_idx]) { - return srslte_pdsch_encode_seq(q, cfg, softbuffer, data, &q->seq_multi[cfg->sf_idx][rnti_idx], sf_symbols); - } else { - fprintf(stderr, "Error RNTI idx %d not set\n", rnti_idx); - return SRSLTE_ERROR; - } - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } -} - -/** Converts the PDSCH data bits to symbols mapped to the slot ready for transmission - */ -int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) -{ - if (rnti != q->rnti) { - srslte_sequence_t seq; - if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { - return SRSLTE_ERROR; - } - int r = srslte_pdsch_encode_seq(q, cfg, softbuffer, data, &seq, sf_symbols); - srslte_sequence_free(&seq); - return r; - } else { - return srslte_pdsch_encode_seq(q, cfg, softbuffer, data, &q->seq[cfg->sf_idx], sf_symbols); - } -} - - float srslte_pdsch_average_noi(srslte_pdsch_t *q) { return q->dl_sch.average_nof_iterations; diff --git a/srslte/lib/phch/pusch.c b/srslte/lib/phch/pusch.c index 8f73e71da..7c4484872 100644 --- a/srslte/lib/phch/pusch.c +++ b/srslte/lib/phch/pusch.c @@ -209,6 +209,12 @@ int srslte_pusch_init(srslte_pusch_t *q, srslte_cell_t cell) { srslte_modem_table_bytes(&q->mod[i]); } + q->users = calloc(sizeof(srslte_pusch_user_t*), 1+SRSLTE_SIRNTI); + if (!q->users) { + perror("malloc"); + goto clean; + } + /* Precompute sequence for type2 frequency hopping */ if (srslte_sequence_LTE_pr(&q->seq_type2_fo, 210, q->cell.id)) { fprintf(stderr, "Error initiating type2 frequency hopping sequence\n"); @@ -222,8 +228,6 @@ int srslte_pusch_init(srslte_pusch_t *q, srslte_cell_t cell) { goto clean; } - q->rnti_is_set = false; - // Allocate int16 for reception (LLRs). Buffer casted to uint8_t for transmission q->q = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM)); if (!q->q) { @@ -279,10 +283,12 @@ void srslte_pusch_free(srslte_pusch_t *q) { srslte_dft_precoding_free(&q->dft_precoding); - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - srslte_sequence_free(&q->seq[i]); + if (q->users) { + for (int rnti=0;rntiusers); } - srslte_sequence_free(&q->seq_type2_fo); for (i = 0; i < 4; i++) { @@ -382,118 +388,39 @@ int srslte_pusch_cfg(srslte_pusch_t *q, /* Precalculate the PUSCH scramble sequences for a given RNTI. This function takes a while * to execute, so shall be called once the final C-RNTI has been allocated for the session. - * For the connection procedure, use srslte_pusch_encode_rnti() or srslte_pusch_decode_rnti() functions */ + * For the connection procedure, use srslte_pusch_encode() functions */ int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti) { uint32_t i; - - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pusch(&q->seq[i], rnti, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - return SRSLTE_ERROR; - } - } - q->rnti_is_set = true; - q->rnti = rnti; - return SRSLTE_SUCCESS; -} - - -/* Initializes the memory to support pre-calculation of multiple scrambling sequences */ -int srslte_pusch_init_rnti_multi(srslte_pusch_t *q, uint32_t nof_rntis) -{ - for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - q->seq_multi[i] = malloc(sizeof(srslte_sequence_t)*nof_rntis); - if (!q->seq_multi[i]) { - perror("malloc"); - return SRSLTE_ERROR; - } - } - q->rnti_multi = srslte_vec_malloc(sizeof(uint16_t)*nof_rntis); - if (!q->rnti_multi) { - perror("malloc"); - return SRSLTE_ERROR; - } - bzero(q->rnti_multi, sizeof(uint16_t)*nof_rntis); - - q->nof_crnti = nof_rntis; - - return SRSLTE_SUCCESS; -} - -int srslte_pusch_set_rnti_multi(srslte_pusch_t *q, uint32_t idx, uint16_t rnti) -{ - if (idx < q->nof_crnti) { - if (q->rnti_multi[idx]) { - for (uint32_t i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - srslte_sequence_free(&q->seq_multi[i][idx]); - } - q->rnti_multi[idx] = 0; - } - if (rnti) { - q->rnti_multi[idx] = rnti; - q->rnti_is_set = true; - for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pusch(&q->seq_multi[i][idx], rnti, 2 * i, q->cell.id, + if (!q->users[rnti]) { + q->users[rnti] = malloc(sizeof(srslte_pusch_user_t)); + if (q->users[rnti]) { + for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + if (srslte_sequence_pusch(&q->users[rnti]->seq[i], rnti, 2 * i, q->cell.id, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { return SRSLTE_ERROR; } - } + } } - return SRSLTE_SUCCESS; - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } -} - -uint16_t srslte_pusch_get_rnti_multi(srslte_pusch_t *q, uint32_t idx) -{ - if (idx < q->nof_crnti) { - return q->rnti_multi[idx]; - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } -} - -int srslte_pusch_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, uint16_t rnti, - cf_t *sf_symbols) -{ - srslte_uci_data_t uci_data; - bzero(&uci_data, sizeof(srslte_uci_data_t)); - return srslte_pusch_uci_encode_rnti(q, cfg, softbuffer, data, uci_data, rnti, sf_symbols); -} - -int srslte_pusch_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, cf_t *sf_symbols) -{ - if (q->rnti_is_set) { - srslte_uci_data_t uci_data; - bzero(&uci_data, sizeof(srslte_uci_data_t)); - return srslte_pusch_uci_encode_rnti(q, cfg, softbuffer, data, uci_data, q->rnti, sf_symbols); - } else { - fprintf(stderr, "Must call srslte_pusch_set_rnti() to set the encoder/decoder RNTI\n"); - return SRSLTE_ERROR; } + return SRSLTE_SUCCESS; } -int srslte_pusch_uci_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, srslte_uci_data_t uci_data, - cf_t *sf_symbols) -{ - if (q->rnti_is_set) { - return srslte_pusch_uci_encode_rnti(q, cfg, softbuffer, data, uci_data, q->rnti, sf_symbols); - } else { - fprintf(stderr, "Must call srslte_pusch_set_rnti() to set the encoder/decoder RNTI\n"); - return SRSLTE_ERROR; +void srslte_pusch_clear_rnti(srslte_pusch_t *q, uint16_t rnti) { + if (q->users[rnti]) { + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + srslte_sequence_free(&q->users[rnti]->seq[i]); + } + free(q->users[rnti]); + q->users[rnti] = NULL; } } /** Converts the PUSCH data bits to symbols mapped to the slot ready for transmission */ -int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, srslte_uci_data_t uci_data, uint16_t rnti, - cf_t *sf_symbols) +int srslte_pusch_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, + uint8_t *data, srslte_uci_data_t uci_data, uint16_t rnti, + cf_t *sf_symbols) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -517,7 +444,7 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs return SRSLTE_ERROR; } - if (rnti != q->rnti || !q->rnti_is_set) { + if (!q->users[rnti]) { srslte_sequence_t seq; if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { return SRSLTE_ERROR; @@ -525,7 +452,7 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs srslte_scrambling_bytes(&seq, (uint8_t*) q->q, cfg->nbits.nof_bits); srslte_sequence_free(&seq); } else { - srslte_scrambling_bytes(&q->seq[cfg->sf_idx], (uint8_t*) q->q, cfg->nbits.nof_bits); + srslte_scrambling_bytes(&q->users[rnti]->seq[cfg->sf_idx], (uint8_t*) q->q, cfg->nbits.nof_bits); } // Correct UCI placeholder/repetition bits @@ -560,23 +487,14 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs return ret; } + +/** Decodes the PUSCH from the received symbols + */ int srslte_pusch_decode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, cf_t *sf_symbols, - cf_t *ce, float noise_estimate, - uint8_t *data) -{ - srslte_uci_data_t uci_data; - bzero(&uci_data, sizeof(srslte_uci_data_t)); - return srslte_pusch_uci_decode(q, cfg, softbuffer, sf_symbols, ce, noise_estimate, data, &uci_data); -} - -int srslte_pusch_uci_decode_seq(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - srslte_sequence_t *seq, - cf_t *sf_symbols, - cf_t *ce, float noise_estimate, - uint8_t *data, srslte_uci_data_t *uci_data) + cf_t *ce, float noise_estimate, uint16_t rnti, + uint8_t *data, srslte_uci_data_t *uci_data) { uint32_t n; @@ -587,82 +505,63 @@ int srslte_pusch_uci_decode_seq(srslte_pusch_t *q, cfg != NULL) { - if (q->rnti_is_set) { - INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n", - cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, - cfg->nbits.nof_re, cfg->nbits.nof_symb, cfg->nbits.nof_bits, cfg->rv); - - /* extract symbols */ - n = pusch_get(q, &cfg->grant, sf_symbols, q->d); - if (n != cfg->nbits.nof_re) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); - return SRSLTE_ERROR; - } - - /* extract channel estimates */ - n = pusch_get(q, &cfg->grant, ce, q->ce); - if (n != cfg->nbits.nof_re) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); - return SRSLTE_ERROR; - } + INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n", + cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, + cfg->nbits.nof_re, cfg->nbits.nof_symb, cfg->nbits.nof_bits, cfg->rv); + + /* extract symbols */ + n = pusch_get(q, &cfg->grant, sf_symbols, q->d); + if (n != cfg->nbits.nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); + return SRSLTE_ERROR; + } + + /* extract channel estimates */ + n = pusch_get(q, &cfg->grant, ce, q->ce); + if (n != cfg->nbits.nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); + return SRSLTE_ERROR; + } - // Equalization - srslte_predecoding_single(q->d, q->ce, q->z, cfg->nbits.nof_re, noise_estimate); - - // DFT predecoding - srslte_dft_predecoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->nbits.nof_symb); - - // Soft demodulation - srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re); + // Equalization + srslte_predecoding_single(q->d, q->ce, q->z, cfg->nbits.nof_re, noise_estimate); + + // DFT predecoding + srslte_dft_predecoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->nbits.nof_symb); + + // Soft demodulation + srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re); - // Decode RI/HARQ bits before descrambling - if (srslte_ulsch_uci_decode_ri_ack(&q->ul_sch, cfg, softbuffer, q->q, seq->c, uci_data)) { - fprintf(stderr, "Error decoding RI/HARQ bits\n"); + srslte_sequence_t *seq = NULL; + + // Create sequence if does not exist + if (!q->users[rnti]) { + srslte_sequence_t tmp; + seq = &tmp; + if (srslte_sequence_pusch(seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { return SRSLTE_ERROR; } - - // Descrambling - srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits); - - return srslte_ulsch_uci_decode(&q->ul_sch, cfg, softbuffer, q->q, q->g, data, uci_data); } else { - fprintf(stderr, "Must call srslte_pusch_set_rnti() before calling srslte_pusch_decode()\n"); - return SRSLTE_ERROR; - } - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } -} - -/** Decodes the PUSCH from the received symbols - */ -int srslte_pusch_uci_decode(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, - cf_t *ce, float noise_estimate, - uint8_t *data, srslte_uci_data_t *uci_data) -{ - return srslte_pusch_uci_decode_seq(q, cfg, softbuffer, &q->seq[cfg->sf_idx], sf_symbols, ce, noise_estimate, data, uci_data); -} - -/** Decodes the PUSCH from the received symbols for a given RNTI index - */ -int srslte_pusch_uci_decode_rnti_idx(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, - cf_t *ce, float noise_estimate, - uint32_t rnti_idx, - uint8_t *data, srslte_uci_data_t *uci_data) -{ - if (rnti_idx < q->nof_crnti) { - if (q->rnti_multi[rnti_idx]) { - return srslte_pusch_uci_decode_seq(q, cfg, softbuffer, &q->seq_multi[cfg->sf_idx][rnti_idx], sf_symbols, ce, noise_estimate, data, uci_data); - } else { - fprintf(stderr, "Error RNTI idx %d not set\n", rnti_idx); + seq = &q->users[rnti]->seq[cfg->sf_idx]; + } + + // Decode RI/HARQ bits before descrambling + if (srslte_ulsch_uci_decode_ri_ack(&q->ul_sch, cfg, softbuffer, q->q, seq->c, uci_data)) { + fprintf(stderr, "Error decoding RI/HARQ bits\n"); return SRSLTE_ERROR; } + + // Descrambling + srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits); + + if (!q->users[rnti]) { + srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits); + srslte_sequence_free(seq); + } + + return srslte_ulsch_uci_decode(&q->ul_sch, cfg, softbuffer, q->q, q->g, data, uci_data); } else { - return SRSLTE_ERROR_INVALID_INPUTS; + return SRSLTE_ERROR_INVALID_INPUTS; } } diff --git a/srslte/lib/phch/test/pdsch_test.c b/srslte/lib/phch/test/pdsch_test.c index 2e869f6f2..3b3b1e568 100644 --- a/srslte/lib/phch/test/pdsch_test.c +++ b/srslte/lib/phch/test/pdsch_test.c @@ -229,14 +229,14 @@ int main(int argc, char **argv) { if (rv_idx) { /* Do 1st transmission for rv_idx!=0 */ pdsch_cfg.rv = 0; - if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) { + if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, rnti, slot_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); goto quit; } } pdsch_cfg.rv = rv_idx; - if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) { + if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, rnti, slot_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); goto quit; } @@ -265,7 +265,7 @@ int main(int argc, char **argv) { srslte_ofdm_rx_sf(&ofdm_rx, sf_symbols, slot_symbols[1]); #endif srslte_softbuffer_rx_reset_tbs(&softbuffer_rx, grant.mcs.tbs); - r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data); + r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, rnti, data); } gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index 9deaef2cb..45bd1ae09 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -97,7 +97,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error initiating PDSCH\n"); return; } - srslte_pdsch_set_rnti(&pdsch, (uint16_t) (rnti32 & 0xffff)); + uint16_t rnti = (uint16_t) (rnti32 & 0xffff); + srslte_pdsch_set_rnti(&pdsch, rnti); if (srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating soft buffer\n"); @@ -250,7 +251,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) noise_power = srslte_chest_dl_get_noise_estimate(&chest); } - r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes); + r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, rnti, data_bytes); } uint8_t *data = malloc(grant.mcs.tbs); diff --git a/srslte/lib/phch/test/pusch_encode_test_mex.c b/srslte/lib/phch/test/pusch_encode_test_mex.c index 4d8693bbf..59c0bbe15 100644 --- a/srslte/lib/phch/test/pusch_encode_test_mex.c +++ b/srslte/lib/phch/test/pusch_encode_test_mex.c @@ -76,8 +76,9 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Field RNTI not found in pusch config\n"); return; } - srslte_pusch_set_rnti(&pusch, (uint16_t) (rnti32 & 0xffff)); + uint16_t rnti = (uint16_t) (rnti32 & 0xffff); + srslte_pusch_set_rnti(&pusch, rnti); srslte_pusch_cfg_t cfg; @@ -195,7 +196,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexPrintf("I_cqi: %2d, I_ri: %2d, I_ack=%2d\n", cfg.uci_cfg.I_offset_cqi, cfg.uci_cfg.I_offset_ri, cfg.uci_cfg.I_offset_ack); mexPrintf("NofRE: %3d, NofBits: %3d, TBS: %3d, N_srs=%d\n", cfg.nbits.nof_re, cfg.nbits.nof_bits, grant.mcs.tbs, N_srs); - int r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols); + int r = srslte_pusch_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, rnti, sf_symbols); if (r < 0) { mexErrMsgTxt("Error encoding PUSCH\n"); return; @@ -205,7 +206,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } if (cfg.rv > 0) { - r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols); + r = srslte_pusch_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, rnti, sf_symbols); if (r < 0) { mexErrMsgTxt("Error encoding PUSCH\n"); return; diff --git a/srslte/lib/phch/test/pusch_test.c b/srslte/lib/phch/test/pusch_test.c index def6b5982..29980a83f 100644 --- a/srslte/lib/phch/test/pusch_test.c +++ b/srslte/lib/phch/test/pusch_test.c @@ -164,7 +164,8 @@ int main(int argc, char **argv) { exit(-1); } - srslte_pusch_set_rnti(&pusch, 1234); + uint16_t rnti = 1234; + srslte_pusch_set_rnti(&pusch, rnti); srslte_uci_data_t uci_data_tx; srslte_uci_data_t uci_data_rx; @@ -208,13 +209,13 @@ int main(int argc, char **argv) { uint32_t ntrials = 100; - if (srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer_tx, data, uci_data_tx, sf_symbols)) { + if (srslte_pusch_encode(&pusch, &cfg, &softbuffer_tx, data, uci_data_tx, rnti, sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); exit(-1); } if (rv_idx > 0) { cfg.rv = rv_idx; - if (srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer_tx, data, uci_data_tx, sf_symbols)) { + if (srslte_pusch_encode(&pusch, &cfg, &softbuffer_tx, data, uci_data_tx, rnti, sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); exit(-1); } @@ -230,7 +231,7 @@ int main(int argc, char **argv) { } gettimeofday(&t[1], NULL); - int r = srslte_pusch_uci_decode(&pusch, &cfg, &softbuffer_rx, sf_symbols, ce, 0, data, &uci_data_rx); + int r = srslte_pusch_decode(&pusch, &cfg, &softbuffer_rx, sf_symbols, ce, 0, rnti, data, &uci_data_rx); gettimeofday(&t[2], NULL); get_time_interval(t); if (r) { diff --git a/srslte/lib/phch/uci.c b/srslte/lib/phch/uci.c index 10a4a99c1..b22ff75ec 100644 --- a/srslte/lib/phch/uci.c +++ b/srslte/lib/phch/uci.c @@ -299,8 +299,9 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q, // Set viterbi normalization based on amplitude int16_t max = srslte_vec_max_abs_star_si(q->encoded_cqi_s, 3 * (nof_bits + 8)); - srslte_viterbi_set_gain_quant_s(&q->viterbi, (float) abs(max)/36); - + if (max != 0) { + srslte_viterbi_set_gain_quant_s(&q->viterbi, (float) abs(max)/36); + } DEBUG("cconv_rx=", 0); if (SRSLTE_VERBOSE_ISDEBUG()) { srslte_vec_fprint_s(stdout, q->encoded_cqi_s, 3 * (nof_bits + 8)); diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 9444be773..3f4e739fa 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -299,7 +299,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { - ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, + ret = srslte_pdsch_decode(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, q->sf_symbols, q->ce, noise_estimate, rnti, data); @@ -543,7 +543,7 @@ void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuf snprintf(tmpstr,64,"rmout_%d.dat",i); srslte_vec_save_file(tmpstr, softbuffer->buffer_f[i], (3*cb_len+12)*sizeof(int16_t)); } - printf("Saved files for tti=%d, sf=%d, cfi=%d, mcs=%d, rv=%d, rnti=%d\n", tti, tti%10, cfi, + printf("Saved files for tti=%d, sf=%d, cfi=%d, mcs=%d, rv=%d, rnti=0x%x\n", tti, tti%10, cfi, q->pdsch_cfg.grant.mcs.idx, rv_idx, rnti); } diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index 483c83820..2b05e2df1 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -394,7 +394,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); - if (srslte_pusch_uci_encode_rnti(&q->pusch, &q->pusch_cfg, softbuffer, data, uci_data, rnti, q->sf_symbols)) { + if (srslte_pusch_encode(&q->pusch, &q->pusch_cfg, softbuffer, data, uci_data, rnti, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); return ret; } From 5b7d082a04ec5173483e3e61ddc2082e295ebd00 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 21 Nov 2016 10:34:00 +0100 Subject: [PATCH 071/111] fixed coverty bug --- srslte/include/srslte/phch/pusch.h | 1 + srslte/lib/phch/pusch.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/include/srslte/phch/pusch.h b/srslte/include/srslte/phch/pusch.h index e75b83c63..25f4f40d8 100644 --- a/srslte/include/srslte/phch/pusch.h +++ b/srslte/include/srslte/phch/pusch.h @@ -87,6 +87,7 @@ typedef struct SRSLTE_API { // This is to generate the scrambling seq for multiple CRNTIs srslte_pusch_user_t **users; + srslte_sequence_t tmp_seq; srslte_sch_t ul_sch; bool shortened; diff --git a/srslte/lib/phch/pusch.c b/srslte/lib/phch/pusch.c index 7c4484872..d1e9b6838 100644 --- a/srslte/lib/phch/pusch.c +++ b/srslte/lib/phch/pusch.c @@ -536,8 +536,7 @@ int srslte_pusch_decode(srslte_pusch_t *q, // Create sequence if does not exist if (!q->users[rnti]) { - srslte_sequence_t tmp; - seq = &tmp; + seq = &q->tmp_seq; if (srslte_sequence_pusch(seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { return SRSLTE_ERROR; } From b0245503163e8dbfb0fea6c8c54cf4c853fe530b Mon Sep 17 00:00:00 2001 From: Agmagor Date: Tue, 22 Nov 2016 23:55:37 +0100 Subject: [PATCH 072/111] coverity: timeval.tv_usec is 'long int', not 'int' --- srslte/examples/synch_file.c | 2 +- srslte/lib/ch_estimation/test/refsignal_ul_test.c | 4 ++-- srslte/lib/mimo/test/precoding_test.c | 2 +- srslte/lib/modem/test/modem_test.c | 6 +++--- srslte/lib/phch/sch.c | 2 +- srslte/lib/phch/test/prach_test.c | 2 +- srslte/lib/phch/test/pucch_test.c | 2 +- srslte/lib/scrambling/test/scrambling_test.c | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/srslte/examples/synch_file.c b/srslte/examples/synch_file.c index 798db953e..a9e3e7146 100644 --- a/srslte/examples/synch_file.c +++ b/srslte/examples/synch_file.c @@ -182,7 +182,7 @@ int main(int argc, char **argv) { } gettimeofday(&tdata[2], NULL); get_time_interval(tdata); - printf("done in %d s %d ms\n", (int) tdata[0].tv_sec, (int) tdata[0].tv_usec/1000); + printf("done in %ld s %ld ms\n", (int) tdata[0].tv_sec, (int) tdata[0].tv_usec/1000); printf("\n\tFr.Cnt\tN_id_2\tN_id_1\tSubf\tPSS Peak/Avg\tIdx\tm0\tm1\tCFO\n"); printf("\t===============================================================================\n"); diff --git a/srslte/lib/ch_estimation/test/refsignal_ul_test.c b/srslte/lib/ch_estimation/test/refsignal_ul_test.c index d5530c395..40e940b49 100644 --- a/srslte/lib/ch_estimation/test/refsignal_ul_test.c +++ b/srslte/lib/ch_estimation/test/refsignal_ul_test.c @@ -131,13 +131,13 @@ int main(int argc, char **argv) { srslte_refsignal_dmrs_pusch_gen(&refs, nof_prb, sf_idx, cshift_dmrs, signal); gettimeofday(&t[2], NULL); get_time_interval(t); - printf("DMRS ExecTime: %d us\n", t[0].tv_usec); + printf("DMRS ExecTime: %ld us\n", t[0].tv_usec); gettimeofday(&t[1], NULL); srslte_refsignal_srs_gen(&refs, sf_idx, signal); gettimeofday(&t[2], NULL); get_time_interval(t); - printf("SRS ExecTime: %d us\n", t[0].tv_usec); + printf("SRS ExecTime: %ld us\n", t[0].tv_usec); } } } diff --git a/srslte/lib/mimo/test/precoding_test.c b/srslte/lib/mimo/test/precoding_test.c index 68ff0d8f5..e935a7067 100644 --- a/srslte/lib/mimo/test/precoding_test.c +++ b/srslte/lib/mimo/test/precoding_test.c @@ -173,7 +173,7 @@ int main(int argc, char **argv) { } gettimeofday(&t[2], NULL); get_time_interval(t); - printf("Execution Time: %d us\n", t[0].tv_usec); + printf("Execution Time: %ld us\n", t[0].tv_usec); /* check errors */ mse = 0; diff --git a/srslte/lib/modem/test/modem_test.c b/srslte/lib/modem/test/modem_test.c index 59c80dbfc..d233f7418 100644 --- a/srslte/lib/modem/test/modem_test.c +++ b/srslte/lib/modem/test/modem_test.c @@ -159,7 +159,7 @@ int main(int argc, char **argv) { gettimeofday(&t[2], NULL); get_time_interval(t); - printf("Bit: %d us\n", t[0].tv_usec); + printf("Bit: %ld us\n", t[0].tv_usec); /* Test packed implementation */ srslte_bit_pack_vector(input, input_bytes, num_bits); @@ -170,8 +170,8 @@ int main(int argc, char **argv) { gettimeofday(&t[2], NULL); get_time_interval(t); - printf("Byte: %d us\n", t[0].tv_usec); + printf("Byte: %ld us\n", t[0].tv_usec); for (int i=0;i=0 ? 1 : 0; } diff --git a/srslte/lib/phch/sch.c b/srslte/lib/phch/sch.c index 5b0c6c266..4cc3da883 100644 --- a/srslte/lib/phch/sch.c +++ b/srslte/lib/phch/sch.c @@ -654,7 +654,7 @@ int srslte_ulsch_uci_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_sof uci_data->uci_cqi, &uci_data->cqi_ack); gettimeofday(&t[2], NULL); get_time_interval(t); - printf("texec=%d us\n", t[0].tv_usec); + printf("texec=%ld us\n", t[0].tv_usec); if (ret < 0) { return ret; diff --git a/srslte/lib/phch/test/prach_test.c b/srslte/lib/phch/test/prach_test.c index 088f815c0..ddd05eba0 100644 --- a/srslte/lib/phch/test/prach_test.c +++ b/srslte/lib/phch/test/prach_test.c @@ -114,7 +114,7 @@ int main(int argc, char **argv) { srslte_prach_detect(p, frequency_offset, &preamble[p->N_cp], prach_len, indices, &n_indices); gettimeofday(&t[2], NULL); get_time_interval(t); - printf("texec=%d us\n", t[0].tv_usec); + printf("texec=%ld us\n", t[0].tv_usec); if(n_indices != 1 || indices[0] != seq_index) return -1; } diff --git a/srslte/lib/phch/test/pucch_test.c b/srslte/lib/phch/test/pucch_test.c index a2a9b8958..67cf46fdd 100644 --- a/srslte/lib/phch/test/pucch_test.c +++ b/srslte/lib/phch/test/pucch_test.c @@ -156,7 +156,7 @@ int main(int argc, char **argv) { } gettimeofday(&t[2], NULL); get_time_interval(t); - INFO("format %d, n_pucch: %d, ncs: %d, d: %d, t_exec=%d us\n", format, n_pucch, ncs, d, t[0].tv_usec); + INFO("format %d, n_pucch: %d, ncs: %d, d: %d, t_exec=%ld us\n", format, n_pucch, ncs, d, t[0].tv_usec); } } } diff --git a/srslte/lib/scrambling/test/scrambling_test.c b/srslte/lib/scrambling/test/scrambling_test.c index 49679e9e0..9ff47dc85 100644 --- a/srslte/lib/scrambling/test/scrambling_test.c +++ b/srslte/lib/scrambling/test/scrambling_test.c @@ -131,7 +131,7 @@ int main(int argc, char **argv) { srslte_scrambling_b(&seq, scrambled_b); get_time_interval(t); - printf("Texec=%d us for %d bits\n", t[0].tv_usec, seq.len); + printf("Texec=%ld us for %d bits\n", t[0].tv_usec, seq.len); for (i=0;i Date: Wed, 23 Nov 2016 10:36:04 +0000 Subject: [PATCH 073/111] Changed port types to uint16 --- srslte/include/srslte/io/netsink.h | 2 +- srslte/include/srslte/io/netsource.h | 2 +- srslte/lib/io/netsink.c | 2 +- srslte/lib/io/netsource.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/srslte/include/srslte/io/netsink.h b/srslte/include/srslte/io/netsink.h index 154d33feb..4f0771958 100644 --- a/srslte/include/srslte/io/netsink.h +++ b/srslte/include/srslte/io/netsink.h @@ -60,7 +60,7 @@ typedef struct SRSLTE_API { SRSLTE_API int srslte_netsink_init(srslte_netsink_t *q, char *address, - int port, + uint16_t port, srslte_netsink_type_t type); SRSLTE_API void srslte_netsink_free(srslte_netsink_t *q); diff --git a/srslte/include/srslte/io/netsource.h b/srslte/include/srslte/io/netsource.h index b581a1ef1..7a2739993 100644 --- a/srslte/include/srslte/io/netsource.h +++ b/srslte/include/srslte/io/netsource.h @@ -61,7 +61,7 @@ typedef struct SRSLTE_API { SRSLTE_API int srslte_netsource_init(srslte_netsource_t *q, char *address, - int port, + uint16_t port, srslte_netsource_type_t type); SRSLTE_API void srslte_netsource_free(srslte_netsource_t *q); diff --git a/srslte/lib/io/netsink.c b/srslte/lib/io/netsink.c index bedb5fc92..c7f8d3db8 100644 --- a/srslte/lib/io/netsink.c +++ b/srslte/lib/io/netsink.c @@ -38,7 +38,7 @@ #include "srslte/io/netsink.h" -int srslte_netsink_init(srslte_netsink_t *q, char *address, int port, srslte_netsink_type_t type) { +int srslte_netsink_init(srslte_netsink_t *q, char *address, uint16_t port, srslte_netsink_type_t type) { bzero(q, sizeof(srslte_netsink_t)); q->sockfd=socket(AF_INET, type==SRSLTE_NETSINK_TCP?SOCK_STREAM:SOCK_DGRAM,0); diff --git a/srslte/lib/io/netsource.c b/srslte/lib/io/netsource.c index f41296c3c..a86a05d1c 100644 --- a/srslte/lib/io/netsource.c +++ b/srslte/lib/io/netsource.c @@ -36,7 +36,7 @@ #include "srslte/io/netsource.h" -int srslte_netsource_init(srslte_netsource_t *q, char *address, int port, srslte_netsource_type_t type) { +int srslte_netsource_init(srslte_netsource_t *q, char *address, uint16_t port, srslte_netsource_type_t type) { bzero(q, sizeof(srslte_netsource_t)); q->sockfd=socket(AF_INET,type==SRSLTE_NETSOURCE_TCP?SOCK_STREAM:SOCK_DGRAM,0); From 604dcef9cdfbd42b319e6345d2aaa55a2aedfabd Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 23 Nov 2016 19:09:52 +0100 Subject: [PATCH 074/111] Commented printf message --- srslte/lib/phch/dci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 9bb8c96be..66a1b218f 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -65,7 +65,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { - fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); + //fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); return ret; } From 881bb7f6b335ffcf3473db6eeb3ecf2c32c19ad3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 23 Nov 2016 19:11:34 +0100 Subject: [PATCH 075/111] puch_test_mex: fixed new api --- srslte/lib/phch/test/pusch_test_mex.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srslte/lib/phch/test/pusch_test_mex.c b/srslte/lib/phch/test/pusch_test_mex.c index 6178a1f3a..7b29075eb 100644 --- a/srslte/lib/phch/test/pusch_test_mex.c +++ b/srslte/lib/phch/test/pusch_test_mex.c @@ -99,7 +99,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error initiating PDSCH\n"); return; } - srslte_pusch_set_rnti(&pusch, (uint16_t) (rnti32 & 0xffff)); + uint16_t rnti = (uint16_t) (rnti32 & 0xffff); + srslte_pusch_set_rnti(&pusch, rnti); if (srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating soft buffer\n"); @@ -272,7 +273,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) noise_power = srslte_chest_ul_get_noise_estimate(&chest); } - r = srslte_pusch_uci_decode(&pusch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes, &uci_data); + r = srslte_pusch_decode(&pusch, &cfg, &softbuffer, input_fft, ce, noise_power, rnti, data_bytes, &uci_data); } uint8_t *data = malloc(grant.mcs.tbs); From 50694d7c3fe3e1c6cce5fc08a5e67fb5766bedff Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 24 Nov 2016 11:18:54 +0100 Subject: [PATCH 076/111] PRACH: support all ConfigIndex values --- srslte/lib/phch/prach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index 1cfedd3c6..59ed3d072 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -341,7 +341,7 @@ int srslte_prach_init(srslte_prach_t *p, int ret = SRSLTE_ERROR; if(p != NULL && N_ifft_ul < 2049 && - config_idx < 16 && + config_idx < 64 && root_seq_index < MAX_ROOTS) { uint32_t preamble_format = srslte_prach_get_preamble_format(config_idx); From b401ee27ea7c0f9e143f5c506f34739313bca40b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 25 Nov 2016 12:43:04 +0100 Subject: [PATCH 077/111] removed warning --- srslte/lib/phch/dci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 9bb8c96be..50f3dd0bb 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -62,7 +62,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) { crc_is_crnti = true; } - srslte_dci_format_t tmp = msg->format; + //srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); From d970aecd6c2cafc5970cfc31ac38ef880b7a76fb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 25 Nov 2016 12:45:13 +0100 Subject: [PATCH 078/111] fixed compilation issue --- srslte/lib/phch/dci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 50f3dd0bb..4dea38567 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -65,7 +65,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, //srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { - fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); + //fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); return ret; } From 4c3e64d224aa7f981a5351898e5dddf2e2e36579 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 28 Nov 2016 22:21:50 +0100 Subject: [PATCH 079/111] removed bw_idx from srslte_cell_t --- srslte/include/srslte/common/phy_common.h | 5 +- srslte/lib/common/phy_common.c | 80 ++++++++++++++--------- srslte/lib/phch/pbch.c | 6 +- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/srslte/include/srslte/common/phy_common.h b/srslte/include/srslte/common/phy_common.h index 81cce7b66..95110a9a2 100644 --- a/srslte/include/srslte/common/phy_common.h +++ b/srslte/include/srslte/common/phy_common.h @@ -158,7 +158,6 @@ typedef enum { typedef struct SRSLTE_API { uint32_t nof_prb; uint32_t nof_ports; - uint32_t bw_idx; uint32_t id; srslte_cp_t cp; srslte_phich_length_t phich_length; @@ -246,8 +245,12 @@ SRSLTE_API char *srslte_mod_string(srslte_mod_t mod); SRSLTE_API uint32_t srslte_mod_bits_x_symbol(srslte_mod_t mod); +SRSLTE_API int srslte_band_get_band(uint32_t earfcn); + SRSLTE_API float srslte_band_fd(uint32_t earfcn); +SRSLTE_API float srslte_band_fu(uint32_t earfcn); + SRSLTE_API int srslte_band_get_fd_band(uint32_t band, srslte_earfcn_t *earfcn, int earfcn_start, diff --git a/srslte/lib/common/phy_common.c b/srslte/lib/common/phy_common.c index 447a7562d..e3429e0a3 100644 --- a/srslte/lib/common/phy_common.c +++ b/srslte/lib/common/phy_common.c @@ -372,39 +372,40 @@ struct lte_band { float fd_low_mhz; uint32_t earfcn_offset; uint32_t earfcn_max; + float duplex_mhz; enum band_geographical_area area; }; struct lte_band lte_bands[SRSLTE_NOF_LTE_BANDS] = { - {1, 2110, 0, 599, SRSLTE_BAND_GEO_AREA_ALL}, - {2, 1930, 600, 1199, SRSLTE_BAND_GEO_AREA_NAR}, - {3, 1805, 1200, 1949, SRSLTE_BAND_GEO_AREA_ALL}, - {4, 2110, 1950, 2399, SRSLTE_BAND_GEO_AREA_NAR}, - {5, 869, 2400, 2649, SRSLTE_BAND_GEO_AREA_NAR}, - {6, 875, 2650, 2749, SRSLTE_BAND_GEO_AREA_APAC}, - {7, 2620, 2750, 3449, SRSLTE_BAND_GEO_AREA_EMEA}, - {8, 925, 3450, 3799, SRSLTE_BAND_GEO_AREA_ALL}, - {9, 1844.9, 3800, 4149, SRSLTE_BAND_GEO_AREA_APAC}, - {10, 2110, 4150, 4749, SRSLTE_BAND_GEO_AREA_NAR}, - {11, 1475.9, 4750, 4949, SRSLTE_BAND_GEO_AREA_JAPAN}, - {12, 729, 5010, 5179, SRSLTE_BAND_GEO_AREA_NAR}, - {13, 746, 5180, 5279, SRSLTE_BAND_GEO_AREA_NAR}, - {14, 758, 5280, 5379, SRSLTE_BAND_GEO_AREA_NAR}, - {17, 734, 5730, 5849, SRSLTE_BAND_GEO_AREA_NAR}, - {18, 860, 5850, 5999, SRSLTE_BAND_GEO_AREA_JAPAN}, - {19, 875, 6000, 6149, SRSLTE_BAND_GEO_AREA_JAPAN}, - {20, 791, 6150, 6449, SRSLTE_BAND_GEO_AREA_EMEA}, - {21, 1495.9, 6450, 6599, SRSLTE_BAND_GEO_AREA_JAPAN}, - {22, 3500, 6600, 7399, SRSLTE_BAND_GEO_AREA_NA}, - {23, 2180, 7500, 7699, SRSLTE_BAND_GEO_AREA_NAR}, - {24, 1525, 7700, 8039, SRSLTE_BAND_GEO_AREA_NAR}, - {25, 1930, 8040, 8689, SRSLTE_BAND_GEO_AREA_NAR}, - {26, 859, 8690, 9039, SRSLTE_BAND_GEO_AREA_NAR}, - {27, 852, 9040, 9209, SRSLTE_BAND_GEO_AREA_NAR}, - {28, 758, 9210, 9659, SRSLTE_BAND_GEO_AREA_APAC}, - {29, 717, 9660, 9769, SRSLTE_BAND_GEO_AREA_NAR}, - {30, 2350, 9770, 9869, SRSLTE_BAND_GEO_AREA_NAR}, - {31, 462.5, 9870, 9919, SRSLTE_BAND_GEO_AREA_CALA} + {1, 2110, 0, 599, 190, SRSLTE_BAND_GEO_AREA_ALL}, + {2, 1930, 600, 1199, 80, SRSLTE_BAND_GEO_AREA_NAR}, + {3, 1805, 1200, 1949, 95, SRSLTE_BAND_GEO_AREA_ALL}, + {4, 2110, 1950, 2399, 400, SRSLTE_BAND_GEO_AREA_NAR}, + {5, 869, 2400, 2649, 45, SRSLTE_BAND_GEO_AREA_NAR}, + {6, 875, 2650, 2749, 45, SRSLTE_BAND_GEO_AREA_APAC}, + {7, 2620, 2750, 3449, 120, SRSLTE_BAND_GEO_AREA_EMEA}, + {8, 925, 3450, 3799, 45, SRSLTE_BAND_GEO_AREA_ALL}, + {9, 1844.9, 3800, 4149, 95, SRSLTE_BAND_GEO_AREA_APAC}, + {10, 2110, 4150, 4749, 400, SRSLTE_BAND_GEO_AREA_NAR}, + {11, 1475.9, 4750, 4949, 48, SRSLTE_BAND_GEO_AREA_JAPAN}, + {12, 729, 5010, 5179, 30, SRSLTE_BAND_GEO_AREA_NAR}, + {13, 746, 5180, 5279, -31, SRSLTE_BAND_GEO_AREA_NAR}, + {14, 758, 5280, 5379, -30, SRSLTE_BAND_GEO_AREA_NAR}, + {17, 734, 5730, 5849, 30, SRSLTE_BAND_GEO_AREA_NAR}, + {18, 860, 5850, 5999, 45, SRSLTE_BAND_GEO_AREA_JAPAN}, + {19, 875, 6000, 6149, 45, SRSLTE_BAND_GEO_AREA_JAPAN}, + {20, 791, 6150, 6449, -41, SRSLTE_BAND_GEO_AREA_EMEA}, + {21, 1495.9, 6450, 6599, 48, SRSLTE_BAND_GEO_AREA_JAPAN}, + {22, 3500, 6600, 7399, 100, SRSLTE_BAND_GEO_AREA_NA}, + {23, 2180, 7500, 7699, 180, SRSLTE_BAND_GEO_AREA_NAR}, + {24, 1525, 7700, 8039, -101.5, SRSLTE_BAND_GEO_AREA_NAR}, + {25, 1930, 8040, 8689, 80, SRSLTE_BAND_GEO_AREA_NAR}, + {26, 859, 8690, 9039, 45, SRSLTE_BAND_GEO_AREA_NAR}, + {27, 852, 9040, 9209, 45, SRSLTE_BAND_GEO_AREA_NAR}, + {28, 758, 9210, 9659, 55, SRSLTE_BAND_GEO_AREA_APAC}, + {29, 717, 9660, 9769, 0, SRSLTE_BAND_GEO_AREA_NAR}, + {30, 2350, 9770, 9869, 45, SRSLTE_BAND_GEO_AREA_NAR}, + {31, 462.5, 9870, 9919, 10, SRSLTE_BAND_GEO_AREA_CALA} }; #define EOF_BAND 9919 @@ -429,7 +430,7 @@ float get_fd(struct lte_band *band, uint32_t earfcn) { } } -float srslte_band_fd(uint32_t earfcn) { +int srslte_band_get_band(uint32_t earfcn) { uint32_t i; i=0; while(i < SRSLTE_NOF_LTE_BANDS && lte_bands[i].earfcn_offset 0 && lte_bands[i].earfcn_offset>earfcn) { + i--; } return get_fd(<e_bands[i], earfcn); } + +float srslte_band_fu(uint32_t earfcn) { + uint32_t i = SRSLTE_NOF_LTE_BANDS-1; + while(i > 0 && lte_bands[i].earfcn_offset>earfcn) { + i--; + } + return get_fd(<e_bands[i], earfcn) - lte_bands[i].duplex_mhz; +} + int srslte_band_get_fd_band_all(uint32_t band, srslte_earfcn_t *earfcn, uint32_t max_elems) { return srslte_band_get_fd_band(band, earfcn, -1, -1, max_elems); } diff --git a/srslte/lib/phch/pbch.c b/srslte/lib/phch/pbch.c index 4c5416ab3..5fdacf7b7 100644 --- a/srslte/lib/phch/pbch.c +++ b/srslte/lib/phch/pbch.c @@ -250,8 +250,8 @@ void srslte_pbch_free(srslte_pbch_t *q) { void srslte_pbch_mib_unpack(uint8_t *msg, srslte_cell_t *cell, uint32_t *sfn) { int phich_res; - cell->bw_idx = srslte_bit_pack(&msg, 3); - switch (cell->bw_idx) { + uint32_t bw_idx = srslte_bit_pack(&msg, 3); + switch (bw_idx) { case 0: cell->nof_prb = 6; break; @@ -259,7 +259,7 @@ void srslte_pbch_mib_unpack(uint8_t *msg, srslte_cell_t *cell, uint32_t *sfn) { cell->nof_prb = 15; break; default: - cell->nof_prb = (cell->bw_idx - 1) * 25; + cell->nof_prb = (bw_idx - 1) * 25; break; } if (*msg) { From a21536a60e4c008a69c083179d783dfdb43b7318 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 29 Nov 2016 20:18:12 +0100 Subject: [PATCH 080/111] fixed get band in phy_common --- srslte/lib/common/phy_common.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/srslte/lib/common/phy_common.c b/srslte/lib/common/phy_common.c index e3429e0a3..68532ebeb 100644 --- a/srslte/lib/common/phy_common.c +++ b/srslte/lib/common/phy_common.c @@ -431,14 +431,9 @@ float get_fd(struct lte_band *band, uint32_t earfcn) { } int srslte_band_get_band(uint32_t earfcn) { - uint32_t i; - i=0; - while(i < SRSLTE_NOF_LTE_BANDS && lte_bands[i].earfcn_offset 0 && lte_bands[i].earfcn_offset>earfcn) { + i--; } return lte_bands[i].band; } From b795a22f6a4bff9cfc2e8ada3433b9354e682730 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 29 Nov 2016 20:31:22 +0100 Subject: [PATCH 081/111] fixed failing tests --- srslte/examples/pdsch_enodeb.c | 1 - srslte/lib/phch/test/pbch_file_test.c | 1 - srslte/lib/phch/test/pcfich_file_test.c | 1 - srslte/lib/phch/test/pdcch_file_test.c | 1 - srslte/lib/phch/test/pdsch_pdcch_file_test.c | 1 - srslte/lib/phch/test/pdsch_test.c | 1 - srslte/lib/phch/test/phich_file_test.c | 1 - srslte/lib/phch/test/pucch_test.c | 1 - 8 files changed, 8 deletions(-) diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index c68b4d125..28c020708 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -57,7 +57,6 @@ char *output_file_name = NULL; srslte_cell_t cell = { 25, // nof_prb 1, // nof_ports - 0, // bw idx 0, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1, // PHICH resources diff --git a/srslte/lib/phch/test/pbch_file_test.c b/srslte/lib/phch/test/pbch_file_test.c index 6e9ba5950..f3e4b9b08 100644 --- a/srslte/lib/phch/test/pbch_file_test.c +++ b/srslte/lib/phch/test/pbch_file_test.c @@ -37,7 +37,6 @@ char *input_file_name = NULL; srslte_cell_t cell = { 6, // nof_prb 2, // nof_ports - 0, // bw_idx 150, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1, // PHICH resources diff --git a/srslte/lib/phch/test/pcfich_file_test.c b/srslte/lib/phch/test/pcfich_file_test.c index 03029c9fc..27b50baeb 100644 --- a/srslte/lib/phch/test/pcfich_file_test.c +++ b/srslte/lib/phch/test/pcfich_file_test.c @@ -39,7 +39,6 @@ char *matlab_file_name = NULL; srslte_cell_t cell = { 6, // nof_prb 1, // nof_ports - 0, // bw_idx 0, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1, // PHICH resources diff --git a/srslte/lib/phch/test/pdcch_file_test.c b/srslte/lib/phch/test/pdcch_file_test.c index ed3aafdf4..b505e6b68 100644 --- a/srslte/lib/phch/test/pdcch_file_test.c +++ b/srslte/lib/phch/test/pdcch_file_test.c @@ -37,7 +37,6 @@ char *input_file_name = NULL; srslte_cell_t cell = { 6, // cell.cell.cell.nof_prb 1, // cell.cell.nof_ports - 0, // bw_idx 0, // cell.id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1, // PHICH resources diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index 372683a36..33ad2c58d 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -37,7 +37,6 @@ char *input_file_name = NULL; srslte_cell_t cell = { 6, // nof_prb 1, // nof_ports - 0, // bw_idx 0, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1, // PHICH resources diff --git a/srslte/lib/phch/test/pdsch_test.c b/srslte/lib/phch/test/pdsch_test.c index 3b3b1e568..099400462 100644 --- a/srslte/lib/phch/test/pdsch_test.c +++ b/srslte/lib/phch/test/pdsch_test.c @@ -39,7 +39,6 @@ srslte_cell_t cell = { 6, // nof_prb 1, // nof_ports - 0, 0, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1_6, // PHICH resources diff --git a/srslte/lib/phch/test/phich_file_test.c b/srslte/lib/phch/test/phich_file_test.c index 1fdc12797..f037a55da 100644 --- a/srslte/lib/phch/test/phich_file_test.c +++ b/srslte/lib/phch/test/phich_file_test.c @@ -38,7 +38,6 @@ char *matlab_file_name = NULL; srslte_cell_t cell = { 50, // cell.nof_prb 2, // cell.nof_ports - 2, // bw_idx 150, // cell.id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1, // PHICH resources diff --git a/srslte/lib/phch/test/pucch_test.c b/srslte/lib/phch/test/pucch_test.c index 67cf46fdd..20b173e4b 100644 --- a/srslte/lib/phch/test/pucch_test.c +++ b/srslte/lib/phch/test/pucch_test.c @@ -36,7 +36,6 @@ srslte_cell_t cell = { 25, // nof_prb 1, // nof_ports - 2, // bw_idx = 5 MHz 1, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_R_1_6, // PHICH resources From 0dd24e32dfb0a9bef775e5199433261f4635f40f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 8 Dec 2016 21:39:35 +0100 Subject: [PATCH 082/111] added check for cfi in srslte_ue_dl_find_ul_dci --- srslte/lib/phch/dci.c | 2 +- srslte/lib/ue/ue_dl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 4dea38567..a8d0260e4 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -65,7 +65,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, //srslte_dci_format_t tmp = msg->format; ret = srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, nof_ports, crc_is_crnti); if (ret) { - //fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(tmp), tmp); + fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(msg->format), msg->format); return ret; } diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 3f4e739fa..d7015c46a 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -376,7 +376,7 @@ static int dci_blind_search(srslte_ue_dl_t *q, dci_blind_search_t *search_space, int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, srslte_dci_msg_t *dci_msg) { - if (rnti) { + if (rnti && cfi > 1 && cfi < 4) { /* Do not search if an UL DCI is already pending */ if (q->pending_ul_dci_rnti == rnti) { q->pending_ul_dci_rnti = 0; From 54ffba6567826593b8c007d84a1486e66d85ca8f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 30 Nov 2016 14:51:09 -0500 Subject: [PATCH 083/111] fixed missing SO_REUSE* in old kernels --- srslte/lib/io/netsink.c | 4 ++++ srslte/lib/io/netsource.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/srslte/lib/io/netsink.c b/srslte/lib/io/netsink.c index c7f8d3db8..ce4fdd731 100644 --- a/srslte/lib/io/netsink.c +++ b/srslte/lib/io/netsink.c @@ -48,10 +48,14 @@ int srslte_netsink_init(srslte_netsink_t *q, char *address, uint16_t port, srslt } int enable = 1; +#if defined (SO_REUSEADDR) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEADDR) failed"); +#endif +#if defined (SO_REUSEPORT) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEPORT) failed"); +#endif q->servaddr.sin_family = AF_INET; q->servaddr.sin_addr.s_addr=inet_addr(address); diff --git a/srslte/lib/io/netsource.c b/srslte/lib/io/netsource.c index a86a05d1c..9d6849368 100644 --- a/srslte/lib/io/netsource.c +++ b/srslte/lib/io/netsource.c @@ -48,11 +48,14 @@ int srslte_netsource_init(srslte_netsource_t *q, char *address, uint16_t port, s // Make sockets reusable int enable = 1; +#if defined (SO_REUSEADDR) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEADDR) failed"); +#endif +#if defined (SO_REUSEPORT) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEPORT) failed"); - +#endif q->type = type; q->servaddr.sin_family = AF_INET; From cea68bf2f212a47ad76f4f5f7e6abedab7532bca Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Fri, 9 Dec 2016 10:03:02 +0000 Subject: [PATCH 084/111] Added const to char* to allow initialisation from std::string in applications using the library --- srslte/include/srslte/io/netsink.h | 2 +- srslte/include/srslte/io/netsource.h | 2 +- srslte/lib/io/netsink.c | 2 +- srslte/lib/io/netsource.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/srslte/include/srslte/io/netsink.h b/srslte/include/srslte/io/netsink.h index 4f0771958..3339716c1 100644 --- a/srslte/include/srslte/io/netsink.h +++ b/srslte/include/srslte/io/netsink.h @@ -59,7 +59,7 @@ typedef struct SRSLTE_API { }srslte_netsink_t; SRSLTE_API int srslte_netsink_init(srslte_netsink_t *q, - char *address, + const char *address, uint16_t port, srslte_netsink_type_t type); diff --git a/srslte/include/srslte/io/netsource.h b/srslte/include/srslte/io/netsource.h index 7a2739993..e10d8d644 100644 --- a/srslte/include/srslte/io/netsource.h +++ b/srslte/include/srslte/io/netsource.h @@ -60,7 +60,7 @@ typedef struct SRSLTE_API { }srslte_netsource_t; SRSLTE_API int srslte_netsource_init(srslte_netsource_t *q, - char *address, + const char *address, uint16_t port, srslte_netsource_type_t type); diff --git a/srslte/lib/io/netsink.c b/srslte/lib/io/netsink.c index ce4fdd731..0a4c8110d 100644 --- a/srslte/lib/io/netsink.c +++ b/srslte/lib/io/netsink.c @@ -38,7 +38,7 @@ #include "srslte/io/netsink.h" -int srslte_netsink_init(srslte_netsink_t *q, char *address, uint16_t port, srslte_netsink_type_t type) { +int srslte_netsink_init(srslte_netsink_t *q, const char *address, uint16_t port, srslte_netsink_type_t type) { bzero(q, sizeof(srslte_netsink_t)); q->sockfd=socket(AF_INET, type==SRSLTE_NETSINK_TCP?SOCK_STREAM:SOCK_DGRAM,0); diff --git a/srslte/lib/io/netsource.c b/srslte/lib/io/netsource.c index 9d6849368..4e81331f4 100644 --- a/srslte/lib/io/netsource.c +++ b/srslte/lib/io/netsource.c @@ -36,7 +36,7 @@ #include "srslte/io/netsource.h" -int srslte_netsource_init(srslte_netsource_t *q, char *address, uint16_t port, srslte_netsource_type_t type) { +int srslte_netsource_init(srslte_netsource_t *q, const char *address, uint16_t port, srslte_netsource_type_t type) { bzero(q, sizeof(srslte_netsource_t)); q->sockfd=socket(AF_INET,type==SRSLTE_NETSOURCE_TCP?SOCK_STREAM:SOCK_DGRAM,0); From 238818f1d3d71139302d888e5f937b66b384fe43 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Dec 2016 11:25:25 +0100 Subject: [PATCH 085/111] fixed FPE in PUSCH UCI decoding --- srslte/lib/phch/uci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srslte/lib/phch/uci.c b/srslte/lib/phch/uci.c index b22ff75ec..62d2bedcf 100644 --- a/srslte/lib/phch/uci.c +++ b/srslte/lib/phch/uci.c @@ -299,8 +299,10 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q, // Set viterbi normalization based on amplitude int16_t max = srslte_vec_max_abs_star_si(q->encoded_cqi_s, 3 * (nof_bits + 8)); - if (max != 0) { + if (abs(max) > 100) { srslte_viterbi_set_gain_quant_s(&q->viterbi, (float) abs(max)/36); + } else { + srslte_viterbi_set_gain_quant_s(&q->viterbi, 1); } DEBUG("cconv_rx=", 0); if (SRSLTE_VERBOSE_ISDEBUG()) { From cf7be556ef04c01c85bba3e48b602c3994fd9a0e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 19 Dec 2016 15:25:19 +0100 Subject: [PATCH 086/111] minor RA changes --- srslte/include/srslte/enb/enb_ul.h | 3 +-- srslte/include/srslte/phch/ra.h | 4 ++++ srslte/lib/phch/ra.c | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index 9a05436ba..6e426b81c 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -94,10 +94,9 @@ typedef struct { srslte_dci_location_t location; uint32_t rv_idx; uint32_t current_tx_nb; - bool needs_pdcch; uint8_t *data; srslte_softbuffer_rx_t *softbuffer; - + bool needs_pdcch; } srslte_enb_ul_pusch_t; /* This function shall be called just after the initial synchronization */ diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 5da9a191b..176ccecf9 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -206,6 +206,10 @@ SRSLTE_API void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t sf_idx, srslte_ra_nbits_t *nbits); +SRSLTE_API uint32_t srslte_ra_dl_approx_nof_re(srslte_cell_t cell, + uint32_t nof_prb, + uint32_t nof_ctrl_symbols); + SRSLTE_API uint32_t srslte_ra_dl_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t cell, uint32_t sf_idx, diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index 2f4db4074..9f5da581f 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -198,6 +198,7 @@ static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *gr // 8.6.1 and 8.6.2 36.213 second paragraph grant->mcs.mod = SRSLTE_MOD_QPSK; tbs = srslte_ra_tbs_from_idx(last_ul_tbs_idx[harq_pid%8], grant->L_prb); + dci->rv_idx = 1; } else if (dci->mcs_idx >= 29) { // Else use last TBS/Modulation and use mcs to obtain rv_idx tbs = srslte_ra_tbs_from_idx(last_ul_tbs_idx[harq_pid%8], grant->L_prb); @@ -249,6 +250,24 @@ int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, uint32_t nof_prb, uint32_ return SRSLTE_SUCCESS; } +uint32_t srslte_ra_dl_approx_nof_re(srslte_cell_t cell, uint32_t nof_prb, uint32_t nof_ctrl_symbols) +{ + uint32_t nof_refs = 0; + uint32_t nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-nof_ctrl_symbols; + switch(cell.nof_ports) { + case 1: + nof_refs = 2*3; + break; + case 2: + nof_refs = 4*3; + break; + case 4: + nof_refs = 4*4; + break; + } + return nof_prb * (nof_symb*SRSLTE_NRE-nof_refs); +} + /* Computes the number of RE for each PRB in the prb_dist structure */ uint32_t srslte_ra_dl_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t cell, uint32_t sf_idx, uint32_t nof_ctrl_symbols) From 1ea776f8c3927b91f93f61d2b5e60edae45aefc9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 20 Dec 2016 13:28:53 +0100 Subject: [PATCH 087/111] return valid crc on turbo decoder zero words --- srslte/lib/phch/sch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/phch/sch.c b/srslte/lib/phch/sch.c index c144f1265..ad77035b8 100644 --- a/srslte/lib/phch/sch.c +++ b/srslte/lib/phch/sch.c @@ -466,7 +466,7 @@ static int decode_tb(srslte_sch_t *q, INFO("Warning: Received all-zero transport block\n\n", 0); } - if (par_rx == par_tx && par_rx) { + if (par_rx == par_tx) { INFO("TB decoded OK\n",i); return SRSLTE_SUCCESS; } else { From 69bfd114c5afc5ef2438047318751a8d4ffba8c3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 20 Dec 2016 13:29:17 +0100 Subject: [PATCH 088/111] fixed incorrect allowed UL DFT sizes --- srslte/lib/dft/dft_precoding.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/srslte/lib/dft/dft_precoding.c b/srslte/lib/dft/dft_precoding.c index bb3753545..bc285d8f6 100644 --- a/srslte/lib/dft/dft_precoding.c +++ b/srslte/lib/dft/dft_precoding.c @@ -85,14 +85,16 @@ void srslte_dft_precoding_free(srslte_dft_precoding_t *q) bzero(q, sizeof(srslte_dft_precoding_t)); } +static bool valid_prb[101]={true,true,true,true,true,true,true,false,true,true,true,false,true,false,false,true,true,false,true,false,true,false,false,false, + true,true,false,true,false,false,true,false,true,false,false,false,true,false,false,false,true,false,false,false,false,true,false,false,true,false, + true,false,false,false,true,false,false,false,false,false,true,false,false,false,true,false,false,false,false,false,false,false,true,false,false,true, + false,false,false,false,true,true,false,false,false,false,false,false,false,false,true,false,false,false,false,false,true,false,false,false,true}; + bool srslte_dft_precoding_valid_prb(uint32_t nof_prb) { - if (nof_prb > 0 && - (nof_prb == 1 || (nof_prb%2) == 0 || (nof_prb%3) == 0 || (nof_prb%5) == 0)) - { - return true; - } else { - return false; + if (nof_prb <= 100) { + return valid_prb[nof_prb]; } + return false; } int srslte_dft_precoding(srslte_dft_precoding_t *q, cf_t *input, cf_t *output, From e9baebd0257f672206a6d098c321fbabedf8ddd0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 20 Dec 2016 13:32:44 +0100 Subject: [PATCH 089/111] added PUSCH TPC command to format0 --- srslte/lib/phch/dci.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index a8d0260e4..49351231a 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -445,14 +445,11 @@ int dci_format0_pack(srslte_ra_ul_dci_t *data, srslte_dci_msg_t *msg, uint32_t n *y++ = data->ndi; - // TCP commands not implemented - *y++ = 0; - *y++ = 0; + // TCP command + srslte_bit_unpack(data->tpc_pusch, &y, 2); // DM RS not implemented - *y++ = 0; - *y++ = 0; - *y++ = 0; + srslte_bit_unpack(data->n_dmrs, &y, 3); // CQI request *y++ = data->cqi_request; From 4cd69444185d29bc65c58a1d3175a0daed46e448 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 22 Dec 2016 01:09:08 +0100 Subject: [PATCH 090/111] added PUCCH TPC to format1 --- srslte/include/srslte/phch/ra.h | 4 +++- srslte/lib/phch/dci.c | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 176ccecf9..52e8764a9 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -132,6 +132,8 @@ typedef struct SRSLTE_API { bool pconf; bool power_offset; + uint8_t tpc_pucch; + uint32_t nof_tb; bool dci_is_1a; @@ -179,7 +181,7 @@ typedef struct SRSLTE_API { uint32_t n_dmrs; bool ndi; bool cqi_request; - uint32_t tpc_pusch; + uint8_t tpc_pusch; } srslte_ra_ul_dci_t; diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 49351231a..7699ae57d 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -445,7 +445,7 @@ int dci_format0_pack(srslte_ra_ul_dci_t *data, srslte_dci_msg_t *msg, uint32_t n *y++ = data->ndi; - // TCP command + // TCP command for PUSCH srslte_bit_unpack(data->tpc_pusch, &y, 2); // DM RS not implemented @@ -563,9 +563,8 @@ int dci_format1_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t n // rv version srslte_bit_unpack(data->rv_idx, &y, 2); - // TPC not implemented - *y++ = 0; - *y++ = 0; + // TCP command for PUCCH + srslte_bit_unpack(data->tpc_pucch, &y, 2); // Padding with zeros uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb); From 2985a68e91b883ddda7015ab6524cf18a3a8311b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 9 Jan 2017 17:15:36 +0100 Subject: [PATCH 091/111] Fixed bug in PUSCH channel estimation --- srslte/include/srslte/ue/ue_ul.h | 2 -- srslte/lib/ch_estimation/chest_ul.c | 30 ++++++++++++++++------------- srslte/lib/phch/pusch.c | 4 ++-- srslte/lib/phch/sch.c | 4 ++-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/srslte/include/srslte/ue/ue_ul.h b/srslte/include/srslte/ue/ue_ul.h index b0264a6e5..20642cdcc 100644 --- a/srslte/include/srslte/ue/ue_ul.h +++ b/srslte/include/srslte/ue/ue_ul.h @@ -51,8 +51,6 @@ #include "srslte/config.h" -#define SRSLTE_UE_UL_NOF_HARQ_PROCESSES 8 - /* UE UL power control */ typedef struct { // Common configuration diff --git a/srslte/lib/ch_estimation/chest_ul.c b/srslte/lib/ch_estimation/chest_ul.c index 75d816702..4366e865c 100644 --- a/srslte/lib/ch_estimation/chest_ul.c +++ b/srslte/lib/ch_estimation/chest_ul.c @@ -145,13 +145,13 @@ void srslte_chest_ul_set_cfg(srslte_chest_ul_t *q, } /* Uses the difference between the averaged and non-averaged pilot estimates */ -static float estimate_noise_pilots(srslte_chest_ul_t *q, cf_t *ce, uint32_t nrefs) +static float estimate_noise_pilots(srslte_chest_ul_t *q, cf_t *ce, uint32_t nrefs, uint32_t n_prb[2]) { float power = 0; for (int i=0;i<2;i++) { power += srslte_chest_estimate_noise_pilots(&q->pilot_estimates[i*nrefs], - &ce[SRSLTE_REFSIGNAL_UL_L(i, q->cell.cp)*q->cell.nof_prb*SRSLTE_NRE], + &ce[SRSLTE_REFSIGNAL_UL_L(i, q->cell.cp)*q->cell.nof_prb*SRSLTE_NRE+n_prb[i]*SRSLTE_NRE], q->tmp_noise, nrefs); } @@ -168,9 +168,9 @@ static float estimate_noise_pilots(srslte_chest_ul_t *q, cf_t *ce, uint32_t nref } } -#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)] - -static void interpolate_pilots(srslte_chest_ul_t *q, cf_t *ce, uint32_t nrefs) +// The interpolator currently only supports same frequency allocation for each subframe +#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,n_prb[0]*SRSLTE_NRE)] +static void interpolate_pilots(srslte_chest_ul_t *q, cf_t *ce, uint32_t nrefs, uint32_t n_prb[2]) { uint32_t L1 = SRSLTE_REFSIGNAL_UL_L(0, q->cell.cp); uint32_t L2 = SRSLTE_REFSIGNAL_UL_L(1, q->cell.cp); @@ -206,10 +206,10 @@ void srslte_chest_ul_set_smooth_filter3_coeff(srslte_chest_ul_t* q, float w) q->smooth_filter_len = 3; } -static void average_pilots(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, uint32_t nrefs) { +static void average_pilots(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, uint32_t nrefs, uint32_t n_prb[2]) { for (int i=0;i<2;i++) { srslte_chest_average_pilots(&input[i*nrefs], - &ce[SRSLTE_REFSIGNAL_UL_L(i, q->cell.cp)*q->cell.nof_prb*SRSLTE_NRE], + &ce[SRSLTE_REFSIGNAL_UL_L(i, q->cell.cp)*q->cell.nof_prb*SRSLTE_NRE+n_prb[i]*SRSLTE_NRE], q->smooth_filter, nrefs, 1, q->smooth_filter_len); } } @@ -237,21 +237,25 @@ int srslte_chest_ul_estimate(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->dmrs_pregen.r[cyclic_shift_for_dmrs][sf_idx][nof_prb], q->pilot_estimates, nrefs_sf); + if (n_prb[0] != n_prb[1]) { + printf("ERROR: intra-subframe frequency hopping not supported in the estimator!!\n"); + } + if (ce != NULL) { if (q->smooth_filter_len > 0) { - average_pilots(q, q->pilot_estimates, ce, nrefs_sym); - interpolate_pilots(q, ce, nrefs_sym); + average_pilots(q, q->pilot_estimates, ce, nrefs_sym, n_prb); + interpolate_pilots(q, ce, nrefs_sym, n_prb); /* If averaging, compute noise from difference between received and averaged estimates */ - q->noise_estimate = estimate_noise_pilots(q, ce, nrefs_sym); + q->noise_estimate = estimate_noise_pilots(q, ce, nrefs_sym, n_prb); } else { // Copy estimates to CE vector without averaging for (int i=0;i<2;i++) { - memcpy(&ce[SRSLTE_REFSIGNAL_UL_L(i, q->cell.cp)*q->cell.nof_prb*SRSLTE_NRE], + memcpy(&ce[SRSLTE_REFSIGNAL_UL_L(i, q->cell.cp)*q->cell.nof_prb*SRSLTE_NRE+n_prb[i]*SRSLTE_NRE], &q->pilot_estimates[i*nrefs_sym], - nrefs_sym*sizeof(cf_t)); + nrefs_sym*sizeof(cf_t)); } - interpolate_pilots(q, ce, nrefs_sym); + interpolate_pilots(q, ce, nrefs_sym, n_prb); q->noise_estimate = 0; } } diff --git a/srslte/lib/phch/pusch.c b/srslte/lib/phch/pusch.c index d1e9b6838..7f771159a 100644 --- a/srslte/lib/phch/pusch.c +++ b/srslte/lib/phch/pusch.c @@ -533,7 +533,7 @@ int srslte_pusch_decode(srslte_pusch_t *q, srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re); srslte_sequence_t *seq = NULL; - + // Create sequence if does not exist if (!q->users[rnti]) { seq = &q->tmp_seq; @@ -557,7 +557,7 @@ int srslte_pusch_decode(srslte_pusch_t *q, srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits); srslte_sequence_free(seq); } - + return srslte_ulsch_uci_decode(&q->ul_sch, cfg, softbuffer, q->q, q->g, data, uci_data); } else { return SRSLTE_ERROR_INVALID_INPUTS; diff --git a/srslte/lib/phch/sch.c b/srslte/lib/phch/sch.c index ad77035b8..3b521f794 100644 --- a/srslte/lib/phch/sch.c +++ b/srslte/lib/phch/sch.c @@ -463,7 +463,7 @@ static int decode_tb(srslte_sch_t *q, par_tx = ((uint32_t) parity[0])<<16 | ((uint32_t) parity[1])<<8 | ((uint32_t) parity[2]); if (!par_rx) { - INFO("Warning: Received all-zero transport block\n\n", 0); + INFO("Warning: Received all-zero transport block\n\n", 0); } if (par_rx == par_tx) { @@ -657,7 +657,7 @@ int srslte_ulsch_uci_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_sof } e_offset += Q_prime_cqi*Qm; - + // Decode ULSCH if (cfg->cb_segm.tbs > 0) { uint32_t G = nb_q/Qm - Q_prime_ri - Q_prime_cqi; From fe867af3198405c39bc5925bf7082835622f677a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 13 Jan 2017 12:59:09 +0100 Subject: [PATCH 092/111] Fixed bug in PUSCH and PUCCH decoding --- matlab/tests/pucch_bler.m | 11 +++++---- srslte/include/srslte/phch/pucch.h | 2 ++ srslte/lib/ch_estimation/chest_ul.c | 2 +- srslte/lib/ch_estimation/refsignal_ul.c | 2 ++ srslte/lib/enb/enb_ul.c | 6 +---- srslte/lib/phch/pucch.c | 31 +++++++++++++++++++++---- srslte/lib/phch/pusch.c | 1 - 7 files changed, 38 insertions(+), 17 deletions(-) diff --git a/matlab/tests/pucch_bler.m b/matlab/tests/pucch_bler.m index 4bac59411..7ab269497 100644 --- a/matlab/tests/pucch_bler.m +++ b/matlab/tests/pucch_bler.m @@ -1,15 +1,16 @@ clear -ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',25,'NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off'); -pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',2); +ueConfig=struct('NCellID',1,'RNTI',46,'NULRB',25,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off'); +pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0); format_str={'1','1a'}; threshold=[0.5 0]; -formats=[1]; +formats=1; pucchConfig.ResourceIdx= 0; -pucchConfig.DeltaShift = 1; +pucchConfig.DeltaShift = 2; pucchConfig.CyclicShifts = 0; -ueConfig.NSubframe=0; +pucchConfig.ResourceSize=2; +ueConfig.NSubframe=9; enable_fading=false; diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index f99ecfe51..2ed0743b4 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -102,6 +102,8 @@ typedef struct SRSLTE_API { float threshold_format1; float threshold_format1a; float last_corr; + uint32_t last_n_prb; + uint32_t last_n_pucch; }srslte_pucch_t; diff --git a/srslte/lib/ch_estimation/chest_ul.c b/srslte/lib/ch_estimation/chest_ul.c index 4366e865c..7e558c2d0 100644 --- a/srslte/lib/ch_estimation/chest_ul.c +++ b/srslte/lib/ch_estimation/chest_ul.c @@ -289,7 +289,7 @@ int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, /* Use the known DMRS signal to compute Least-squares estimates */ srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates, nrefs_sf); - + if (ce != NULL) { /* FIXME: Currently averaging entire slot, performance good enough? */ for (int ns=0;ns<2;ns++) { diff --git a/srslte/lib/ch_estimation/refsignal_ul.c b/srslte/lib/ch_estimation/refsignal_ul.c index e2316e1dd..143bf53f4 100644 --- a/srslte/lib/ch_estimation/refsignal_ul.c +++ b/srslte/lib/ch_estimation/refsignal_ul.c @@ -237,6 +237,8 @@ void srslte_refsignal_ul_set_cfg(srslte_refsignal_ul_t *q, if (pucch_cfg) { if (srslte_pucch_cfg_isvalid(pucch_cfg, q->cell.nof_prb)) { memcpy(&q->pucch_cfg, pucch_cfg, sizeof(srslte_pucch_cfg_t)); + } else { + fprintf(stderr, "Invalid PUCCH configuration in refsignal_ul\n"); } } if (srs_cfg) { diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index f966cd508..d41bfc245 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -259,11 +259,7 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti, // Save ACK bits if (uci_data->uci_ack_len > 0) { - if (ret_val > 0) { - uci_data->uci_ack = bits[0]; - } else { - uci_data->uci_ack = 0; - } + uci_data->uci_ack = bits[0]; } return SRSLTE_SUCCESS; } else { diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index 6beb4afc4..9472711bb 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -67,7 +67,7 @@ float w_n_oc[2][3][4] = { bool srslte_pucch_cfg_isvalid(srslte_pucch_cfg_t *cfg, uint32_t nof_prb) { if (cfg->delta_pucch_shift > 0 && cfg->delta_pucch_shift < 4 && cfg->N_cs < 8 && (cfg->N_cs%cfg->delta_pucch_shift) == 0 && - cfg->n_rb_2 < nof_prb) { + cfg->n_rb_2 <= nof_prb) { return true; } else { return false; @@ -377,7 +377,7 @@ static int pucch_cp(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n_ // Determine n_prb uint32_t n_prb = srslte_pucch_n_prb(&q->pucch_cfg, format, n_pucch, q->cell.nof_prb, q->cell.cp, ns); - + q->last_n_prb = n_prb; if (n_prb < q->cell.nof_prb) { for (uint32_t i=0;icell.cp); @@ -654,6 +654,8 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, } } + q->last_n_pucch = n_pucch; + if (format >= SRSLTE_PUCCH_FORMAT_2 && !q->rnti_is_set) { fprintf(stderr, "Error encoding PUCCH: C-RNTI must be set before encoding PUCCH Format 2/2a/2b\n"); return SRSLTE_ERROR; @@ -700,6 +702,8 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, } } + q->last_n_pucch = n_pucch; + if (format >= SRSLTE_PUCCH_FORMAT_2 && !q->rnti_is_set) { fprintf(stderr, "Error decoding PUCCH: C-RNTI must be set before encoding PUCCH Format 2/2a/2b\n"); return SRSLTE_ERROR; @@ -731,6 +735,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, } else { ret = 0; } + q->last_corr = corr; DEBUG("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, q->threshold_format1); break; case SRSLTE_PUCCH_FORMAT_1A: @@ -740,15 +745,32 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, bits[0] = b; pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; - if (corr > corr_max && corr >= q->threshold_format1a) { + if (corr > corr_max) { corr_max = corr; b_max = b; } - if (corr_max > q->threshold_format1a) { + if (corr_max > q->threshold_format1) { // check with format1 in case ack+sr because ack only is binary ret = 1; } DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a); } + q->last_corr = corr_max; + +/* + if (corr_max < 0.01) { + srslte_vec_save_file("sf_symbols", sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); + srslte_vec_save_file("sf_ce", ce, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); + srslte_vec_save_file("ce", q->ce, sizeof(cf_t)*nof_re); + srslte_vec_save_file("z_before", zz, sizeof(cf_t)*nof_re); + srslte_vec_save_file("z_eq", q->z, sizeof(cf_t)*nof_re); + srslte_vec_save_file("z_1", q->z_tmp, sizeof(cf_t)*nof_re); + bits[0] = 0; + pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); + srslte_vec_save_file("z_0", q->z_tmp, sizeof(cf_t)*nof_re); + printf("corr_max=%f, b_max=%d, n_pucch=%d, n_prb=%d, sf_idx=%d, nof_re=%d, noise_estimate=%f\n", corr_max, b_max, n_pucch, q->last_n_prb, sf_idx, nof_re, noise_estimate); + exit(-1); + } +*/ bits[0] = b_max; break; default: @@ -756,7 +778,6 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, ret = SRSLTE_ERROR; break; } - q->last_corr = corr; } return ret; diff --git a/srslte/lib/phch/pusch.c b/srslte/lib/phch/pusch.c index 7f771159a..f82173f54 100644 --- a/srslte/lib/phch/pusch.c +++ b/srslte/lib/phch/pusch.c @@ -554,7 +554,6 @@ int srslte_pusch_decode(srslte_pusch_t *q, srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits); if (!q->users[rnti]) { - srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits); srslte_sequence_free(seq); } From 2644031ac8258528344d380e815aee75e291e0f3 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 16 Jan 2017 16:23:10 +0000 Subject: [PATCH 093/111] Adding option to statically link MKL --- CMakeLists.txt | 3 ++- cmake/modules/FindMKL.cmake | 32 ++++++++++++++++++++++++++------ srslte/lib/CMakeLists.txt | 15 +++++++++++---- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fec7856b9..86df46c34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ configure_file( # Options ######################################################################## option(DisableMEX "DisableMEX" ON) +option(StaticMKL "StaticMKL" OFF) ######################################################################## # Install Dirs @@ -98,7 +99,7 @@ endif(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE -g") - + if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") find_package(SSE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") diff --git a/cmake/modules/FindMKL.cmake b/cmake/modules/FindMKL.cmake index 2320cf065..ef9d53379 100644 --- a/cmake/modules/FindMKL.cmake +++ b/cmake/modules/FindMKL.cmake @@ -5,23 +5,43 @@ # MKL_LIBRARIES - The libraries needed to use mkl # MKL_DEFINITIONS - Compiler switches required for using mkl -find_path(MKL_INCLUDE_DIR +find_path(MKL_INCLUDE_DIRS NAMES mkl.h HINTS $ENV{MKL_DIR}/include PATHS) -find_library(MKL_LIBRARY +find_library(MKL_LIBRARIES NAMES mkl_rt HINTS $ENV{MKL_DIR}/lib/intel64 PATHS) -set(MKL_LIBRARIES ${MKL_LIBRARY} ) -set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR} ) +find_library(MKL_CORE + NAMES libmkl_core.a + HINTS $ENV{MKL_DIR}/lib/intel64 + PATHS) + +find_library(MKL_ILP + NAMES libmkl_intel_ilp64.a + HINTS $ENV{MKL_DIR}/lib/intel64 + PATHS) + +find_library(MKL_SEQ + NAMES libmkl_sequential.a + HINTS $ENV{MKL_DIR}/lib/intel64 + PATHS) + +set(MKL_STATIC_LIBRARIES -Wl,--start-group ${MKL_CORE} ${MKL_ILP} ${MKL_SEQ} -Wl,--end-group -lpthread -lm -ldl) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args(mkl DEFAULT_MSG - MKL_LIBRARY MKL_INCLUDE_DIR) + MKL_LIBRARIES MKL_CORE MKL_ILP MKL_SEQ MKL_INCLUDE_DIRS) + +if(MKL_FOUND) + MESSAGE(STATUS "Found MKL_INCLUDE_DIRS: ${MKL_INCLUDE_DIRS}" ) + MESSAGE(STATUS "Found MKL_LIBRARIES: ${MKL_LIBRARIES}" ) + MESSAGE(STATUS "Found MKL_STATIC_LIBRARIES: ${MKL_STATIC_LIBRARIES}" ) +endif(MKL_FOUND) -mark_as_advanced(MKL_INCLUDE_DIR MKL_LIBRARY ) +mark_as_advanced(MKL_INCLUDE_DIRS MKL_LIBRARIES MKL_CORE MKL_ILP MKL_SEQ) diff --git a/srslte/lib/CMakeLists.txt b/srslte/lib/CMakeLists.txt index 3a73d8761..6047ac78d 100644 --- a/srslte/lib/CMakeLists.txt +++ b/srslte/lib/CMakeLists.txt @@ -69,10 +69,17 @@ if(NOT DisableMEX) endif(NOT DisableMEX) if(MKL_FOUND) - target_link_libraries(srslte ${MKL_LIBRARIES}) - if(NOT DisableMEX) - target_link_libraries(srslte_static ${MKL_LIBRARIES}) - endif(NOT DisableMEX) + if(StaticMKL) + target_link_libraries(srslte ${MKL_STATIC_LIBRARIES}) + if(NOT DisableMEX) + target_link_libraries(srslte_static ${MKL_STATIC_LIBRARIES}) + endif(NOT DisableMEX) + else(StaticMKL) + target_link_libraries(srslte ${MKL_LIBRARIES}) + if(NOT DisableMEX) + target_link_libraries(srslte_static ${MKL_LIBRARIES}) + endif(NOT DisableMEX) + endif(StaticMKL) else(MKL_FOUND) target_link_libraries(srslte ${FFTW3F_LIBRARIES}) if(NOT DisableMEX) From e43bdd55079faef532bd110031d47ba6fc75a31a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 01:06:28 +0100 Subject: [PATCH 094/111] some fixes in cmake. added option to disable bladerf --- CMakeLists.txt | 13 +++++++------ srslte/CMakeLists.txt | 12 +++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86df46c34..5ba4bf2c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,8 +51,9 @@ configure_file( ######################################################################## # Options ######################################################################## -option(DisableMEX "DisableMEX" ON) -option(StaticMKL "StaticMKL" OFF) +option(DisableMEX "DisableMEX" ON) +option(StaticMKL "StaticMKL" OFF) +option(DisableBladeRF "DisableBladeRF" OFF) ######################################################################## # Install Dirs @@ -102,14 +103,14 @@ if(CMAKE_COMPILER_IS_GNUCC) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") find_package(SSE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") if(HAVE_AVX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") elseif(HAVE_SSE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfpmath=sse -msse4.1 -DLV_HAVE_SSE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -DLV_HAVE_SSE") endif(HAVE_AVX) else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") find_package(SSE) if(HAVE_AVX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") diff --git a/srslte/CMakeLists.txt b/srslte/CMakeLists.txt index 0ecf9ddf6..d4f336d57 100644 --- a/srslte/CMakeLists.txt +++ b/srslte/CMakeLists.txt @@ -61,11 +61,13 @@ if(UHD_FOUND) link_directories(${UHD_LIBRARY_DIRS}) endif(UHD_FOUND) -find_package(bladeRF) -if(BLADERF_FOUND) - include_directories(${BLADERF_INCLUDE_DIRS}) - link_directories(${BLADERF_LIBRARY_DIRS}) -endif(BLADERF_FOUND) +if(NOT DisableBladeRF) + find_package(bladeRF) + if(BLADERF_FOUND) + include_directories(${BLADERF_INCLUDE_DIRS}) + link_directories(${BLADERF_LIBRARY_DIRS}) + endif(BLADERF_FOUND) +endif(NOT DisableBladeRF) if(BLADERF_FOUND OR UHD_FOUND) set(RF_FOUND TRUE CACHE INTERNAL "RF frontend found") From 3ea68a1ad78f8dba5e7e0525296d14a03e17c2cb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 16:03:06 +0100 Subject: [PATCH 095/111] make srslte_rf a shared library instead of an object --- srslte/lib/CMakeLists.txt | 8 ++++---- srslte/lib/rf/CMakeLists.txt | 13 +++++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/srslte/lib/CMakeLists.txt b/srslte/lib/CMakeLists.txt index 6047ac78d..88431bcde 100644 --- a/srslte/lib/CMakeLists.txt +++ b/srslte/lib/CMakeLists.txt @@ -55,10 +55,6 @@ set(srslte_srcs version.c $ ) -if(RF_FOUND) - list(APPEND srslte_srcs $) -endif(RF_FOUND) - add_library(srslte SHARED ${srslte_srcs}) target_link_libraries(srslte pthread m) set_target_properties(srslte PROPERTIES @@ -87,7 +83,11 @@ else(MKL_FOUND) endif(NOT DisableMEX) endif(MKL_FOUND) +## This linkage is required for the examples and tests only if(RF_FOUND) + + target_link_libraries(srslte srslte_rf) + if(UHD_FOUND) target_link_libraries(srslte ${UHD_LIBRARIES}) endif(UHD_FOUND) diff --git a/srslte/lib/rf/CMakeLists.txt b/srslte/lib/rf/CMakeLists.txt index 3b97dfecf..00e4dd6a4 100644 --- a/srslte/lib/rf/CMakeLists.txt +++ b/srslte/lib/rf/CMakeLists.txt @@ -33,6 +33,15 @@ if(RF_FOUND) list(APPEND SOURCES_RF rf_blade_imp.c) endif (BLADERF_FOUND) - add_library(srslte_rf OBJECT ${SOURCES_RF}) + add_library(srslte_rf SHARED ${SOURCES_RF}) + + if (UHD_FOUND) + target_link_libraries(srslte_rf ${UHD_LIBRARIES}) + endif (UHD_FOUND) + + if (BLADERF_FOUND) + target_link_libraries(srslte_rf ${BLADERF_LIBRARIES}) + endif (BLADERF_FOUND) + SRSLTE_SET_PIC(srslte_rf) -endif(RF_FOUND) +endif(RF_FOUND) \ No newline at end of file From ef01150982d03395e867860d2ca9672853225b1d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 18:13:11 +0100 Subject: [PATCH 096/111] remove sse math in compiler options in libsrslte_rf.so --- srslte/lib/rf/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srslte/lib/rf/CMakeLists.txt b/srslte/lib/rf/CMakeLists.txt index 00e4dd6a4..d49ceea1f 100644 --- a/srslte/lib/rf/CMakeLists.txt +++ b/srslte/lib/rf/CMakeLists.txt @@ -33,8 +33,10 @@ if(RF_FOUND) list(APPEND SOURCES_RF rf_blade_imp.c) endif (BLADERF_FOUND) + add_compile_options(-march=native -mfpmath=sse -mno-avx -msse4.1) add_library(srslte_rf SHARED ${SOURCES_RF}) - + + if (UHD_FOUND) target_link_libraries(srslte_rf ${UHD_LIBRARIES}) endif (UHD_FOUND) From 49a2a749a166d8d788dc29965b466bd15df26019 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 18:30:45 +0100 Subject: [PATCH 097/111] added more compiler flags. Added option for avx2 --- CMakeLists.txt | 15 ++++++++++----- cmake/modules/FindSSE.cmake | 27 ++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ba4bf2c6..fd3f0a396 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,11 +112,16 @@ if(CMAKE_COMPILER_IS_GNUCC) else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") find_package(SSE) - if(HAVE_AVX) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") - elseif(HAVE_SSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -DLV_HAVE_SSE") - endif(HAVE_AVX) + if (HAVE_AVX2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx2 -Ofast -flto -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") + elseif (HAVE_AVX2) + if(HAVE_AVX) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -Ofast -flto -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") + elseif(HAVE_SSE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -Ofast -flto -funroll-loops -DLV_HAVE_SSE") + endif(HAVE_AVX) + endif (HAVE_AVX2) + endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake index 8647e9413..36be09ea4 100644 --- a/cmake/modules/FindSSE.cmake +++ b/cmake/modules/FindSSE.cmake @@ -6,6 +6,7 @@ include(CheckCSourceRuns) option(ENABLE_SSE "Enable compile-time SSE4.1 support." ON) option(ENABLE_AVX "Enable compile-time AVX support." ON) +option(ENABLE_AVX2 "Enable compile-time AVX2 support." ON) if (ENABLE_SSE) # @@ -52,7 +53,31 @@ if (ENABLE_SSE) message(STATUS "AVX is enabled - target CPU must support it") endif() endif() + + if (ENABLE_AVX2) + + # + # Check compiler for AVX intrinsics + # + if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG ) + set(CMAKE_REQUIRED_FLAGS "-mavx2") + check_c_source_runs(" + #include + + int main() + { + __m256i a = _mm256_setzero_si256(); + __m256i b = _mm256_abs_epi16(a); + return 0; + }" + HAVE_AVX2) + endif() + + if (HAVE_AVX2) + message(STATUS "AVX2 is enabled - target CPU must support it") + endif() + endif() endif() -mark_as_advanced(HAVE_SSE, HAVE_AVX) \ No newline at end of file +mark_as_advanced(HAVE_SSE, HAVE_AVX, HAVE_AVX2) \ No newline at end of file From 9eca0027890be875420986f467d89beb7da4a9b3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 19:01:03 +0100 Subject: [PATCH 098/111] harq PID len in dci global symbol --- srslte/lib/phch/dci.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 7699ae57d..49bf8681c 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -41,6 +41,10 @@ #include "dci_sz_table.h" + +int harq_pid_len = 3; + + /* Unpacks a DCI message and configures the DL grant object */ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, @@ -556,7 +560,7 @@ int dci_format1_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t n srslte_bit_unpack(data->mcs_idx, &y, 5); /* harq process number */ - srslte_bit_unpack(data->harq_process, &y, 3); + srslte_bit_unpack(data->harq_process, &y, harq_pid_len); *y++ = data->ndi; @@ -615,7 +619,7 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t data->mcs_idx = srslte_bit_pack(&y, 5); /* harq process number */ - data->harq_process = srslte_bit_pack(&y, 3); + data->harq_process = srslte_bit_pack(&y, harq_pid_len); data->ndi = *y++ ? true : false; // rv version @@ -687,7 +691,7 @@ int dci_format1As_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t // in format1A, MCS = TBS according to 7.1.7.2 of 36.213 srslte_bit_unpack(data->mcs_idx, &y, 5); - srslte_bit_unpack(data->harq_process, &y, 3); + srslte_bit_unpack(data->harq_process, &y, harq_pid_len); if (crc_is_crnti) { if (nof_prb >= 50 && data->type2_alloc.mode == SRSLTE_RA_TYPE2_DIST) { @@ -788,7 +792,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 // unpack MCS data->mcs_idx = srslte_bit_pack(&y, 5); - data->harq_process = srslte_bit_pack(&y, 3); + data->harq_process = srslte_bit_pack(&y, harq_pid_len); if (!crc_is_crnti) { if (nof_prb >= 50 && data->type2_alloc.mode == SRSLTE_RA_TYPE2_DIST) { @@ -848,7 +852,7 @@ int dci_format1B_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ // unpack MCS, Harq pid and ndi data->mcs_idx = srslte_bit_pack(&y, 5); - data->harq_process = srslte_bit_pack(&y, 3); + data->harq_process = srslte_bit_pack(&y, harq_pid_len); data->ndi = *y++ ? true : false; data->rv_idx = srslte_bit_pack(&y, 2); @@ -989,7 +993,7 @@ int dci_format1D_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ // unpack MCS, Harq pid and ndi data->mcs_idx = srslte_bit_pack(&y, 5); - data->harq_process = srslte_bit_pack(&y, 3); + data->harq_process = srslte_bit_pack(&y, harq_pid_len); data->ndi = *y++ ? true : false; data->rv_idx = srslte_bit_pack(&y, 2); @@ -1038,7 +1042,7 @@ int dci_format2AB_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 y+=2; /* harq process number */ - data->harq_process = srslte_bit_pack(&y, 3); + data->harq_process = srslte_bit_pack(&y, harq_pid_len); // Transpor block to codeword swap flag if (msg->format == SRSLTE_DCI_FORMAT2B) { From b1951ec8505d2a2d0063e2d35bfd30754b0f4759 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 19:28:13 +0100 Subject: [PATCH 099/111] fixed failing tests due to compiler flag --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd3f0a396..57e876c63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,12 +113,12 @@ if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") find_package(SSE) if (HAVE_AVX2) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx2 -Ofast -flto -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx2 -Ofast -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") elseif (HAVE_AVX2) if(HAVE_AVX) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -Ofast -flto -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -Ofast -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") elseif(HAVE_SSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -Ofast -flto -funroll-loops -DLV_HAVE_SSE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -Ofast -funroll-loops -DLV_HAVE_SSE") endif(HAVE_AVX) endif (HAVE_AVX2) From 603639399cf828287c44b208a0cf6c4e2c153d45 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 19:38:05 +0100 Subject: [PATCH 100/111] fixed flexible harq pid len --- srslte/include/srslte/phch/dci.h | 2 ++ srslte/lib/phch/dci.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/include/srslte/phch/dci.h b/srslte/include/srslte/phch/dci.h index b8e590516..dcc8cf215 100644 --- a/srslte/include/srslte/phch/dci.h +++ b/srslte/include/srslte/phch/dci.h @@ -47,6 +47,8 @@ #define SRSLTE_RAR_GRANT_LEN 20 +SRSLTE_API extern int harq_pid_len; + typedef enum { SRSLTE_DCI_FORMAT0 = 0, SRSLTE_DCI_FORMAT1, diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 49bf8681c..d3511bcdf 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -41,10 +41,8 @@ #include "dci_sz_table.h" - int harq_pid_len = 3; - /* Unpacks a DCI message and configures the DL grant object */ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti, From 4e226675393b14754b29466acbb591cd7ca9b3ba Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jan 2017 20:06:02 +0100 Subject: [PATCH 101/111] changed dci sizes computation from lut to function --- srslte/lib/phch/dci.c | 32 ++++++++++++++++---------------- srslte/lib/phch/pdcch.c | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index d3511bcdf..d4f0cd6b0 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -242,7 +242,7 @@ uint32_t dci_format0_sizeof_(uint32_t nof_prb) { uint32_t dci_format1A_sizeof(uint32_t nof_prb) { uint32_t n; - n = 1 + 1 + riv_nbits(nof_prb) + 5 + 3 + 1 + 2 + 2; + n = 1 + 1 + riv_nbits(nof_prb) + 5 + harq_pid_len + 1 + 2 + 2; while (n < dci_format0_sizeof_(nof_prb)) { n++; } @@ -262,7 +262,7 @@ uint32_t dci_format0_sizeof(uint32_t nof_prb) { uint32_t dci_format1_sizeof(uint32_t nof_prb) { - uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb)) + 5 + 3 + 1 + 2 + uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb)) + 5 + harq_pid_len + 1 + 2 + 2; if (nof_prb > 10) { n++; @@ -318,7 +318,7 @@ uint32_t precoding_bits_f2(uint32_t nof_ports) { } uint32_t dci_format2_sizeof(uint32_t nof_prb, uint32_t nof_ports) { - uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb))+2+3+1+2*(5+1+2)+precoding_bits_f2(nof_ports); + uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb))+2+harq_pid_len+1+2*(5+1+2)+precoding_bits_f2(nof_ports); if (nof_prb > 10) { n++; } @@ -338,7 +338,7 @@ uint32_t precoding_bits_f2a(uint32_t nof_ports) { } uint32_t dci_format2A_sizeof(uint32_t nof_prb, uint32_t nof_ports) { - uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb))+2+3+1+2*(5+1+2)+precoding_bits_f2a(nof_ports); + uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb))+2+harq_pid_len+1+2*(5+1+2)+precoding_bits_f2a(nof_ports); if (nof_prb > 10) { n++; } @@ -350,7 +350,7 @@ uint32_t dci_format2A_sizeof(uint32_t nof_prb, uint32_t nof_ports) { } uint32_t dci_format2B_sizeof(uint32_t nof_prb, uint32_t nof_ports) { - uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb))+2+3+1+2*(5+1+2); + uint32_t n = (uint32_t) ceilf((float) nof_prb / srslte_ra_type0_P(nof_prb))+2+harq_pid_len+1+2*(5+1+2); if (nof_prb > 10) { n++; } @@ -457,7 +457,7 @@ int dci_format0_pack(srslte_ra_ul_dci_t *data, srslte_dci_msg_t *msg, uint32_t n *y++ = data->cqi_request; // Padding with zeros - uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT0, nof_prb); + uint32_t n = srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT0, nof_prb, 1); while (y - msg->data < n) { *y++ = 0; } @@ -476,7 +476,7 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t uint32_t n_ul_hop; /* Make sure it's a SRSLTE_DCI_FORMAT0 message */ - if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT0, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT0, nof_prb, 1)) { fprintf(stderr, "Invalid message length for format 0\n"); return SRSLTE_ERROR; } @@ -569,7 +569,7 @@ int dci_format1_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t n srslte_bit_unpack(data->tpc_pucch, &y, 2); // Padding with zeros - uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb); + uint32_t n = srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb, 1); while (y - msg->data < n) { *y++ = 0; } @@ -584,7 +584,7 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t uint8_t *y = msg->data; /* Make sure it's a SRSLTE_DCI_FORMAT1 message */ - if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb, 1)) { fprintf(stderr, "Invalid message length for format 1\n"); return SRSLTE_ERROR; } @@ -714,7 +714,7 @@ int dci_format1As_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t } // Padding with zeros - uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb); + uint32_t n = srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1A, nof_prb, 1); while (y - msg->data < n) { *y++ = 0; } @@ -733,7 +733,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 uint8_t *y = msg->data; /* Make sure it's a SRSLTE_DCI_FORMAT0 message */ - if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1A, nof_prb, 1)) { fprintf(stderr, "Invalid message length for format 1A\n"); return SRSLTE_ERROR; } @@ -926,7 +926,7 @@ int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 /* pack bits */ uint8_t *y = msg->data; - if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1C, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1C, nof_prb, 1)) { fprintf(stderr, "Invalid message length for format 1C\n"); return SRSLTE_ERROR; } @@ -1204,16 +1204,16 @@ int srslte_dci_msg_get_type(srslte_dci_msg_t *msg, srslte_dci_msg_type_t *type, uint16_t msg_rnti) { DEBUG("Get message type: nof_bits=%d, msg_rnti=0x%x\n", msg->nof_bits, msg_rnti); - if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT0, nof_prb) + if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT0, nof_prb, 1) && !msg->data[0]) { type->type = SRSLTE_DCI_MSG_TYPE_PUSCH_SCHED; type->format = SRSLTE_DCI_FORMAT0; return SRSLTE_SUCCESS; - } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb, 1)) { type->type = SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED; // only these 2 types supported type->format = SRSLTE_DCI_FORMAT1; return SRSLTE_SUCCESS; - } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1A, nof_prb, 1)) { /* The RNTI is not the only condition. Also some fields in the packet. * if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) { type->type = SRSLTE_DCI_MSG_TYPE_RA_PROC_PDCCH; @@ -1224,7 +1224,7 @@ int srslte_dci_msg_get_type(srslte_dci_msg_t *msg, srslte_dci_msg_type_t *type, type->format = SRSLTE_DCI_FORMAT1A; //} return SRSLTE_SUCCESS; - } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1C, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1C, nof_prb, 1)) { if (msg_rnti == SRSLTE_MRNTI) { type->type = SRSLTE_DCI_MSG_TYPE_MCCH_CHANGE; type->format = SRSLTE_DCI_FORMAT1C; diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 8fca3d91d..9cf610c01 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -340,7 +340,7 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, } else { ret = SRSLTE_SUCCESS; - uint32_t nof_bits = srslte_dci_format_sizeof_lut(format, q->cell.nof_prb); + uint32_t nof_bits = srslte_dci_format_sizeof(format, q->cell.nof_prb, q->cell.nof_ports); uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L); double mean = 0; From 50567ade691673ace26de5fb44eb5079c30a8e2f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 20 Jan 2017 10:42:50 +0100 Subject: [PATCH 102/111] added install target for srslte_rf --- srslte/lib/rf/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/srslte/lib/rf/CMakeLists.txt b/srslte/lib/rf/CMakeLists.txt index d49ceea1f..ae98aaedf 100644 --- a/srslte/lib/rf/CMakeLists.txt +++ b/srslte/lib/rf/CMakeLists.txt @@ -45,5 +45,6 @@ if(RF_FOUND) target_link_libraries(srslte_rf ${BLADERF_LIBRARIES}) endif (BLADERF_FOUND) + INSTALL(TARGETS srslte_rf DESTINATION ${LIBRARY_DIR}) SRSLTE_SET_PIC(srslte_rf) endif(RF_FOUND) \ No newline at end of file From 1cef7818e7d2f52d8d7334d398456d2be151279e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 20 Jan 2017 11:55:20 +0100 Subject: [PATCH 103/111] typo in avx2 check --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57e876c63..206139295 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,8 +114,10 @@ if(CMAKE_COMPILER_IS_GNUCC) find_package(SSE) if (HAVE_AVX2) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx2 -Ofast -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") - elseif (HAVE_AVX2) + else (HAVE_AVX2) + message("NOT HAVE AVX2") if(HAVE_AVX) + message("HAVE AVX") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -Ofast -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") elseif(HAVE_SSE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -Ofast -funroll-loops -DLV_HAVE_SSE") From bd77f2d360ce0bc76a8d6516df1aaeb98f93c211 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 20 Jan 2017 11:56:31 +0100 Subject: [PATCH 104/111] typo in avx2 check --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 206139295..ae8e9c532 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,9 +115,7 @@ if(CMAKE_COMPILER_IS_GNUCC) if (HAVE_AVX2) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx2 -Ofast -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") else (HAVE_AVX2) - message("NOT HAVE AVX2") if(HAVE_AVX) - message("HAVE AVX") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -Ofast -funroll-loops -DLV_HAVE_AVX -DLV_HAVE_SSE") elseif(HAVE_SSE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -Ofast -funroll-loops -DLV_HAVE_SSE") From 9114441fbfeda85abc432cf1749057ac797a4bc9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 22 Jan 2017 14:16:10 +0100 Subject: [PATCH 105/111] fixed test for avx2 in cmake --- cmake/modules/FindSSE.cmake | 65 ++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake index 36be09ea4..89c7d8c19 100644 --- a/cmake/modules/FindSSE.cmake +++ b/cmake/modules/FindSSE.cmake @@ -40,11 +40,21 @@ if (ENABLE_SSE) set(CMAKE_REQUIRED_FLAGS "-mavx") check_c_source_runs(" #include - int main() { - __m256i a = _mm256_setzero_si256(); - return 0; + __m256 a, b, c; + const float src[8] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; + float dst[8]; + a = _mm256_loadu_ps( src ); + b = _mm256_loadu_ps( src ); + c = _mm256_add_ps( a, b ); + _mm256_storeu_ps( dst, c ); + for( int i = 0; i < 8; i++ ){ + if( ( src[i] + src[i] ) != dst[i] ){ + return -1; + } + } + return 0; }" HAVE_AVX) endif() @@ -54,29 +64,38 @@ if (ENABLE_SSE) endif() endif() - if (ENABLE_AVX2) + if (ENABLE_AVX2) - # - # Check compiler for AVX intrinsics - # - if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG ) - set(CMAKE_REQUIRED_FLAGS "-mavx2") - check_c_source_runs(" - #include - - int main() - { - __m256i a = _mm256_setzero_si256(); - __m256i b = _mm256_abs_epi16(a); + # + # Check compiler for AVX intrinsics + # + if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG ) + set(CMAKE_REQUIRED_FLAGS "-mavx2") + check_c_source_runs(" + #include + int main() + { + __m256i a, b, c; + const int src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + int dst[8]; + a = _mm256_loadu_si256( (__m256i*)src ); + b = _mm256_loadu_si256( (__m256i*)src ); + c = _mm256_add_epi32( a, b ); + _mm256_storeu_si256( (__m256i*)dst, c ); + for( int i = 0; i < 8; i++ ){ + if( ( src[i] + src[i] ) != dst[i] ){ + return -1; + } + } return 0; - }" - HAVE_AVX2) - endif() + }" + HAVE_AVX2) + endif() - if (HAVE_AVX2) - message(STATUS "AVX2 is enabled - target CPU must support it") - endif() - endif() + if (HAVE_AVX2) + message(STATUS "AVX2 is enabled - target CPU must support it") + endif() + endif() endif() From b2f889081fe60ddf90ab3e47f34aaa0c6d650b13 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 22 Jan 2017 14:26:54 +0100 Subject: [PATCH 106/111] fixed test for avx2 in cmake --- cmake/modules/FindSSE.cmake | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake index 89c7d8c19..7b258f70f 100644 --- a/cmake/modules/FindSSE.cmake +++ b/cmake/modules/FindSSE.cmake @@ -1,6 +1,3 @@ -if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|^i[3,9]86$") - return() -endif() include(CheckCSourceRuns) From 5615df0fee14eb85b7c9a54f1fbefcdddd414070 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 22 Jan 2017 14:38:43 +0100 Subject: [PATCH 107/111] fixed mem alignment in lut simd operation segfaulting in avx --- srslte/lib/utils/vector_simd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/lib/utils/vector_simd.c b/srslte/lib/utils/vector_simd.c index 1612f2c07..8fee71f21 100644 --- a/srslte/lib/utils/vector_simd.c +++ b/srslte/lib/utils/vector_simd.c @@ -223,8 +223,8 @@ void srslte_vec_lut_sss_simd(short *x, unsigned short *lut, short *y, uint32_t l __m128i xVal, lutVal; for(;number < points; number++){ - xVal = _mm_load_si128(xPtr); - lutVal = _mm_load_si128(lutPtr); + xVal = _mm_loadu_si128(xPtr); + lutVal = _mm_loadu_si128(lutPtr); for (int i=0;i<8;i++) { int16_t x = (int16_t) _mm_extract_epi16(xVal, i); From 808fc2db08b16dd1a3c41f4701183f76e8fbcc8a Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 25 Jan 2017 22:38:02 +0000 Subject: [PATCH 108/111] Adding fftw include path from mkl --- srslte/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/srslte/CMakeLists.txt b/srslte/CMakeLists.txt index d4f336d57..afb6060e7 100644 --- a/srslte/CMakeLists.txt +++ b/srslte/CMakeLists.txt @@ -46,6 +46,7 @@ add_custom_target (add_srslte_headers SOURCES ${HEADERS_ALL}) find_package(MKL) if(MKL_FOUND) include_directories(${MKL_INCLUDE_DIRS}) + include_directories(${MKL_INCLUDE_DIRS}/fftw) link_directories(${MKL_LIBRARY_DIRS}) else(MKL_FOUND) find_package(FFTW3F REQUIRED) From 9cbaad2c3a8efaafb43f1019e90c824158797049 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 26 Jan 2017 00:35:02 +0100 Subject: [PATCH 109/111] Check maximum EARFCN --- srslte/lib/common/phy_common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/srslte/lib/common/phy_common.c b/srslte/lib/common/phy_common.c index 68532ebeb..4717c6ca7 100644 --- a/srslte/lib/common/phy_common.c +++ b/srslte/lib/common/phy_common.c @@ -439,15 +439,21 @@ int srslte_band_get_band(uint32_t earfcn) { } float srslte_band_fd(uint32_t earfcn) { + if (earfcn > lte_bands[SRSLTE_NOF_LTE_BANDS-1].earfcn_max) { + return -1; + } uint32_t i = SRSLTE_NOF_LTE_BANDS-1; while(i > 0 && lte_bands[i].earfcn_offset>earfcn) { i--; } - return get_fd(<e_bands[i], earfcn); + return get_fd(<e_bands[i], earfcn); } float srslte_band_fu(uint32_t earfcn) { + if (earfcn > lte_bands[SRSLTE_NOF_LTE_BANDS-1].earfcn_max) { + return -1; + } uint32_t i = SRSLTE_NOF_LTE_BANDS-1; while(i > 0 && lte_bands[i].earfcn_offset>earfcn) { i--; From 0931518fa66fd999e030d0499a27ab31e6ffeef7 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Thu, 26 Jan 2017 09:46:57 +0000 Subject: [PATCH 110/111] Cleaner fix for MKL includes --- cmake/modules/FindMKL.cmake | 8 +++++++- srslte/CMakeLists.txt | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindMKL.cmake b/cmake/modules/FindMKL.cmake index ef9d53379..80adeafd7 100644 --- a/cmake/modules/FindMKL.cmake +++ b/cmake/modules/FindMKL.cmake @@ -5,11 +5,16 @@ # MKL_LIBRARIES - The libraries needed to use mkl # MKL_DEFINITIONS - Compiler switches required for using mkl -find_path(MKL_INCLUDE_DIRS +find_path(MKL_INCLUDE_DIR NAMES mkl.h HINTS $ENV{MKL_DIR}/include PATHS) +find_path(MKL_FFTW_INCLUDE_DIR + NAMES fftw3.h + HINTS $ENV{MKL_DIR}/include/fftw + PATHS) + find_library(MKL_LIBRARIES NAMES mkl_rt HINTS $ENV{MKL_DIR}/lib/intel64 @@ -31,6 +36,7 @@ find_library(MKL_SEQ PATHS) set(MKL_STATIC_LIBRARIES -Wl,--start-group ${MKL_CORE} ${MKL_ILP} ${MKL_SEQ} -Wl,--end-group -lpthread -lm -ldl) +set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR} ${MKL_FFTW_INCLUDE_DIR}) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE diff --git a/srslte/CMakeLists.txt b/srslte/CMakeLists.txt index afb6060e7..d4f336d57 100644 --- a/srslte/CMakeLists.txt +++ b/srslte/CMakeLists.txt @@ -46,7 +46,6 @@ add_custom_target (add_srslte_headers SOURCES ${HEADERS_ALL}) find_package(MKL) if(MKL_FOUND) include_directories(${MKL_INCLUDE_DIRS}) - include_directories(${MKL_INCLUDE_DIRS}/fftw) link_directories(${MKL_LIBRARY_DIRS}) else(MKL_FOUND) find_package(FFTW3F REQUIRED) From ac311690883e5c353f8d1708819be7250b88befb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 6 Feb 2017 21:04:55 +0100 Subject: [PATCH 111/111] Fixed number of codewords in format2 --- srslte/include/srslte/phch/ra.h | 3 ++- srslte/lib/phch/dci.c | 29 +++++++++++++++++--------- srslte/lib/phch/ra.c | 36 ++++++++++++++++++++++++--------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 52e8764a9..fb17703dd 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -106,6 +106,7 @@ typedef struct SRSLTE_API { uint32_t Qm2; srslte_ra_mcs_t mcs; srslte_ra_mcs_t mcs2; + uint32_t nof_tb; } srslte_ra_dl_grant_t; /** Unpacked DCI message for DL grant */ @@ -134,7 +135,7 @@ typedef struct SRSLTE_API { uint8_t tpc_pucch; - uint32_t nof_tb; + bool tb_en[2]; bool dci_is_1a; bool dci_is_1c; diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index d4f0cd6b0..194220507 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -625,7 +625,8 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t // TPC not implemented - data->nof_tb = 1; + data->tb_en[0] = true; + data->tb_en[1] = false; return SRSLTE_SUCCESS; } @@ -814,7 +815,8 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 data->type2_alloc.n_prb1a = *y++; // LSB indicates N_prb_1a for TBS } - data->nof_tb = 1; + data->tb_en[0] = true; + data->tb_en[1] = false; return SRSLTE_SUCCESS; } @@ -860,7 +862,8 @@ int dci_format1B_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ data->pinfo = srslte_bit_pack(&y, tpmi_bits(nof_ports)); data->pconf = *y++ ? true : false; - data->nof_tb = 1; + data->tb_en[0] = true; + data->tb_en[1] = false; return SRSLTE_SUCCESS; } @@ -955,7 +958,8 @@ int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 msg->nof_bits = (y - msg->data); - data->nof_tb = 1; + data->tb_en[0] = true; + data->tb_en[1] = false; return SRSLTE_SUCCESS; } @@ -1001,7 +1005,8 @@ int dci_format1D_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ data->pinfo = srslte_bit_pack(&y, tpmi_bits(nof_ports)); data->power_offset = *y++ ? true : false; - data->nof_tb = 1; + data->tb_en[0] = true; + data->tb_en[1] = false; return SRSLTE_SUCCESS; } @@ -1051,16 +1056,23 @@ int dci_format2AB_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 /* unpack MCS according to 7.1.7 of 36.213 */ data->mcs_idx = srslte_bit_pack(&y, 5); - data->ndi = *y++ ? true : false; - - // rv version data->rv_idx = srslte_bit_pack(&y, 2); + if (data->mcs_idx == 0 && data->rv_idx == 1) { + data->tb_en[0] = false; + } else { + data->tb_en[0] = true; + } // same for tb1 data->mcs_idx_1 = srslte_bit_pack(&y, 5); data->ndi_1 = *y++ ? true : false; data->rv_idx_1 = srslte_bit_pack(&y, 2); + if (data->mcs_idx_1 == 0 && data->rv_idx_1 == 1) { + data->tb_en[1] = false; + } else { + data->tb_en[1] = true; + } // Precoding information if (msg->format == SRSLTE_DCI_FORMAT2A) { @@ -1069,7 +1081,6 @@ int dci_format2AB_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 data->pinfo = srslte_bit_pack(&y, precoding_bits_f2a(nof_ports)); } - data->nof_tb = 2; return SRSLTE_SUCCESS; } diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index 9f5da581f..e830710f5 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -172,6 +172,7 @@ int srslte_ra_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ srslte_mod_t last_mod[8]; uint32_t last_ul_tbs_idx[8]; uint32_t last_dl_tbs[8]; +uint32_t last_dl_tbs2[8]; static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t harq_pid) { int tbs = -1; @@ -459,21 +460,38 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr grant->mcs.tbs = (uint32_t) tbs; } else { n_prb = grant->nof_prb; - grant->mcs.idx = dci->mcs_idx; - tbs = dl_fill_ra_mcs(&grant->mcs, n_prb); - if (tbs) { - last_dl_tbs[dci->harq_process%8] = tbs; + grant->nof_tb = 0; + if (dci->tb_en[0]) { + grant->mcs.idx = dci->mcs_idx; + tbs = dl_fill_ra_mcs(&grant->mcs, n_prb); + if (tbs) { + last_dl_tbs[dci->harq_process%8] = tbs; + } else { + // For mcs>=29, set last TBS received for this PID + grant->mcs.tbs = last_dl_tbs[dci->harq_process%8]; + } + grant->nof_tb++; } else { - // For mcs>=29, set last TBS received for this PID - grant->mcs.tbs = last_dl_tbs[dci->harq_process%8]; + grant->mcs.tbs = 0; } - if (dci->nof_tb == 2) { + if (dci->tb_en[1]) { grant->mcs2.idx = dci->mcs_idx_1; tbs = dl_fill_ra_mcs(&grant->mcs2, n_prb); + if (tbs) { + last_dl_tbs2[dci->harq_process%8] = tbs; + } else { + // For mcs>=29, set last TBS received for this PID + grant->mcs2.tbs = last_dl_tbs2[dci->harq_process%8]; + } + grant->nof_tb++; + } else { + grant->mcs2.tbs = 0; } } - grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); - if (dci->nof_tb == 2) { + if (dci->tb_en[0]) { + grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); + } + if (dci->tb_en[1]) { grant->Qm2 = srslte_mod_bits_x_symbol(grant->mcs2.mod); } if (tbs < 0) {