2019-04-26 12:27:38 -07:00
|
|
|
/*
|
|
|
|
* Copyright 2013-2019 Software Radio Systems Limited
|
2015-01-29 16:15:09 -08:00
|
|
|
*
|
2019-04-26 12:27:38 -07:00
|
|
|
* This file is part of srsLTE.
|
2015-01-29 16:15:09 -08:00
|
|
|
*
|
2015-03-20 05:01:08 -07:00
|
|
|
* srsLTE is free software: you can redistribute it and/or modify
|
2015-05-08 08:05:40 -07:00
|
|
|
* it under the terms of the GNU Affero General Public License as
|
2015-01-29 16:15:09 -08:00
|
|
|
* published by the Free Software Foundation, either version 3 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
2015-03-20 05:01:08 -07:00
|
|
|
* srsLTE is distributed in the hope that it will be useful,
|
2015-01-29 16:15:09 -08:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2015-05-08 08:05:40 -07:00
|
|
|
* GNU Affero General Public License for more details.
|
2015-01-29 16:15:09 -08:00
|
|
|
*
|
2015-05-08 08:05:40 -07:00
|
|
|
* A copy of the GNU Affero General Public License can be found in
|
2015-01-29 16:15:09 -08:00
|
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
#include "srslte/srslte.h"
|
|
|
|
#include <srslte/phy/phch/pusch_cfg.h>
|
2019-04-30 06:56:47 -07:00
|
|
|
#include <srslte/phy/utils/random.h>
|
2015-01-29 16:15:09 -08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/time.h>
|
2019-04-23 01:53:11 -07:00
|
|
|
#include <unistd.h>
|
2015-01-29 16:15:09 -08:00
|
|
|
|
2015-03-18 05:31:13 -07:00
|
|
|
#include "srslte/srslte.h"
|
2015-01-29 16:15:09 -08:00
|
|
|
|
2018-07-02 09:15:56 -07:00
|
|
|
static srslte_cell_t cell = {
|
2019-12-16 07:04:22 -08:00
|
|
|
.nof_prb = 6, // nof_prb
|
|
|
|
.nof_ports = 1, // nof_ports
|
|
|
|
.id = 0, // cell_id
|
|
|
|
.cp = SRSLTE_CP_NORM, // cyclic prefix
|
|
|
|
.phich_length = SRSLTE_PHICH_NORM, // PHICH length
|
2018-07-02 09:15:56 -07:00
|
|
|
.phich_resources = SRSLTE_PHICH_R_1_6 // PHICH resources
|
2018-05-14 01:45:04 -07:00
|
|
|
};
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
static srslte_uci_offset_cfg_t uci_cfg = {
|
2018-05-14 01:45:04 -07:00
|
|
|
.I_offset_cqi = 6,
|
2019-04-23 01:53:11 -07:00
|
|
|
.I_offset_ri = 2,
|
2018-05-14 01:45:04 -07:00
|
|
|
.I_offset_ack = 9,
|
|
|
|
};
|
|
|
|
|
2019-04-30 06:56:47 -07:00
|
|
|
static srslte_uci_data_t uci_data_tx = {};
|
2015-01-29 16:15:09 -08:00
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
uint32_t L_rb = 2;
|
2019-12-16 07:04:22 -08:00
|
|
|
uint32_t tbs = 0;
|
|
|
|
uint32_t subframe = 10;
|
|
|
|
srslte_mod_t modulation = SRSLTE_MOD_QPSK;
|
|
|
|
uint32_t rv_idx = 0;
|
|
|
|
int freq_hop = -1;
|
|
|
|
int riv = -1;
|
|
|
|
uint32_t mcs_idx = 0;
|
|
|
|
bool enable_64_qam = false;
|
|
|
|
|
|
|
|
void usage(char* prog)
|
|
|
|
{
|
2019-04-23 01:53:11 -07:00
|
|
|
printf("Usage: %s [csrnfvmtF] \n", prog);
|
2018-05-14 01:45:04 -07:00
|
|
|
printf("\n\tCell specific parameters:\n");
|
|
|
|
printf("\t\t-n number of PRB [Default %d]\n", cell.nof_prb);
|
|
|
|
printf("\t\t-c cell id [Default %d]\n", cell.id);
|
|
|
|
|
|
|
|
printf("\n\tGrant parameters:\n");
|
|
|
|
printf("\t\t-m MCS index (0-28) [Default %d]\n", mcs_idx);
|
|
|
|
printf("\t\t-F frequency hopping [Default %d]\n", freq_hop);
|
2019-04-23 01:53:11 -07:00
|
|
|
printf("\t\t-L L_rb [Default %d]\n", L_rb);
|
2018-05-14 01:45:04 -07:00
|
|
|
printf("\t\t-R RIV [Default %d]\n", riv);
|
|
|
|
printf("\t\t-r rv_idx (0-3) [Default %d]\n", rv_idx);
|
|
|
|
|
|
|
|
printf("\n\tCQI/RI/ACK Reporting indexes parameters:\n");
|
|
|
|
printf("\t\t-p I_offset_cqi (0-15) [Default %d]\n", uci_cfg.I_offset_cqi);
|
|
|
|
printf("\t\t-p I_offset_ri (0-15) [Default %d]\n", uci_cfg.I_offset_ri);
|
|
|
|
printf("\t\t-p I_offset_ack (0-15) [Default %d]\n", uci_cfg.I_offset_ack);
|
|
|
|
|
|
|
|
printf("\n\tCQI/RI/ACK Reporting contents:\n");
|
2019-04-23 01:53:11 -07:00
|
|
|
printf("\t\t-p cqi (none, wideband) [Default none]\n");
|
|
|
|
printf("\t\t-p ri (0-1) (zeros, ones, random) [Default none]\n");
|
2018-07-03 08:29:22 -07:00
|
|
|
printf("\t\t-p uci_ack [Default none]\n");
|
2018-05-14 01:45:04 -07:00
|
|
|
|
|
|
|
printf("\n\tOther parameters:\n");
|
2019-12-16 07:04:22 -08:00
|
|
|
printf("\t\t-p enable_64qam [Default %s]\n", enable_64_qam ? "enabled" : "disabled");
|
2018-07-02 09:15:56 -07:00
|
|
|
printf("\t\t-s number of subframes [Default %d]\n", subframe);
|
2015-03-18 11:14:24 -07:00
|
|
|
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
2015-01-29 16:15:09 -08:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
void parse_extensive_param(char* param, char* arg)
|
|
|
|
{
|
2018-05-14 01:45:04 -07:00
|
|
|
int ext_code = SRSLTE_SUCCESS;
|
|
|
|
if (!strcmp(param, "I_offset_cqi")) {
|
2019-12-16 07:04:22 -08:00
|
|
|
uci_cfg.I_offset_cqi = (uint32_t)strtol(arg, NULL, 10);
|
2018-05-14 01:45:04 -07:00
|
|
|
if (uci_cfg.I_offset_cqi > 15) {
|
|
|
|
ext_code = SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
} else if (!strcmp(param, "I_offset_ri")) {
|
2019-12-16 07:04:22 -08:00
|
|
|
uci_cfg.I_offset_ri = (uint32_t)strtol(arg, NULL, 10);
|
2018-05-14 01:45:04 -07:00
|
|
|
if (uci_cfg.I_offset_ri > 15) {
|
|
|
|
ext_code = SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
} else if (!strcmp(param, "I_offset_ack")) {
|
2019-12-16 07:04:22 -08:00
|
|
|
uci_cfg.I_offset_ack = (uint32_t)strtol(arg, NULL, 10);
|
2018-05-14 01:45:04 -07:00
|
|
|
if (uci_cfg.I_offset_ack > 15) {
|
|
|
|
ext_code = SRSLTE_ERROR;
|
|
|
|
}
|
2019-04-23 01:53:11 -07:00
|
|
|
} else if (!strcmp(param, "cqi")) {
|
2018-05-14 01:45:04 -07:00
|
|
|
if (!strcmp(arg, "wideband")) {
|
2019-04-23 01:53:11 -07:00
|
|
|
uci_data_tx.cfg.cqi.type = SRSLTE_CQI_TYPE_WIDEBAND;
|
|
|
|
uci_data_tx.value.cqi.wideband.wideband_cqi = (uint8_t)(0x0f);
|
|
|
|
uci_data_tx.cfg.cqi.data_enable = true;
|
2018-07-02 09:15:56 -07:00
|
|
|
} else if (!strcmp(arg, "none")) {
|
2019-04-23 01:53:11 -07:00
|
|
|
uci_data_tx.cfg.cqi.data_enable = false;
|
2018-05-14 01:45:04 -07:00
|
|
|
} else {
|
|
|
|
ext_code = SRSLTE_ERROR;
|
|
|
|
}
|
2019-04-23 01:53:11 -07:00
|
|
|
} else if (!strcmp(param, "ri")) {
|
|
|
|
uci_data_tx.value.ri = (uint8_t)strtol(arg, NULL, 10);
|
|
|
|
if (uci_data_tx.value.ri > 1) {
|
2018-05-14 01:45:04 -07:00
|
|
|
ext_code = SRSLTE_ERROR;
|
|
|
|
} else {
|
2019-04-23 01:53:11 -07:00
|
|
|
uci_data_tx.cfg.cqi.ri_len = 1;
|
2018-05-14 01:45:04 -07:00
|
|
|
}
|
|
|
|
} else if (!strcmp(param, "uci_ack")) {
|
2019-10-01 07:05:44 -07:00
|
|
|
uci_data_tx.cfg.ack[0].nof_acks = SRSLTE_MIN(uci_data_tx.cfg.ack[0].nof_acks + 1, SRSLTE_UCI_MAX_ACK_BITS);
|
2018-07-03 08:29:22 -07:00
|
|
|
} else if (!strcmp(param, "enable_64qam")) {
|
|
|
|
enable_64_qam ^= true;
|
2018-05-14 01:45:04 -07:00
|
|
|
} else {
|
|
|
|
ext_code = SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ext_code) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error parsing parameter '%s' and argument '%s'\n", param, arg);
|
2018-05-14 01:45:04 -07:00
|
|
|
exit(ext_code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
void parse_args(int argc, char** argv)
|
|
|
|
{
|
2015-01-29 16:15:09 -08:00
|
|
|
int opt;
|
2019-04-23 01:53:11 -07:00
|
|
|
while ((opt = getopt(argc, argv, "msLFrncpvf")) != -1) {
|
2018-07-02 09:15:56 -07:00
|
|
|
switch (opt) {
|
|
|
|
case 'm':
|
2019-12-16 07:04:22 -08:00
|
|
|
mcs_idx = (uint32_t)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
|
|
|
case 's':
|
2019-12-16 07:04:22 -08:00
|
|
|
subframe = (uint32_t)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
|
|
|
case 'R':
|
2019-12-16 07:04:22 -08:00
|
|
|
riv = (int)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
2019-04-23 01:53:11 -07:00
|
|
|
case 'L':
|
2019-04-30 06:56:47 -07:00
|
|
|
L_rb = (uint32_t)strtol(argv[optind], NULL, 10);
|
2019-04-23 01:53:11 -07:00
|
|
|
break;
|
2018-07-02 09:15:56 -07:00
|
|
|
case 'F':
|
2019-12-16 07:04:22 -08:00
|
|
|
freq_hop = (int)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
|
|
|
case 'r':
|
2019-12-16 07:04:22 -08:00
|
|
|
rv_idx = (uint32_t)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
|
|
|
case 'n':
|
2019-12-16 07:04:22 -08:00
|
|
|
cell.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
|
|
|
case 'c':
|
2019-12-16 07:04:22 -08:00
|
|
|
cell.id = (uint32_t)strtol(argv[optind], NULL, 10);
|
2018-07-02 09:15:56 -07:00
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
parse_extensive_param(argv[optind], argv[optind + 1]);
|
|
|
|
optind++;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
srslte_verbose++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage(argv[0]);
|
|
|
|
exit(-1);
|
2015-01-29 16:15:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
2019-04-30 06:56:47 -07:00
|
|
|
srslte_random_t random_h = srslte_random_init(0);
|
2019-04-23 01:53:11 -07:00
|
|
|
srslte_chest_ul_res_t chest_res;
|
2019-12-16 07:04:22 -08:00
|
|
|
srslte_pusch_t pusch_tx;
|
|
|
|
srslte_pusch_t pusch_rx;
|
|
|
|
uint8_t* data = NULL;
|
|
|
|
uint8_t* data_rx = NULL;
|
|
|
|
cf_t* sf_symbols = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
struct timeval t[3];
|
|
|
|
srslte_pusch_cfg_t cfg;
|
2016-04-21 10:06:48 -07:00
|
|
|
srslte_softbuffer_tx_t softbuffer_tx;
|
2018-07-02 09:15:56 -07:00
|
|
|
srslte_softbuffer_rx_t softbuffer_rx;
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
ZERO_OBJECT(uci_data_tx);
|
2015-01-29 16:15:09 -08:00
|
|
|
|
2015-04-27 09:14:28 -07:00
|
|
|
bzero(&cfg, sizeof(srslte_pusch_cfg_t));
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
srslte_dci_ul_t dci;
|
|
|
|
ZERO_OBJECT(dci);
|
|
|
|
|
|
|
|
parse_args(argc, argv);
|
|
|
|
|
2015-04-27 09:14:28 -07:00
|
|
|
dci.freq_hop_fl = freq_hop;
|
2019-04-23 01:53:11 -07:00
|
|
|
if (riv >= 0) {
|
2019-12-16 07:04:22 -08:00
|
|
|
dci.type2_alloc.riv = (uint32_t)riv;
|
2019-04-23 01:53:11 -07:00
|
|
|
} else {
|
|
|
|
dci.type2_alloc.riv = srslte_ra_type2_to_riv(L_rb, 0, cell.nof_prb);
|
2015-04-27 09:14:28 -07:00
|
|
|
}
|
2019-04-23 01:53:11 -07:00
|
|
|
dci.tb.mcs_idx = mcs_idx;
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
srslte_ul_sf_cfg_t ul_sf;
|
|
|
|
ZERO_OBJECT(ul_sf);
|
|
|
|
ul_sf.tti = 0;
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2019-04-30 06:56:47 -07:00
|
|
|
srslte_pusch_hopping_cfg_t ul_hopping = {.n_sb = 1, .hopping_offset = 0, .hop_mode = 1};
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
if (srslte_ra_ul_dci_to_grant(&cell, &ul_sf, &ul_hopping, &dci, &cfg.grant)) {
|
|
|
|
ERROR("Error computing resource allocation\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg.grant.n_prb_tilde[0] = cfg.grant.n_prb[0];
|
|
|
|
cfg.grant.n_prb_tilde[1] = cfg.grant.n_prb[1];
|
|
|
|
|
2017-09-01 04:29:11 -07:00
|
|
|
if (srslte_pusch_init_ue(&pusch_tx, cell.nof_prb)) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error creating PUSCH object\n");
|
2015-06-14 13:11:49 -07:00
|
|
|
goto quit;
|
|
|
|
}
|
2017-09-01 04:29:11 -07:00
|
|
|
if (srslte_pusch_set_cell(&pusch_tx, cell)) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error creating PUSCH object\n");
|
2017-09-01 04:29:11 -07:00
|
|
|
goto quit;
|
|
|
|
}
|
|
|
|
if (srslte_pusch_init_enb(&pusch_rx, cell.nof_prb)) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error creating PUSCH object\n");
|
2017-09-01 04:29:11 -07:00
|
|
|
goto quit;
|
|
|
|
}
|
|
|
|
if (srslte_pusch_set_cell(&pusch_rx, cell)) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error creating PUSCH object\n");
|
2017-09-01 04:29:11 -07:00
|
|
|
goto quit;
|
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
uint16_t rnti = 62;
|
|
|
|
dci.rnti = rnti;
|
|
|
|
cfg.rnti = rnti;
|
2017-09-01 04:29:11 -07:00
|
|
|
srslte_pusch_set_rnti(&pusch_tx, rnti);
|
|
|
|
srslte_pusch_set_rnti(&pusch_rx, rnti);
|
|
|
|
|
2018-07-02 09:15:56 -07:00
|
|
|
uint32_t nof_re = SRSLTE_NRE * cell.nof_prb * 2 * SRSLTE_CP_NSYMB(cell.cp);
|
2019-12-16 07:04:22 -08:00
|
|
|
sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re);
|
2015-02-14 05:20:16 -08:00
|
|
|
if (!sf_symbols) {
|
|
|
|
perror("malloc");
|
2016-08-25 17:05:17 -07:00
|
|
|
exit(-1);
|
2015-02-14 05:20:16 -08:00
|
|
|
}
|
2018-07-02 09:15:56 -07:00
|
|
|
|
|
|
|
data = srslte_vec_malloc(sizeof(uint8_t) * 150000);
|
2015-02-14 05:20:16 -08:00
|
|
|
if (!data) {
|
|
|
|
perror("malloc");
|
2016-08-25 17:05:17 -07:00
|
|
|
exit(-1);
|
2015-02-14 05:20:16 -08:00
|
|
|
}
|
2018-07-02 09:15:56 -07:00
|
|
|
|
|
|
|
data_rx = srslte_vec_malloc(sizeof(uint8_t) * 150000);
|
|
|
|
if (!data_rx) {
|
|
|
|
perror("malloc");
|
|
|
|
exit(-1);
|
2015-02-14 05:20:16 -08:00
|
|
|
}
|
2015-01-29 16:15:09 -08:00
|
|
|
|
2016-04-21 10:06:48 -07:00
|
|
|
if (srslte_softbuffer_tx_init(&softbuffer_tx, 100)) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error initiating soft buffer\n");
|
2016-04-21 10:06:48 -07:00
|
|
|
goto quit;
|
|
|
|
}
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2016-04-21 10:06:48 -07:00
|
|
|
if (srslte_softbuffer_rx_init(&softbuffer_rx, 100)) {
|
2019-04-23 01:53:11 -07:00
|
|
|
ERROR("Error initiating soft buffer\n");
|
2015-07-05 13:30:47 -07:00
|
|
|
goto quit;
|
|
|
|
}
|
2016-04-21 10:06:48 -07:00
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
srslte_chest_ul_res_init(&chest_res, cell.nof_prb);
|
|
|
|
srslte_chest_ul_res_set_identity(&chest_res);
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
cfg.enable_64qam = enable_64_qam;
|
2018-07-03 08:29:22 -07:00
|
|
|
|
2018-07-02 09:15:56 -07:00
|
|
|
for (int n = 0; n < subframe; n++) {
|
|
|
|
ret = SRSLTE_SUCCESS;
|
|
|
|
|
|
|
|
/* Configure PUSCH */
|
2019-04-30 06:56:47 -07:00
|
|
|
ul_sf.tti = (uint32_t)n;
|
2019-04-23 01:53:11 -07:00
|
|
|
cfg.uci_offset = uci_cfg;
|
2018-07-02 09:15:56 -07:00
|
|
|
|
|
|
|
srslte_softbuffer_tx_reset(&softbuffer_tx);
|
|
|
|
srslte_softbuffer_rx_reset(&softbuffer_rx);
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
for (uint32_t i = 0; i < cfg.grant.tb.tbs / 8; i++) {
|
2019-04-30 06:56:47 -07:00
|
|
|
data[i] = (uint8_t)srslte_random_uniform_int_dist(random_h, 0, 255);
|
2016-04-27 08:23:36 -07:00
|
|
|
}
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2019-10-01 07:05:44 -07:00
|
|
|
for (uint32_t a = 0; a < uci_data_tx.cfg.ack[0].nof_acks; a++) {
|
2019-04-30 06:56:47 -07:00
|
|
|
uci_data_tx.value.ack.ack_value[a] = (uint8_t)srslte_random_uniform_int_dist(random_h, 0, 1);
|
2018-07-02 09:15:56 -07:00
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
srslte_pusch_data_t pdata;
|
|
|
|
pdata.ptr = data;
|
|
|
|
pdata.uci = uci_data_tx.value;
|
|
|
|
cfg.uci_cfg = uci_data_tx.cfg;
|
|
|
|
cfg.softbuffers.tx = &softbuffer_tx;
|
2018-07-02 09:15:56 -07:00
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
if (srslte_pusch_encode(&pusch_tx, &ul_sf, &cfg, &pdata, sf_symbols)) {
|
|
|
|
ERROR("Error encoding TB\n");
|
2018-07-02 09:15:56 -07:00
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
if (rv_idx > 0) {
|
2019-04-23 01:53:11 -07:00
|
|
|
|
|
|
|
cfg.grant.tb.rv = rv_idx;
|
|
|
|
if (srslte_pusch_encode(&pusch_tx, &ul_sf, &cfg, &pdata, sf_symbols)) {
|
|
|
|
ERROR("Error encoding TB\n");
|
2018-07-02 09:15:56 -07:00
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-30 06:56:47 -07:00
|
|
|
srslte_pusch_res_t pusch_res = {};
|
|
|
|
pusch_res.data = data_rx;
|
|
|
|
cfg.softbuffers.rx = &softbuffer_rx;
|
2019-04-23 01:53:11 -07:00
|
|
|
memcpy(&cfg.uci_cfg, &uci_data_tx.cfg, sizeof(srslte_uci_cfg_t));
|
|
|
|
|
2018-07-02 09:15:56 -07:00
|
|
|
gettimeofday(&t[1], NULL);
|
2019-04-23 01:53:11 -07:00
|
|
|
int r = srslte_pusch_decode(&pusch_rx, &ul_sf, &cfg, &chest_res, sf_symbols, &pusch_res);
|
2018-07-02 09:15:56 -07:00
|
|
|
gettimeofday(&t[2], NULL);
|
|
|
|
if (r) {
|
|
|
|
printf("Error returned while decoding\n");
|
2018-07-03 08:29:22 -07:00
|
|
|
ret = SRSLTE_ERROR;
|
2018-07-02 09:15:56 -07:00
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
if (memcmp(data_rx, data, (size_t)cfg.grant.tb.tbs / 8) != 0) {
|
2018-07-02 09:15:56 -07:00
|
|
|
printf("Unmatched data detected\n");
|
2018-07-03 08:29:22 -07:00
|
|
|
ret = SRSLTE_ERROR;
|
2018-07-02 09:15:56 -07:00
|
|
|
} else {
|
|
|
|
INFO("Rx Data is Ok\n");
|
|
|
|
}
|
|
|
|
|
2019-10-01 07:05:44 -07:00
|
|
|
if (uci_data_tx.cfg.ack[0].nof_acks) {
|
|
|
|
if (memcmp(uci_data_tx.value.ack.ack_value, pusch_res.uci.ack.ack_value, uci_data_tx.cfg.ack[0].nof_acks) != 0) {
|
2019-04-23 01:53:11 -07:00
|
|
|
printf("UCI ACK bit error:\n");
|
|
|
|
printf("\tTx: ");
|
2019-10-01 07:05:44 -07:00
|
|
|
srslte_vec_fprint_byte(stdout, uci_data_tx.value.ack.ack_value, uci_data_tx.cfg.ack[0].nof_acks);
|
2019-04-23 01:53:11 -07:00
|
|
|
printf("\tRx: ");
|
2019-10-01 07:05:44 -07:00
|
|
|
srslte_vec_fprint_byte(stdout, pusch_res.uci.ack.ack_value, cfg.uci_cfg.ack[0].nof_acks);
|
2018-07-02 09:15:56 -07:00
|
|
|
ret = SRSLTE_ERROR;
|
|
|
|
} else {
|
2019-04-23 01:53:11 -07:00
|
|
|
INFO("Rx ACK (%d bits) is Ok, %d%d\n",
|
2019-10-01 07:05:44 -07:00
|
|
|
uci_data_tx.cfg.ack[0].nof_acks,
|
2019-04-23 01:53:11 -07:00
|
|
|
uci_data_tx.value.ack.ack_value[0],
|
|
|
|
uci_data_tx.value.ack.ack_value[1]);
|
2018-07-02 09:15:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
if (uci_data_tx.cfg.cqi.ri_len) {
|
|
|
|
if (uci_data_tx.value.ri != pusch_res.uci.ri) {
|
|
|
|
printf("UCI RI bit error: %d != %d\n", uci_data_tx.value.ri, pusch_res.uci.ri);
|
2018-07-02 09:15:56 -07:00
|
|
|
ret = SRSLTE_ERROR;
|
|
|
|
} else {
|
|
|
|
INFO("Rx RI is Ok\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
if (uci_data_tx.cfg.cqi.data_enable) {
|
|
|
|
uci_data_tx.value.cqi.data_crc = pusch_res.uci.cqi.data_crc;
|
|
|
|
if (memcmp(&uci_data_tx.value.cqi, &pusch_res.uci.cqi, sizeof(pusch_res.uci.cqi)) != 0) {
|
2018-07-02 09:15:56 -07:00
|
|
|
printf("CQI Decode failed at subframe %d\n", n);
|
|
|
|
ret = SRSLTE_ERROR;
|
|
|
|
} else {
|
2019-04-23 01:53:11 -07:00
|
|
|
INFO("Rx CQI is Ok (crc=%d, wb_cqi=%d)\n", pusch_res.uci.cqi.data_crc, pusch_res.uci.cqi.wideband.wideband_cqi);
|
2018-07-02 09:15:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
goto quit;
|
|
|
|
}
|
|
|
|
|
|
|
|
get_time_interval(t);
|
2019-04-23 01:53:11 -07:00
|
|
|
printf("DECODED OK in %d:%d (TBS: %d bits, TX: %.2f Mbps, Processing: %.2f Mbps)\n",
|
|
|
|
(int)t[0].tv_sec,
|
|
|
|
(int)t[0].tv_usec,
|
|
|
|
cfg.grant.tb.tbs,
|
|
|
|
(float)cfg.grant.tb.tbs / 1000,
|
|
|
|
(float)cfg.grant.tb.tbs / t[0].tv_usec);
|
2016-04-27 08:23:36 -07:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
quit:
|
|
|
|
srslte_chest_ul_res_free(&chest_res);
|
|
|
|
srslte_pusch_free(&pusch_tx);
|
|
|
|
srslte_pusch_free(&pusch_rx);
|
|
|
|
srslte_softbuffer_tx_free(&softbuffer_tx);
|
|
|
|
srslte_softbuffer_rx_free(&softbuffer_rx);
|
|
|
|
srslte_random_free(random_h);
|
|
|
|
if (sf_symbols) {
|
|
|
|
free(sf_symbols);
|
2015-01-29 16:15:09 -08:00
|
|
|
}
|
|
|
|
if (data) {
|
|
|
|
free(data);
|
|
|
|
}
|
2018-07-02 09:15:56 -07:00
|
|
|
if (data_rx) {
|
|
|
|
free(data_rx);
|
|
|
|
}
|
2015-01-29 16:15:09 -08:00
|
|
|
if (ret) {
|
|
|
|
printf("Error\n");
|
|
|
|
} else {
|
|
|
|
printf("Ok\n");
|
|
|
|
}
|
|
|
|
exit(ret);
|
|
|
|
}
|