mirror of https://github.com/PentHertz/srsLTE.git
Moved HARQ to MAC. Redesigned RA and DL/UL grant framework
This commit is contained in:
parent
dc9464be9c
commit
addd786e5f
|
@ -35,7 +35,7 @@
|
|||
#include "cuhd_handler.hpp"
|
||||
#include "srslte/cuhd/cuhd.h"
|
||||
|
||||
#define METADATA_VERBOSE
|
||||
//#define METADATA_VERBOSE
|
||||
|
||||
//#define HIDE_MESSAGES
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1);
|
||||
pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0');
|
||||
|
||||
addpath('../../debug/lte/phy/lib/phch/test')
|
||||
addpath('../../debug/srslte/lib/phch/test')
|
||||
|
||||
TBs=1:111:15000;
|
||||
e_bits=10000;
|
||||
|
|
|
@ -10,7 +10,7 @@ Npackets = 1;
|
|||
SNR_values = linspace(15,20,4);
|
||||
|
||||
%% Choose RMC
|
||||
[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.9',[1;0;0;1]);
|
||||
[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.4',[1;0;0;1]);
|
||||
waveform = sum(waveform,2);
|
||||
|
||||
if ~isempty(recordedSignal)
|
||||
|
@ -51,7 +51,7 @@ cec.InterpType = 'linear'; % 2D interpolation type
|
|||
cec.InterpWindow = 'Centered'; % Interpolation window type
|
||||
cec.InterpWinSize = 1; % Interpolation window size
|
||||
|
||||
addpath('../../debug/lte/phy/lib/phch/test')
|
||||
addpath('../../debug/srslte/lib/phch/test')
|
||||
|
||||
decoded = zeros(size(SNR_values));
|
||||
decoded_srslte = zeros(size(SNR_values));
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
clear
|
||||
ueConfig=struct('NCellID',1,'NULRB',6,'NSubframe',8,'RNTI',68,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
ueConfig=struct('NCellID',1,'NULRB',6,'NSubframe',1,'RNTI',18,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[1:4]','Modulation','QPSK','RV',0,'Shortened',0);
|
||||
|
||||
addpath('../../debug/lte/phy/lib/phch/test')
|
||||
addpath('../../debug/srslte/lib/phch/test')
|
||||
|
||||
% TBs=0:13:211;
|
||||
% cqilen=[0, 8, 17];
|
||||
% mods={'QPSK','16QAM','64QAM'};
|
||||
% rvs=0;
|
||||
% betas=0:3:11;
|
||||
|
||||
TBs=88;
|
||||
cqilen=0;
|
||||
mods={'QPSK'};
|
||||
rvs=0;
|
||||
betas=0;
|
||||
TBs=0:13:211;
|
||||
cqilen=[0, 8, 17];
|
||||
mods={'QPSK','16QAM','64QAM'};
|
||||
rvs=0;
|
||||
betas=[2.0 2.5 6.25];
|
||||
|
||||
for i=1:length(TBs)
|
||||
for m=1:length(mods)
|
||||
|
@ -28,9 +22,9 @@ for i=1:length(TBs)
|
|||
|
||||
puschConfig.Modulation = mods{m};
|
||||
puschConfig.RV = rvs(r);
|
||||
puschConfig.BetaCQI = 2+betas(bcqi);
|
||||
puschConfig.BetaRI = 2+betas(bri);
|
||||
puschConfig.BetaACK = 2+betas(back);
|
||||
puschConfig.BetaCQI = betas(bcqi);
|
||||
puschConfig.BetaRI = betas(bri);
|
||||
puschConfig.BetaACK = betas(back);
|
||||
|
||||
if (betas(bri)>0)
|
||||
ri_bit=randi(2,1,1)-1;
|
||||
|
|
|
@ -2,13 +2,13 @@ clear
|
|||
ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','16QAM','RV',0,'Shortened',0);
|
||||
|
||||
addpath('../../debug/lte/phy/lib/phch/test')
|
||||
addpath('../../debug/srslte/lib/phch/test')
|
||||
|
||||
TBs=0:13:222;
|
||||
cqilen=0;%[0, 8, 17];
|
||||
cqilen=[0, 8, 17];
|
||||
mods={'QPSK','16QAM','64QAM'};
|
||||
rvs=0;%[0, 3];
|
||||
betas=0:3:11;
|
||||
rvs=[0, 3];
|
||||
betas=[2.0 2.5 6.25];
|
||||
|
||||
|
||||
for i=1:length(TBs)
|
||||
|
@ -23,9 +23,9 @@ for i=1:length(TBs)
|
|||
|
||||
puschConfig.Modulation = mods{m};
|
||||
puschConfig.RV = rvs(r);
|
||||
puschConfig.BetaCQI = 2+betas(bcqi);
|
||||
puschConfig.BetaRI = 2+betas(bri);
|
||||
puschConfig.BetaACK = 2+betas(back);
|
||||
puschConfig.BetaCQI = betas(bcqi);
|
||||
puschConfig.BetaRI = betas(bri);
|
||||
puschConfig.BetaACK = betas(back);
|
||||
|
||||
if (betas(bri)>0)
|
||||
ri_bit=randi(2,1,1)-1;
|
||||
|
|
|
@ -46,4 +46,4 @@ ADD_CUSTOM_TARGET (add_srslte_headers SOURCES ${HEADERS_ALL})
|
|||
########################################################################
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
add_subdirectory(tutorial_examples)
|
||||
#add_subdirectory(tutorial_examples)
|
||||
|
|
|
@ -74,9 +74,10 @@ srslte_pbch_t pbch;
|
|||
srslte_pcfich_t pcfich;
|
||||
srslte_pdcch_t pdcch;
|
||||
srslte_pdsch_t pdsch;
|
||||
srslte_harq_t harq_process;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
srslte_regs_t regs;
|
||||
srslte_ra_pdsch_t ra_dl;
|
||||
srslte_ra_dl_dci_t ra_dl;
|
||||
|
||||
|
||||
cf_t *sf_buffer = NULL, *output_buffer = NULL;
|
||||
|
@ -253,15 +254,15 @@ void base_init() {
|
|||
|
||||
srslte_pdsch_set_rnti(&pdsch, 1234);
|
||||
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void base_free() {
|
||||
|
||||
srslte_harq_free(&harq_process);
|
||||
srslte_softbuffer_tx_free(&softbuffer);
|
||||
srslte_pdsch_free(&pdsch);
|
||||
srslte_pdcch_free(&pdcch);
|
||||
srslte_regs_free(®s);
|
||||
|
@ -315,21 +316,25 @@ uint32_t prbset_to_bitmask() {
|
|||
|
||||
int update_radl() {
|
||||
|
||||
bzero(&ra_dl, sizeof(srslte_ra_pdsch_t));
|
||||
bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
ra_dl.harq_process = 0;
|
||||
ra_dl.mcs_idx = mcs_idx;
|
||||
ra_dl.ndi = 0;
|
||||
ra_dl.rv_idx = 0;
|
||||
ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
|
||||
ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask();
|
||||
|
||||
srslte_ra_dl_alloc(&ra_dl.prb_alloc, &ra_dl, cell.nof_prb);
|
||||
srslte_ra_dl_alloc_re(&ra_dl.prb_alloc, cell.nof_prb, 1, cell.nof_prb<10?(cfi+1):cfi, SRSLTE_CP_NORM);
|
||||
srslte_ra_mcs_from_idx_dl(mcs_idx, ra_dl.prb_alloc.slot[0].nof_prb, &ra_dl.mcs);
|
||||
|
||||
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
|
||||
srslte_ra_dl_grant_t dummy_grant;
|
||||
srslte_ra_dl_dci_to_grant(&ra_dl, &dummy_grant, cell, 1, cfi, true);
|
||||
srslte_ra_dl_grant_fprint(stdout, &dummy_grant);
|
||||
printf("Type new MCS index and press Enter: "); fflush(stdout);
|
||||
|
||||
if (dummy_grant.mcs.tbs > dummy_grant.nof_bits) {
|
||||
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", dummy_grant.mcs.tbs, dummy_grant.nof_bits, (float) dummy_grant.mcs.tbs / dummy_grant.nof_bits);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -403,7 +408,7 @@ void *net_thread_fnc(void *arg) {
|
|||
do {
|
||||
n = srslte_netsource_read(&net_source, &data_unpacked[rpm], DATA_BUFF_SZ-rpm);
|
||||
if (n > 0) {
|
||||
int nbytes = 1+(ra_dl.mcs.tbs-1)/8;
|
||||
int nbytes = 1+(pdsch_cfg.grant.mcs.tbs-1)/8;
|
||||
rpm += n;
|
||||
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
|
||||
wpm = 0;
|
||||
|
@ -537,13 +542,6 @@ int main(int argc, char **argv) {
|
|||
fprintf(stderr, "Error updating parameters from control port\n");
|
||||
}
|
||||
|
||||
srslte_harq_reset(&harq_process);
|
||||
if (srslte_harq_setup_dl(&harq_process, ra_dl.mcs, ra_dl.rv_idx, sf_idx, &ra_dl.prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Transmit PDCCH + PDSCH only when there is data to send */
|
||||
if (sf_idx != 0 && sf_idx != 5) {
|
||||
if (net_port > 0) {
|
||||
|
@ -552,8 +550,8 @@ int main(int argc, char **argv) {
|
|||
INFO("Transmitting packet\n",0);
|
||||
}
|
||||
} else {
|
||||
INFO("SF: %d, Generating %d random bits\n", sf_idx, ra_dl.mcs.tbs);
|
||||
for (i=0;i<ra_dl.mcs.tbs;i++) {
|
||||
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs.tbs);
|
||||
for (i=0;i<pdsch_cfg.grant.mcs.tbs;i++) {
|
||||
data[i] = rand()%2;
|
||||
}
|
||||
send_data = true;
|
||||
|
@ -563,6 +561,12 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (send_data) {
|
||||
srslte_ra_dl_dci_to_grant(&ra_dl, &pdsch_cfg.grant, cell, sf_idx, cfi, true);
|
||||
srslte_cbsegm(&pdsch_cfg.cb_segm, pdsch_cfg.grant.mcs.tbs);
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
pdsch_cfg.sf_idx = sf_idx;
|
||||
pdsch_cfg.rv = 0;
|
||||
|
||||
srslte_dci_msg_pack_pdsch(&ra_dl, &dci_msg, SRSLTE_DCI_FORMAT1, cell.nof_prb, false);
|
||||
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], 1234, sf_symbols, sf_idx, cfi)) {
|
||||
|
@ -570,14 +574,14 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_pdsch_encode(&pdsch, &harq_process, data, sf_symbols)) {
|
||||
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (net_port > 0 && net_packet_ready) {
|
||||
if (null_file_sink) {
|
||||
srslte_bit_unpack_vector(data, data_tmp, ra_dl.mcs.tbs);
|
||||
if (srslte_netsink_write(&net_sink, data_tmp, 1+(ra_dl.mcs.tbs-1)/8) < 0) {
|
||||
srslte_bit_unpack_vector(data, data_tmp, pdsch_cfg.grant.mcs.tbs);
|
||||
if (srslte_netsink_write(&net_sink, data_tmp, 1+(pdsch_cfg.grant.mcs.tbs-1)/8) < 0) {
|
||||
fprintf(stderr, "Error sending data through UDP socket\n");
|
||||
}
|
||||
}
|
||||
|
@ -598,7 +602,7 @@ int main(int argc, char **argv) {
|
|||
} else {
|
||||
#ifndef DISABLE_UHD
|
||||
// FIXME
|
||||
float norm_factor = (float) cell.nof_prb/15/sqrtf(ra_dl.prb_alloc.slot[0].nof_prb);
|
||||
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb);
|
||||
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
cuhd_send(uhd, output_buffer, sf_n_samples, true);
|
||||
#endif
|
||||
|
|
|
@ -566,7 +566,7 @@ void *plot_thread_run(void *arg) {
|
|||
while(1) {
|
||||
sem_wait(&plot_sem);
|
||||
|
||||
uint32_t nof_symbols = ue_dl.harq_process[0].dl_alloc.re_sf[plot_sf_idx];
|
||||
uint32_t nof_symbols = ue_dl.pdsch_cfg.grant.nof_re;
|
||||
for (i = 0; i < nof_re; i++) {
|
||||
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));
|
||||
if (isinf(tmp_plot[i])) {
|
||||
|
|
|
@ -295,7 +295,8 @@ int main(int argc, char **argv) {
|
|||
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
|
||||
uint32_t sfn_offset;
|
||||
rar_msg_t rar_msg;
|
||||
srslte_ra_pusch_t ra_pusch;
|
||||
srslte_ra_ul_dci_t ra_pusch;
|
||||
srslte_ra_ul_grant_t ra_grant;
|
||||
uint32_t rar_window_start = 0, rar_trials = 0, rar_window_stop = 0;
|
||||
srslte_timestamp_t uhd_time;
|
||||
srslte_timestamp_t next_tx_time;
|
||||
|
@ -489,15 +490,16 @@ int main(int argc, char **argv) {
|
|||
|
||||
rar_unpack(data_rx, &rar_msg);
|
||||
rar_msg_fprint(stdout, &rar_msg);
|
||||
|
||||
srslte_dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch);
|
||||
srslte_dci_rar_grant_t rar_grant;
|
||||
rar_grant.hopping_flag = rar_msg.hopping_flag;
|
||||
rar_grant.rba = rar_msg.rba;
|
||||
rar_grant.trunc_mcs = rar_msg.mcs;
|
||||
srslte_dci_rar_to_ul_grant(&rar_grant, cell, 0, 0, &ra_pusch, &ra_grant);
|
||||
srslte_ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
|
||||
|
||||
srslte_ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb);
|
||||
|
||||
srslte_ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
|
||||
|
||||
srslte_bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
|
||||
srslte_bit_pack_vector((uint8_t*) conn_request_msg, data, ra_grant.mcs.tbs);
|
||||
|
||||
uint32_t n_ta = srslte_N_ta_new_rar(rar_msg.timing_adv_cmd);
|
||||
printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta);
|
||||
|
@ -515,7 +517,7 @@ int main(int argc, char **argv) {
|
|||
printf("Setting CFO: %f (%f)\n", cfo, cfo*15000);
|
||||
srslte_ue_ul_set_cfo(&ue_ul, cfo);
|
||||
|
||||
n = srslte_ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, rar_msg.temp_c_rnti, ul_signal);
|
||||
n = srslte_ue_ul_pusch_encode_rnti(&ue_ul, &ra_grant, data, ul_sf_idx, 0, rar_msg.temp_c_rnti, ul_signal);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error encoding PUSCH\n");
|
||||
exit(-1);
|
||||
|
|
|
@ -126,8 +126,6 @@ typedef enum {SRSLTE_CP_NORM, SRSLTE_CP_EXT} srslte_cp_t;
|
|||
|
||||
#define SRSLTE_NOF_LTE_BANDS 29
|
||||
|
||||
#define SRSLTE_NOF_TC_CB_SIZES 188
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
SRSLTE_PHICH_NORM = 0,
|
||||
SRSLTE_PHICH_EXT
|
||||
|
@ -221,18 +219,12 @@ SRSLTE_API uint32_t srslte_N_ta_new_rar(uint32_t ta);
|
|||
SRSLTE_API uint32_t srslte_N_ta_new(uint32_t N_ta_old,
|
||||
uint32_t ta);
|
||||
|
||||
SRSLTE_API int srslte_cb_size(uint32_t index);
|
||||
|
||||
SRSLTE_API bool srslte_cb_size_isvalid(uint32_t size);
|
||||
|
||||
SRSLTE_API char *srslte_cp_string(srslte_cp_t cp);
|
||||
|
||||
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_find_cb_index(uint32_t long_cb);
|
||||
|
||||
SRSLTE_API float srslte_band_fd(uint32_t earfcn);
|
||||
|
||||
SRSLTE_API int srslte_band_get_fd_band(uint32_t band,
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "srslte/config.h"
|
||||
|
||||
#ifndef CBSEGM_H
|
||||
#define CBSEGM_H
|
||||
|
||||
#define SRSLTE_NOF_TC_CB_SIZES 188
|
||||
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t F;
|
||||
uint32_t C;
|
||||
uint32_t K1;
|
||||
uint32_t K2;
|
||||
uint32_t C1;
|
||||
uint32_t C2;
|
||||
uint32_t tbs;
|
||||
} srslte_cbsegm_t;
|
||||
|
||||
SRSLTE_API int srslte_cbsegm(srslte_cbsegm_t *s,
|
||||
uint32_t tbs);
|
||||
|
||||
SRSLTE_API int srslte_cbsegm_cbsize(uint32_t index);
|
||||
|
||||
SRSLTE_API bool srslte_cbsegm_cbsize_isvalid(uint32_t size);
|
||||
|
||||
SRSLTE_API int srslte_cbsegm_cbindex(uint32_t long_cb);
|
||||
|
||||
#endif
|
|
@ -37,6 +37,7 @@
|
|||
#define _TC_INTERL_H
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t *forward;
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
#define SRSLTE_TCOD_RATE 3
|
||||
#define SRSLTE_TCOD_TOTALTAIL 12
|
||||
|
||||
#define MAX_LONG_CB 6144
|
||||
#define MAX_LONG_CODED (SRSLTE_TCOD_RATE*MAX_LONG_CB+SRSLTE_TCOD_TOTALTAIL)
|
||||
#define SRSLTE_TCOD_MAX_LEN_CB 6144
|
||||
#define SRSLTE_TCOD_MAX_LEN_CODED (SRSLTE_TCOD_RATE*SRSLTE_TCOD_MAX_LEN_CB+SRSLTE_TCOD_TOTALTAIL)
|
||||
|
||||
typedef float srslte_llr_t;
|
||||
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
/******************************************************************************
|
||||
* File: dci.h
|
||||
*
|
||||
* Description: Downlink control information (DCI)
|
||||
* Description: Downlink control information (DCI).
|
||||
* Packing/Unpacking functions to convert between bit streams
|
||||
* and packed DCI UL/DL grants defined in ra.h
|
||||
*
|
||||
* Reference: 3GPP TS 36.212 version 10.0.0 Release 10 Sec. 5.3.3
|
||||
*****************************************************************************/
|
||||
|
@ -79,25 +81,36 @@ typedef struct SRSLTE_API {
|
|||
uint32_t nof_bits;
|
||||
} srslte_dci_msg_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t rba;
|
||||
uint32_t trunc_mcs;
|
||||
bool hopping_flag;
|
||||
} srslte_dci_rar_grant_t;
|
||||
|
||||
/* Converts a received PDSCH DL scheduling DCI message
|
||||
* to ra structures ready to be passed to the harq setup function
|
||||
*/
|
||||
SRSLTE_API int srslte_dci_msg_to_ra_dl(srslte_dci_msg_t *msg,
|
||||
uint16_t msg_rnti,
|
||||
srslte_cell_t cell,
|
||||
uint32_t cfi,
|
||||
srslte_ra_pdsch_t *ra_dl);
|
||||
SRSLTE_API int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg,
|
||||
uint16_t msg_rnti,
|
||||
srslte_cell_t cell,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
srslte_ra_dl_dci_t *dl_dci,
|
||||
srslte_ra_dl_grant_t *grant);
|
||||
|
||||
SRSLTE_API int srslte_dci_msg_to_ra_ul(srslte_dci_msg_t *msg,
|
||||
uint32_t nof_prb,
|
||||
uint32_t n_rb_ho,
|
||||
srslte_ra_pusch_t *ra_ul);
|
||||
SRSLTE_API int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg,
|
||||
srslte_cell_t cell,
|
||||
uint32_t N_srs,
|
||||
uint32_t n_rb_ho,
|
||||
srslte_ra_ul_dci_t *ul_dci,
|
||||
srslte_ra_ul_grant_t *grant);
|
||||
|
||||
SRSLTE_API int srslte_dci_rar_to_ra_ul(uint32_t rba,
|
||||
uint32_t trunc_mcs,
|
||||
bool hopping_flag,
|
||||
uint32_t nof_prb,
|
||||
srslte_ra_pusch_t *ra);
|
||||
SRSLTE_API int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar,
|
||||
srslte_cell_t cell,
|
||||
uint32_t N_srs,
|
||||
uint32_t n_rb_ho,
|
||||
srslte_ra_ul_dci_t *ul_dci,
|
||||
srslte_ra_ul_grant_t *grant);
|
||||
|
||||
SRSLTE_API srslte_dci_format_t srslte_dci_format_from_string(char *str);
|
||||
|
||||
|
@ -118,23 +131,23 @@ SRSLTE_API void srslte_dci_msg_type_fprint(FILE *f,
|
|||
srslte_dci_msg_type_t type);
|
||||
|
||||
// For srslte_dci_msg_type_t = SRSLTE_DCI_MSG_TYPE_PUSCH_SCHED
|
||||
SRSLTE_API int srslte_dci_msg_pack_pusch(srslte_ra_pusch_t *data,
|
||||
SRSLTE_API int srslte_dci_msg_pack_pusch(srslte_ra_ul_dci_t *data,
|
||||
srslte_dci_msg_t *msg,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API int srslte_dci_msg_unpack_pusch(srslte_dci_msg_t *msg,
|
||||
srslte_ra_pusch_t *data,
|
||||
srslte_ra_ul_dci_t *data,
|
||||
uint32_t nof_prb);
|
||||
|
||||
// For srslte_dci_msg_type_t = SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED
|
||||
SRSLTE_API int srslte_dci_msg_pack_pdsch(srslte_ra_pdsch_t *data,
|
||||
SRSLTE_API int srslte_dci_msg_pack_pdsch(srslte_ra_dl_dci_t *data,
|
||||
srslte_dci_msg_t *msg,
|
||||
srslte_dci_format_t format,
|
||||
uint32_t nof_prb,
|
||||
bool crc_is_crnti);
|
||||
|
||||
SRSLTE_API int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg,
|
||||
srslte_ra_pdsch_t *data,
|
||||
srslte_ra_dl_dci_t *data,
|
||||
uint32_t nof_prb,
|
||||
bool crc_is_crnti);
|
||||
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* File: harq.h
|
||||
*
|
||||
* Description: Hybrid Automatic Repeat Request (HARQ)
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HARQ_
|
||||
#define HARQ_
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/phch/ra.h"
|
||||
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t F;
|
||||
uint32_t C;
|
||||
uint32_t K1;
|
||||
uint32_t K2;
|
||||
uint32_t C1;
|
||||
uint32_t C2;
|
||||
} srslte_harq_cbsegm_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_ra_mcs_t mcs;
|
||||
uint32_t rv;
|
||||
uint32_t sf_idx;
|
||||
srslte_ra_dl_alloc_t dl_alloc;
|
||||
srslte_ra_ul_alloc_t ul_alloc;
|
||||
srslte_cell_t cell;
|
||||
|
||||
uint32_t nof_re; // Number of RE per subframe
|
||||
uint32_t nof_bits; // Number of bits per subframe
|
||||
uint32_t nof_symb; // Number of symbols per subframe
|
||||
uint32_t nof_prb; // Number of allocated PRB per subframe.
|
||||
|
||||
uint32_t max_cb;
|
||||
uint32_t w_buff_size;
|
||||
float **pdsch_w_buff_f;
|
||||
uint8_t **pdsch_w_buff_c;
|
||||
|
||||
srslte_harq_cbsegm_t cb_segm;
|
||||
|
||||
} srslte_harq_t;
|
||||
|
||||
SRSLTE_API int srslte_harq_init(srslte_harq_t * q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_harq_setup_dl(srslte_harq_t *p,
|
||||
srslte_ra_mcs_t mcs,
|
||||
uint32_t rv,
|
||||
uint32_t sf_idx,
|
||||
srslte_ra_dl_alloc_t *prb_alloc);
|
||||
|
||||
SRSLTE_API int srslte_harq_setup_ul(srslte_harq_t *p,
|
||||
srslte_ra_mcs_t mcs,
|
||||
uint32_t rv,
|
||||
uint32_t sf_idx,
|
||||
srslte_ra_ul_alloc_t *prb_alloc);
|
||||
|
||||
SRSLTE_API void srslte_harq_reset(srslte_harq_t *p);
|
||||
|
||||
SRSLTE_API void srslte_harq_free(srslte_harq_t *p);
|
||||
|
||||
SRSLTE_API int srslte_harq_codeblock_segmentation(srslte_harq_cbsegm_t *s,
|
||||
uint32_t tbs);
|
||||
|
||||
|
||||
#endif
|
|
@ -46,12 +46,11 @@
|
|||
#include "srslte/phch/dci.h"
|
||||
#include "srslte/phch/regs.h"
|
||||
#include "srslte/phch/sch.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/phch/pdsch_cfg.h"
|
||||
|
||||
#define SRSLTE_PDSCH_MAX_TDEC_ITERS 5
|
||||
|
||||
|
||||
|
||||
/* PDSCH object */
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cell_t cell;
|
||||
|
@ -87,25 +86,29 @@ SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q,
|
|||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_encode(srslte_pdsch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS]);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
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_harq_t *harq_process,
|
||||
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);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
cf_t *sf_symbols,
|
||||
cf_t *ce[SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* File: pdsch_cfg.h
|
||||
*
|
||||
* Description: Physical downlink shared channel configuration
|
||||
*
|
||||
* Reference: 3GPP TS 36.211 version 10.0.0 Release 10 Sec. 6.4
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef PDSCHCFG_
|
||||
#define PDSCHCFG_
|
||||
|
||||
#include "srslte/phch/ra.h"
|
||||
#include "srslte/phch/softbuffer.h"
|
||||
#include "srslte/fec/cbsegm.h"
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cbsegm_t cb_segm;
|
||||
srslte_ra_dl_grant_t grant;
|
||||
uint32_t rv;
|
||||
uint32_t sf_idx;
|
||||
} srslte_pdsch_cfg_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
#include "srslte/scrambling/scrambling.h"
|
||||
#include "srslte/phch/regs.h"
|
||||
#include "srslte/phch/sch.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/phch/pusch_cfg.h"
|
||||
#include "srslte/dft/dft_precoding.h"
|
||||
|
||||
#define SRSLTE_PUSCH_MAX_TDEC_ITERS 5
|
||||
|
@ -110,31 +110,36 @@ SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q,
|
|||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API int srslte_pusch_encode(srslte_pusch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
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_harq_t *harq_process,
|
||||
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_harq_t *harq_process,
|
||||
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_harq_t *harq,
|
||||
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);
|
||||
|
||||
SRSLTE_API int srslte_pusch_decode(srslte_pusch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
cf_t *sf_symbols,
|
||||
cf_t *ce,
|
||||
float noise_estimate,
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* File: pdsch_cfg.h
|
||||
*
|
||||
* Description: Physical downlink shared channel configuration
|
||||
*
|
||||
* Reference: 3GPP TS 36.211 version 10.0.0 Release 10 Sec. 6.4
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef PUSCHCFG_
|
||||
#define PUSCHCFG_
|
||||
|
||||
#include "srslte/phch/ra.h"
|
||||
#include "srslte/phch/softbuffer.h"
|
||||
#include "srslte/fec/cbsegm.h"
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cbsegm_t cb_segm;
|
||||
srslte_ra_ul_grant_t grant;
|
||||
uint32_t rv;
|
||||
uint32_t sf_idx;
|
||||
srslte_cp_t cp;
|
||||
} srslte_pusch_cfg_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
* File: ra.h
|
||||
*
|
||||
* Description: Structures and utility functions for DL/UL resource allocation.
|
||||
* Convert an UL/DL unpacket DCI message to a resource allocation
|
||||
*
|
||||
* Reference: 3GPP TS 36.213 version 10.0.1 Release 10
|
||||
*****************************************************************************/
|
||||
|
@ -42,6 +43,10 @@
|
|||
#include "srslte/config.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
|
||||
/**************************************************
|
||||
* Common structures used for Resource Allocation
|
||||
**************************************************/
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_mod_t mod;
|
||||
int tbs;
|
||||
|
@ -78,39 +83,72 @@ typedef struct SRSLTE_API {
|
|||
} mode;
|
||||
} srslte_ra_type2_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
bool prb_idx[SRSLTE_MAX_PRB];
|
||||
uint32_t nof_prb;
|
||||
} srslte_ra_prb_slot_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************
|
||||
* Structures used for Downlink Resource Allocation
|
||||
**************************************************/
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_ra_prb_slot_t slot[2];
|
||||
bool prb_idx[2][SRSLTE_MAX_PRB];
|
||||
uint32_t lstart;
|
||||
uint32_t re_sf[SRSLTE_NSUBFRAMES_X_FRAME];
|
||||
} srslte_ra_dl_alloc_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t n_prb[2];
|
||||
uint32_t n_prb_tilde[2];
|
||||
uint32_t L_prb;
|
||||
uint32_t freq_hopping;
|
||||
} srslte_ra_ul_alloc_t;
|
||||
uint32_t nof_re;
|
||||
uint32_t nof_bits;
|
||||
uint32_t nof_symb;
|
||||
uint32_t nof_prb;
|
||||
uint32_t Qm;
|
||||
srslte_ra_mcs_t mcs;
|
||||
} srslte_ra_dl_grant_t;
|
||||
|
||||
/** Unpacked DCI message for DL grant */
|
||||
typedef struct SRSLTE_API {
|
||||
|
||||
enum {
|
||||
SRSLTE_RA_DCI_FORMAT1,
|
||||
SRSLTE_RA_DCI_FORMAT1A,
|
||||
SRSLTE_RA_DCI_FORMAT1C,
|
||||
} dci_format;
|
||||
|
||||
srslte_ra_type_t alloc_type;
|
||||
union {
|
||||
srslte_ra_type0_t type0_alloc;
|
||||
srslte_ra_type1_t type1_alloc;
|
||||
srslte_ra_type2_t type2_alloc;
|
||||
};
|
||||
srslte_ra_dl_alloc_t prb_alloc;
|
||||
|
||||
uint32_t mcs_idx;
|
||||
srslte_ra_mcs_t mcs;
|
||||
uint32_t harq_process;
|
||||
uint32_t rv_idx;
|
||||
bool ndi;
|
||||
} srslte_ra_pdsch_t;
|
||||
} srslte_ra_dl_dci_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************
|
||||
* Structures used for Uplink Resource Allocation
|
||||
**************************************************/
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t n_prb[2];
|
||||
uint32_t n_prb_tilde[2];
|
||||
uint32_t L_prb;
|
||||
uint32_t freq_hopping;
|
||||
uint32_t lstart;
|
||||
uint32_t nof_re;
|
||||
uint32_t nof_bits;
|
||||
uint32_t nof_symb;
|
||||
uint32_t M_sc;
|
||||
uint32_t M_sc_init;
|
||||
uint32_t Qm;
|
||||
srslte_ra_mcs_t mcs;
|
||||
} srslte_ra_ul_grant_t;
|
||||
|
||||
/** Unpacked DCI Format0 message */
|
||||
typedef struct SRSLTE_API {
|
||||
/* 36.213 Table 8.4-2: SRSLTE_RA_PUSCH_HOP_HALF is 0 for < 10 Mhz and 10 for > 10 Mhz.
|
||||
* SRSLTE_RA_PUSCH_HOP_QUART is 00 for > 10 Mhz and SRSLTE_RA_PUSCH_HOP_QUART_NEG is 01 for > 10 Mhz.
|
||||
|
@ -123,57 +161,49 @@ typedef struct SRSLTE_API {
|
|||
SRSLTE_RA_PUSCH_HOP_TYPE2 = 3
|
||||
} freq_hop_fl;
|
||||
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
|
||||
srslte_ra_ul_grant_t prb_alloc;
|
||||
|
||||
srslte_ra_type2_t type2_alloc;
|
||||
uint32_t mcs_idx;
|
||||
srslte_ra_mcs_t mcs;
|
||||
uint32_t rv_idx; // If set to non-zero, a retransmission is requested with the same modulation
|
||||
// than before (SRSLTE_DCI_FORMAT0 message, see also 8.6.1 in 36.2313).
|
||||
|
||||
uint32_t rv_idx;
|
||||
uint32_t n_dmrs;
|
||||
bool ndi;
|
||||
bool cqi_request;
|
||||
|
||||
} srslte_ra_pusch_t;
|
||||
} srslte_ra_ul_dci_t;
|
||||
|
||||
SRSLTE_API void srslte_ra_prb_fprint(FILE *f,
|
||||
srslte_ra_prb_slot_t *prb,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API int srslte_ra_dl_alloc(srslte_ra_dl_alloc_t *prb,
|
||||
srslte_ra_pdsch_t *ra,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API int srslte_ra_ul_alloc(srslte_ra_ul_alloc_t *prb,
|
||||
srslte_ra_pusch_t *ra,
|
||||
uint32_t n_rb_ho,
|
||||
uint32_t nof_prb);
|
||||
/**************************************************
|
||||
* Functions
|
||||
**************************************************/
|
||||
|
||||
SRSLTE_API void srslte_ra_dl_alloc_re(srslte_ra_dl_alloc_t *prb_dist,
|
||||
uint32_t nof_prb,
|
||||
uint32_t nof_ports,
|
||||
uint32_t nof_ctrl_symbols,
|
||||
srslte_cp_t cp);
|
||||
|
||||
SRSLTE_API uint32_t srslte_ra_nprb_dl(srslte_ra_pdsch_t *ra,
|
||||
uint32_t nof_prb);
|
||||
SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t* dci,
|
||||
srslte_ra_dl_grant_t* grant,
|
||||
srslte_cell_t cell,
|
||||
uint32_t sf_idx,
|
||||
uint32_t cfi,
|
||||
bool crc_is_crnti);
|
||||
|
||||
SRSLTE_API uint32_t srslte_ra_nprb_ul(srslte_ra_pusch_t *ra,
|
||||
uint32_t nof_prb);
|
||||
SRSLTE_API void srslte_dl_dci_to_grant_nof_re(srslte_ra_dl_grant_t *grant,
|
||||
srslte_cell_t cell,
|
||||
uint32_t sf_idx,
|
||||
uint32_t nof_ctrl_symbols);
|
||||
|
||||
SRSLTE_API int srslte_ra_mcs_from_idx_dl(uint32_t mcs_idx,
|
||||
uint32_t nof_prb,
|
||||
srslte_ra_mcs_t *mcs);
|
||||
SRSLTE_API int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci,
|
||||
srslte_ra_ul_grant_t *grant,
|
||||
srslte_cell_t cell,
|
||||
uint32_t n_rb_ho,
|
||||
uint32_t N_srs);
|
||||
|
||||
SRSLTE_API int srslte_ra_mcs_from_idx_ul(uint32_t mcs_idx,
|
||||
uint32_t nof_prb,
|
||||
srslte_ra_mcs_t *mcs);
|
||||
|
||||
SRSLTE_API int srslte_ra_tbs_from_idx_format1c(uint32_t tbs_idx);
|
||||
SRSLTE_API 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);
|
||||
|
||||
SRSLTE_API int srslte_ra_tbs_from_idx(uint32_t tbs_idx,
|
||||
uint32_t n_prb);
|
||||
uint32_t n_prb);
|
||||
|
||||
SRSLTE_API int srslte_ra_tbs_to_table_idx(uint32_t tbs,
|
||||
uint32_t n_prb);
|
||||
|
@ -201,11 +231,20 @@ SRSLTE_API uint32_t srslte_ra_type2_ngap(uint32_t nof_prb,
|
|||
SRSLTE_API uint32_t srslte_ra_type1_N_rb(uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API void srslte_ra_pdsch_fprint(FILE *f,
|
||||
srslte_ra_pdsch_t *ra,
|
||||
srslte_ra_dl_dci_t *ra,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API void srslte_ra_dl_grant_fprint(FILE *f,
|
||||
srslte_ra_dl_grant_t *grant);
|
||||
|
||||
SRSLTE_API void srslte_ra_prb_fprint(FILE *f,
|
||||
srslte_ra_dl_grant_t *grant);
|
||||
|
||||
SRSLTE_API void srslte_ra_pusch_fprint(FILE *f,
|
||||
srslte_ra_pusch_t *ra,
|
||||
srslte_ra_ul_dci_t *ra,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API void srslte_ra_ul_grant_fprint(FILE *f,
|
||||
srslte_ra_ul_grant_t *grant);
|
||||
|
||||
#endif /* RB_ALLOC_H_ */
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
#include "srslte/fec/turbocoder.h"
|
||||
#include "srslte/fec/turbodecoder.h"
|
||||
#include "srslte/fec/crc.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/phch/pdsch_cfg.h"
|
||||
#include "srslte/phch/pusch_cfg.h"
|
||||
#include "srslte/phch/uci.h"
|
||||
|
||||
#define SRSLTE_PDSCH_MAX_TDEC_ITERS 5
|
||||
|
@ -58,7 +59,7 @@
|
|||
|
||||
/* DL-SCH AND UL-SCH common functions */
|
||||
typedef struct SRSLTE_API {
|
||||
|
||||
|
||||
uint32_t nof_iterations;
|
||||
float average_nof_iterations;
|
||||
|
||||
|
@ -86,31 +87,42 @@ SRSLTE_API float srslte_sch_average_noi(srslte_sch_t *q);
|
|||
SRSLTE_API uint32_t srslte_sch_last_noi(srslte_sch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_dlsch_encode(srslte_sch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
uint8_t *data,
|
||||
uint8_t *e_bits);
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
uint8_t *e_bits);
|
||||
|
||||
SRSLTE_API int srslte_dlsch_decode(srslte_sch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
float *e_bits,
|
||||
uint8_t *data);
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
float *e_bits,
|
||||
uint8_t *data);
|
||||
|
||||
SRSLTE_API int srslte_ulsch_encode(srslte_sch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
uint8_t *data,
|
||||
uint8_t *g_bits,
|
||||
uint8_t *q_bits);
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
uint8_t *g_bits,
|
||||
uint8_t *q_bits);
|
||||
|
||||
SRSLTE_API int srslte_ulsch_uci_encode(srslte_sch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
uint8_t *data,
|
||||
srslte_uci_data_t uci_data,
|
||||
uint8_t *g_bits,
|
||||
uint8_t *q_bits);
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
srslte_uci_data_t uci_data,
|
||||
uint8_t *g_bits,
|
||||
uint8_t *q_bits);
|
||||
|
||||
SRSLTE_API int srslte_ulsch_decode(srslte_sch_t *q,
|
||||
srslte_harq_t *harq_process,
|
||||
float *e_bits,
|
||||
uint8_t *data);
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
float *e_bits,
|
||||
uint8_t *data);
|
||||
|
||||
SRSLTE_API uint32_t srslte_sch_find_Ioffset_ack(float beta);
|
||||
|
||||
SRSLTE_API uint32_t srslte_sch_find_Ioffset_cqi(float beta);
|
||||
|
||||
SRSLTE_API uint32_t srslte_sch_find_Ioffset_ri(float beta);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* File: softbuffer.h
|
||||
*
|
||||
* Description: Buffer for RX and TX soft bits. This should be provided by MAC.
|
||||
* Provided here basically for the examples.
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SOFTBUFFER_
|
||||
#define SOFTBUFFER_
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_cb;
|
||||
uint32_t buff_size;
|
||||
float **buffer_f;
|
||||
} srslte_softbuffer_rx_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_cb;
|
||||
uint32_t buff_size;
|
||||
uint8_t **buffer_b;
|
||||
} srslte_softbuffer_tx_t;
|
||||
|
||||
SRSLTE_API int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t * q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_softbuffer_rx_reset(srslte_softbuffer_rx_t *p);
|
||||
|
||||
SRSLTE_API void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *p);
|
||||
|
||||
SRSLTE_API int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t * q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_softbuffer_tx_reset(srslte_softbuffer_tx_t *p);
|
||||
|
||||
SRSLTE_API void srslte_softbuffer_tx_free(srslte_softbuffer_tx_t *p);
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -38,14 +38,13 @@
|
|||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/phch/pusch_cfg.h"
|
||||
#include "srslte/fec/crc.h"
|
||||
|
||||
#define SRSLTE_UCI_MAX_CQI_LEN_PUSCH 512
|
||||
#define SRSLTE_UCI_MAX_CQI_LEN_PUCCH 13
|
||||
#define SRSLTE_UCI_CQI_CODED_PUCCH_B 20
|
||||
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_crc_t crc;
|
||||
uint8_t tmp_cqi[SRSLTE_UCI_MAX_CQI_LEN_PUSCH];
|
||||
|
@ -72,28 +71,28 @@ SRSLTE_API int srslte_uci_cqi_init(srslte_uci_cqi_pusch_t *q);
|
|||
SRSLTE_API void srslte_uci_cqi_free(srslte_uci_cqi_pusch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t *q,
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
uint8_t *cqi_data,
|
||||
uint32_t cqi_len,
|
||||
float beta,
|
||||
uint32_t Q_prime_ri,
|
||||
srslte_harq_t *harq_process,
|
||||
uint8_t *q_bits);
|
||||
|
||||
SRSLTE_API int srslte_uci_encode_cqi_pucch(uint8_t *cqi_data,
|
||||
uint32_t cqi_len,
|
||||
uint8_t b_bits[SRSLTE_UCI_CQI_CODED_PUCCH_B]);
|
||||
|
||||
SRSLTE_API int srslte_uci_encode_ack(uint8_t data,
|
||||
uint32_t O_cqi,
|
||||
SRSLTE_API int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
||||
uint8_t data,
|
||||
uint32_t O_cqi,
|
||||
float beta,
|
||||
srslte_harq_t *harq_process,
|
||||
uint32_t H_prime_total,
|
||||
uint8_t *q_bits);
|
||||
|
||||
SRSLTE_API int srslte_uci_encode_ri(uint8_t data,
|
||||
uint32_t O_cqi,
|
||||
SRSLTE_API int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
|
||||
uint8_t data,
|
||||
uint32_t O_cqi,
|
||||
float beta,
|
||||
srslte_harq_t *harq_process,
|
||||
uint32_t H_prime_total,
|
||||
uint8_t *q_bits);
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "srslte/fec/tc_interl.h"
|
||||
#include "srslte/fec/turbocoder.h"
|
||||
#include "srslte/fec/turbodecoder.h"
|
||||
#include "srslte/fec/cbsegm.h"
|
||||
#include "srslte/fec/rm_conv.h"
|
||||
#include "srslte/fec/rm_turbo.h"
|
||||
|
||||
|
@ -87,7 +88,7 @@
|
|||
|
||||
#include "srslte/phch/cqi.h"
|
||||
#include "srslte/phch/dci.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/phch/softbuffer.h"
|
||||
#include "srslte/phch/pbch.h"
|
||||
#include "srslte/phch/pcfich.h"
|
||||
#include "srslte/phch/pdcch.h"
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "srslte/phch/pcfich.h"
|
||||
#include "srslte/phch/pdcch.h"
|
||||
#include "srslte/phch/pdsch.h"
|
||||
#include "srslte/phch/pdsch_cfg.h"
|
||||
#include "srslte/phch/phich.h"
|
||||
#include "srslte/phch/ra.h"
|
||||
#include "srslte/phch/regs.h"
|
||||
|
@ -58,19 +59,17 @@
|
|||
|
||||
#include "srslte/config.h"
|
||||
|
||||
#define SRSLTE_UE_UL_NOF_HARQ_PROCESSES 8
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_pcfich_t pcfich;
|
||||
srslte_pdcch_t pdcch;
|
||||
srslte_pdsch_t pdsch;
|
||||
srslte_phich_t phich;
|
||||
srslte_harq_t harq_process[SRSLTE_UE_UL_NOF_HARQ_PROCESSES];
|
||||
srslte_regs_t regs;
|
||||
srslte_ofdm_t fft;
|
||||
srslte_chest_dl_t chest;
|
||||
|
||||
srslte_ra_pdsch_t ra_dl;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_softbuffer_rx_t softbuffer;
|
||||
|
||||
srslte_cell_t cell;
|
||||
|
||||
|
|
|
@ -82,8 +82,8 @@ public:
|
|||
uint32_t get_harq_process();
|
||||
private:
|
||||
union {
|
||||
srslte_ra_pusch_t ul_grant;
|
||||
srslte_ra_pdsch_t dl_grant;
|
||||
srslte_ra_ul_dci_t ul_grant;
|
||||
srslte_ra_dl_dci_t dl_grant;
|
||||
};
|
||||
direction_t dir;
|
||||
};
|
||||
|
|
|
@ -63,8 +63,10 @@ typedef struct SRSLTE_API {
|
|||
|
||||
float current_cfo;
|
||||
|
||||
srslte_pusch_cfg_t pusch_cfg;
|
||||
srslte_refsignal_ul_t dmrs;
|
||||
srslte_harq_t harq_process[SRSLTE_UE_UL_NOF_HARQ_PROCESSES];
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
|
||||
srslte_pusch_t pusch;
|
||||
srslte_pucch_t pucch;
|
||||
|
||||
|
@ -103,33 +105,44 @@ SRSLTE_API int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q,
|
|||
cf_t *output_signal);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q,
|
||||
srslte_ra_pusch_t *ra_ul,
|
||||
srslte_ra_ul_grant_t *grant,
|
||||
uint8_t *data,
|
||||
uint32_t sf_idx,
|
||||
uint32_t rv,
|
||||
cf_t *output_signal);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q,
|
||||
srslte_ra_pusch_t *ra_ul,
|
||||
srslte_ra_ul_grant_t *grant,
|
||||
uint8_t *data,
|
||||
uint32_t sf_idx,
|
||||
uint32_t rv,
|
||||
uint16_t rnti,
|
||||
cf_t *output_signal);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q,
|
||||
srslte_ra_pusch_t *ra_ul,
|
||||
srslte_ra_ul_grant_t *grant,
|
||||
uint8_t *data,
|
||||
srslte_uci_data_t uci_data,
|
||||
uint32_t sf_idx,
|
||||
uint32_t rv,
|
||||
cf_t *output_signal);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q,
|
||||
srslte_ra_pusch_t *ra_ul,
|
||||
srslte_ra_ul_grant_t *grant,
|
||||
uint8_t *data,
|
||||
srslte_uci_data_t uci_data,
|
||||
uint32_t sf_idx,
|
||||
uint32_t rv,
|
||||
uint16_t rnti,
|
||||
cf_t *output_signal);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q,
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
uint8_t *data,
|
||||
srslte_uci_data_t uci_data,
|
||||
uint16_t rnti,
|
||||
cf_t *output_signal);
|
||||
|
||||
SRSLTE_API void srslte_ue_ul_reset(srslte_ue_ul_t *q);
|
||||
|
||||
SRSLTE_API void srslte_ue_ul_set_rnti(srslte_ue_ul_t *q,
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/ue_itf/queue.h"
|
||||
#include "srslte/ue_itf/sched_grant.h"
|
||||
#include "srslte/ue_itf/ul_sched_grant.h"
|
||||
#include "srslte/ue_itf/dl_sched_grant.h"
|
||||
#include "srslte/ue_itf/phy_params.h"
|
||||
|
||||
#ifndef UEDLBUFFER_H
|
||||
|
@ -64,10 +65,11 @@ namespace ue {
|
|||
bool init_cell(srslte_cell_t cell, phy_params *params_db);
|
||||
void free_cell();
|
||||
bool recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time);
|
||||
bool get_ul_grant(pdcch_ul_search_t mode, sched_grant *grant);
|
||||
bool get_dl_grant(pdcch_dl_search_t mode, sched_grant *grant);
|
||||
bool decode_ack(srslte::ue::sched_grant pusch_grant);
|
||||
bool decode_data(sched_grant pdsch_grant, uint8_t *payload); // returns true or false for CRC OK/KO
|
||||
bool get_ul_grant(pdcch_ul_search_t mode, ul_sched_grant *grant);
|
||||
bool get_dl_grant(pdcch_dl_search_t mode, dl_sched_grant *grant);
|
||||
bool decode_ack(ul_sched_grant *pusch_grant);
|
||||
bool decode_data(dl_sched_grant *pdsch_grant, uint8_t *payload); // returns true or false for CRC OK/NOK
|
||||
|
||||
private:
|
||||
phy_params *params_db;
|
||||
srslte_cell_t cell;
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <string.h>
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/ue_itf/sched_grant.h"
|
||||
|
||||
#ifndef UEDLSCHEDGRANT_H
|
||||
#define UEDLSCHEDGRANT_H
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
/* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */
|
||||
class SRSLTE_API dl_sched_grant : public sched_grant {
|
||||
public:
|
||||
|
||||
dl_sched_grant(uint16_t rnti) : sched_grant(rnti) {}
|
||||
|
||||
uint32_t get_rv() {
|
||||
return dl_dci.rv_idx;
|
||||
}
|
||||
void set_rv(uint32_t rv) {
|
||||
dl_dci.rv_idx = rv;
|
||||
}
|
||||
bool get_ndi() {
|
||||
return dl_dci.ndi;
|
||||
}
|
||||
void set_ndi(bool value) {
|
||||
dl_dci.ndi = value;
|
||||
}
|
||||
uint32_t get_harq_process() {
|
||||
return dl_dci.harq_process;
|
||||
}
|
||||
void get_dl_grant(srslte_ra_dl_grant_t *ul_grant) {
|
||||
memcpy(ul_grant, &grant, sizeof(srslte_ra_dl_grant_t));
|
||||
}
|
||||
bool is_sps_release() {
|
||||
return false;
|
||||
}
|
||||
uint32_t get_tbs() {
|
||||
return grant.mcs.tbs;
|
||||
}
|
||||
uint32_t get_ncce() {
|
||||
return ncce;
|
||||
}
|
||||
bool create_from_dci(srslte_dci_msg_t *msg, srslte_cell_t cell, uint32_t cfi, uint32_t sf_idx, uint32_t ncce_) {
|
||||
ncce = ncce_;
|
||||
if (srslte_dci_msg_to_dl_grant(msg, rnti, cell, cfi, sf_idx, &dl_dci, &grant)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void get_pdsch_cfg(uint32_t sf_idx, srslte_pdsch_cfg_t *cfg) {
|
||||
srslte_cbsegm(&cfg->cb_segm, grant.mcs.tbs);
|
||||
memcpy(&cfg->grant, &grant, sizeof(srslte_ra_dl_grant_t));
|
||||
cfg->sf_idx = sf_idx;
|
||||
cfg->rv = dl_dci.rv_idx;
|
||||
}
|
||||
private:
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_dl_dci_t dl_dci;
|
||||
uint32_t ncce;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -59,7 +59,11 @@ typedef _Complex float cf_t;
|
|||
class SRSLTE_API phy
|
||||
{
|
||||
public:
|
||||
|
||||
phy() {
|
||||
started = false;
|
||||
is_sfn_synched = false;
|
||||
cell_is_set = false;
|
||||
}
|
||||
bool init(radio *radio_handler, tti_sync *ttisync);
|
||||
void stop();
|
||||
|
||||
|
@ -87,7 +91,7 @@ public:
|
|||
void set_timeadv(uint32_t ta_cmd);
|
||||
|
||||
// Generate Msg3 UL grant from RAR
|
||||
void rar_ul_grant(uint32_t rba, uint32_t trunc_mcs, bool hopping_flag, sched_grant *grant);
|
||||
void rar_ul_grant(srslte_dci_rar_grant_t *rar, ul_sched_grant *grant);
|
||||
|
||||
// Get status
|
||||
bool status_is_idle();
|
||||
|
@ -114,8 +118,8 @@ private:
|
|||
|
||||
srslte_cell_t cell;
|
||||
bool cell_is_set;
|
||||
bool is_sfn_synched = false;
|
||||
bool started = false;
|
||||
bool is_sfn_synched;
|
||||
bool started;
|
||||
|
||||
srslte_ue_sync_t ue_sync;
|
||||
srslte_ue_mib_t ue_mib;
|
||||
|
|
|
@ -38,6 +38,11 @@ namespace ue {
|
|||
|
||||
class SRSLTE_API prach {
|
||||
public:
|
||||
prach() {
|
||||
params_db = NULL;
|
||||
initiated = false;
|
||||
signal_buffer = NULL;
|
||||
}
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db);
|
||||
void free_cell();
|
||||
bool prepare_to_send(uint32_t preamble_idx);
|
||||
|
@ -51,7 +56,7 @@ namespace ue {
|
|||
bool initiated = false;
|
||||
uint32_t len;
|
||||
cf_t *buffer[64];
|
||||
srslte_prach_t prach;
|
||||
srslte_prach_t prach_obj;
|
||||
uint32_t transmitted_tti;
|
||||
srslte_cell_t cell;
|
||||
cf_t *signal_buffer;
|
||||
|
|
|
@ -37,34 +37,20 @@ namespace ue {
|
|||
/* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */
|
||||
class SRSLTE_API sched_grant {
|
||||
public:
|
||||
|
||||
typedef enum {DOWNLINK=0, UPLINK=1} direction_t;
|
||||
sched_grant(direction_t direction, uint16_t rnti);
|
||||
uint16_t get_rnti();
|
||||
uint32_t get_rv();
|
||||
void set_rv(uint32_t rv);
|
||||
bool get_ndi();
|
||||
void set_ndi(bool value);
|
||||
bool get_cqi_request();
|
||||
int get_harq_process();
|
||||
bool is_uplink();
|
||||
bool is_downlink();
|
||||
void* get_grant_ptr();
|
||||
bool is_sps_release();
|
||||
void set_ncce(uint32_t ncce);
|
||||
uint32_t get_ncce();
|
||||
uint32_t get_tbs();
|
||||
uint32_t get_current_tx_nb();
|
||||
void set_current_tx_nb(uint32_t current_tx_nb);
|
||||
sched_grant(uint16_t rnti_) {
|
||||
rnti = rnti_;
|
||||
}
|
||||
uint16_t get_rnti() {
|
||||
return rnti;
|
||||
}
|
||||
virtual uint32_t get_rv() = 0;
|
||||
virtual void set_rv(uint32_t rv) = 0;
|
||||
virtual bool get_ndi() = 0;
|
||||
virtual void set_ndi(bool value) = 0;
|
||||
virtual bool is_sps_release() = 0;
|
||||
virtual uint32_t get_tbs() = 0;
|
||||
protected:
|
||||
union {
|
||||
srslte_ra_pusch_t ul_grant;
|
||||
srslte_ra_pdsch_t dl_grant;
|
||||
};
|
||||
uint32_t current_tx_nb;
|
||||
direction_t dir;
|
||||
uint16_t rnti;
|
||||
uint32_t ncce;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
#include "srslte/srslte.h"
|
||||
#include "srslte/common/radio.h"
|
||||
#include "srslte/ue_itf/queue.h"
|
||||
#include "srslte/ue_itf/sched_grant.h"
|
||||
#include "srslte/ue_itf/ul_sched_grant.h"
|
||||
#include "srslte/ue_itf/dl_sched_grant.h"
|
||||
#include "srslte/ue_itf/phy_params.h"
|
||||
|
||||
#ifndef UEULBUFFER_H
|
||||
|
@ -48,26 +49,27 @@ namespace ue {
|
|||
void free_cell();
|
||||
void set_tti(uint32_t tti);
|
||||
void set_current_tx_nb(uint32_t current_tx_nb);
|
||||
bool generate_ack(bool ack, sched_grant last_dl_grant);
|
||||
bool generate_ack(bool ack, dl_sched_grant *last_dl_grant);
|
||||
bool generate_ack(bool ack[2]);
|
||||
bool generate_sr();
|
||||
bool generate_cqi_report();
|
||||
bool uci_ready();
|
||||
bool generate_data();
|
||||
bool generate_data(sched_grant pusch_grant, uint8_t *payload);
|
||||
bool generate_data(ul_sched_grant *pusch_grant, uint8_t *payload);
|
||||
bool send(radio* radio_handler, float time_adv_sec, float cfo, srslte_timestamp_t rx_time);
|
||||
static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission
|
||||
|
||||
private:
|
||||
phy_params *params_db;
|
||||
srslte_cell_t cell;
|
||||
srslte_ue_ul_t ue_ul;
|
||||
bool cell_initiated;
|
||||
cf_t* signal_buffer;
|
||||
uint32_t current_tx_nb;
|
||||
uint32_t last_n_cce;
|
||||
srslte_uci_data_t uci_data;
|
||||
bool uci_pending;
|
||||
phy_params *params_db;
|
||||
srslte_cell_t cell;
|
||||
srslte_ue_ul_t ue_ul;
|
||||
srslte_pusch_cfg_t pusch_cfg;
|
||||
bool cell_initiated;
|
||||
cf_t* signal_buffer;
|
||||
uint32_t current_tx_nb;
|
||||
uint32_t last_n_cce;
|
||||
srslte_uci_data_t uci_data;
|
||||
bool uci_pending;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <string.h>
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/ue_itf/sched_grant.h"
|
||||
|
||||
#ifndef UEULSCHEDGRANT_H
|
||||
#define UEULSCHEDGRANT_H
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
/* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */
|
||||
class SRSLTE_API ul_sched_grant : public sched_grant {
|
||||
public:
|
||||
|
||||
ul_sched_grant(uint16_t rnti) : sched_grant(rnti) {}
|
||||
|
||||
uint32_t get_rv() {
|
||||
return ul_dci.rv_idx;
|
||||
}
|
||||
void set_rv(uint32_t rv) {
|
||||
ul_dci.rv_idx = rv;
|
||||
}
|
||||
bool get_ndi() {
|
||||
return ul_dci.ndi;
|
||||
}
|
||||
void set_ndi(bool value) {
|
||||
ul_dci.ndi = value;
|
||||
}
|
||||
bool get_cqi_request() {
|
||||
return ul_dci.cqi_request;
|
||||
}
|
||||
void get_ul_grant(srslte_ra_ul_grant_t *ul_grant) {
|
||||
memcpy(ul_grant, &grant, sizeof(srslte_ra_ul_grant_t));
|
||||
}
|
||||
bool is_sps_release() {
|
||||
return false;
|
||||
}
|
||||
uint32_t get_tbs() {
|
||||
return grant.mcs.tbs;
|
||||
}
|
||||
uint32_t get_current_tx_nb() {
|
||||
return current_tx_nb;
|
||||
}
|
||||
void set_current_tx_nb(uint32_t current_tx_nb) {
|
||||
current_tx_nb = current_tx_nb;
|
||||
}
|
||||
uint32_t get_I_lowest() {
|
||||
return grant.n_prb[0];
|
||||
}
|
||||
uint32_t get_n_dmrs() {
|
||||
return ul_dci.n_dmrs;
|
||||
}
|
||||
bool create_from_dci(srslte_dci_msg_t *msg, srslte_cell_t cell, uint32_t N_srs, uint32_t n_rb_ho) {
|
||||
if (srslte_dci_msg_to_ul_grant(msg, cell, N_srs, n_rb_ho, &ul_dci, &grant)) {
|
||||
return false;
|
||||
} else {
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pusch_fprint(stdout, &ul_dci, cell.nof_prb);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool create_from_rar(srslte_dci_rar_grant_t *rar, srslte_cell_t cell, uint32_t N_srs, uint32_t n_rb_ho) {
|
||||
if (srslte_dci_rar_to_ul_grant(rar, cell, N_srs, n_rb_ho, &ul_dci, &grant)) {
|
||||
return false;
|
||||
} else {
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pusch_fprint(stdout, &ul_dci, cell.nof_prb);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void to_pusch_cfg(uint32_t sf_idx, srslte_cp_t cp, srslte_pusch_cfg_t *cfg) {
|
||||
srslte_cbsegm(&cfg->cb_segm, grant.mcs.tbs);
|
||||
cfg->cp = cp;
|
||||
memcpy(&cfg->grant, &grant, sizeof(srslte_ra_ul_grant_t));
|
||||
cfg->rv = ul_dci.rv_idx;
|
||||
cfg->sf_idx = sf_idx;
|
||||
}
|
||||
private:
|
||||
srslte_ra_ul_grant_t grant;
|
||||
srslte_ra_ul_dci_t ul_dci;
|
||||
uint32_t current_tx_nb;
|
||||
uint16_t rnti;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -85,7 +85,7 @@ int main(int argc, char **argv) {
|
|||
srslte_chest_dl_t est;
|
||||
srslte_precoding_t cheq;
|
||||
cf_t *input = NULL, *ce = NULL, *h = NULL, *output = NULL;
|
||||
int i, j, n_port, sf_idx, cid, num_re;
|
||||
int i, j, n_port=0, sf_idx=0, cid=0, num_re;
|
||||
int ret = -1;
|
||||
int max_cid;
|
||||
FILE *fmatlab = NULL;
|
||||
|
|
|
@ -35,21 +35,6 @@
|
|||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/common/sequence.h"
|
||||
|
||||
const uint32_t tc_cb_sizes[SRSLTE_NOF_TC_CB_SIZES] = { 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
|
||||
128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232,
|
||||
240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320, 328, 336, 344,
|
||||
352, 360, 368, 376, 384, 392, 400, 408, 416, 424, 432, 440, 448, 456,
|
||||
464, 472, 480, 488, 496, 504, 512, 528, 544, 560, 576, 592, 608, 624,
|
||||
640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848,
|
||||
864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1056, 1088,
|
||||
1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472,
|
||||
1504, 1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856,
|
||||
1888, 1920, 1952, 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432,
|
||||
2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200,
|
||||
3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968,
|
||||
4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736,
|
||||
4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504,
|
||||
5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144 };
|
||||
|
||||
/* Returns true if the structure pointed by cell has valid parameters
|
||||
*/
|
||||
|
@ -135,27 +120,6 @@ bool srslte_N_id_1_isvalid(uint32_t N_id_1) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns Turbo coder interleaver size for Table 5.1.3-3 (36.212) index
|
||||
*/
|
||||
int srslte_cb_size(uint32_t index) {
|
||||
if (index < SRSLTE_NOF_TC_CB_SIZES) {
|
||||
return (int) tc_cb_sizes[index];
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
bool srslte_cb_size_isvalid(uint32_t size) {
|
||||
for (int i=0;i<SRSLTE_NOF_TC_CB_SIZES;i++) {
|
||||
if (tc_cb_sizes[i] == size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
char *srslte_mod_string(srslte_mod_t mod) {
|
||||
switch (mod) {
|
||||
case SRSLTE_MOD_BPSK:
|
||||
|
@ -219,21 +183,6 @@ uint32_t srslte_N_ta_new_rar(uint32_t ta) {
|
|||
return ta*16;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds index of minimum K>=long_cb in Table 5.1.3-3 of 36.212
|
||||
*/
|
||||
int srslte_find_cb_index(uint32_t long_cb) {
|
||||
int j = 0;
|
||||
while (j < SRSLTE_NOF_TC_CB_SIZES && tc_cb_sizes[j] < long_cb) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j == SRSLTE_NOF_TC_CB_SIZES) {
|
||||
return SRSLTE_ERROR;
|
||||
} else {
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
int srslte_sampling_freq_hz(uint32_t nof_prb) {
|
||||
int n = srslte_symbol_sz(nof_prb);
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <strings.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "srslte/fec/turbodecoder.h"
|
||||
#include "srslte/fec/cbsegm.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
|
||||
|
||||
const uint32_t tc_cb_sizes[SRSLTE_NOF_TC_CB_SIZES] = { 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
|
||||
128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232,
|
||||
240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320, 328, 336, 344,
|
||||
352, 360, 368, 376, 384, 392, 400, 408, 416, 424, 432, 440, 448, 456,
|
||||
464, 472, 480, 488, 496, 504, 512, 528, 544, 560, 576, 592, 608, 624,
|
||||
640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848,
|
||||
864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1056, 1088,
|
||||
1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472,
|
||||
1504, 1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856,
|
||||
1888, 1920, 1952, 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432,
|
||||
2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200,
|
||||
3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968,
|
||||
4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736,
|
||||
4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504,
|
||||
5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144 };
|
||||
|
||||
/* Calculate Codeblock Segmentation as in Section 5.1.2 of 36.212 */
|
||||
int srslte_cbsegm(srslte_cbsegm_t *s, uint32_t tbs) {
|
||||
uint32_t Bp, B, idx1;
|
||||
int ret;
|
||||
|
||||
if (tbs == 0) {
|
||||
bzero(s, sizeof(srslte_cbsegm_t));
|
||||
ret = SRSLTE_SUCCESS;
|
||||
} else {
|
||||
B = tbs + 24;
|
||||
s->tbs = tbs;
|
||||
|
||||
/* Calculate CB sizes */
|
||||
if (B <= SRSLTE_TCOD_MAX_LEN_CB) {
|
||||
s->C = 1;
|
||||
Bp = B;
|
||||
} else {
|
||||
s->C = (uint32_t) ceilf((float) B / (SRSLTE_TCOD_MAX_LEN_CB - 24));
|
||||
Bp = B + 24 * s->C;
|
||||
}
|
||||
ret = srslte_cbsegm_cbindex((Bp-1) / s->C + 1);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
idx1 = (uint32_t) ret;
|
||||
ret = srslte_cbsegm_cbsize(idx1);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
s->K1 = (uint32_t) ret;
|
||||
if (idx1 > 0) {
|
||||
ret = srslte_cbsegm_cbsize(idx1 - 1);
|
||||
}
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
if (s->C == 1) {
|
||||
s->K2 = 0;
|
||||
s->C2 = 0;
|
||||
s->C1 = 1;
|
||||
} else {
|
||||
s->K2 = (uint32_t) ret;
|
||||
s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2);
|
||||
s->C1 = s->C - s->C2;
|
||||
}
|
||||
s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp;
|
||||
INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n",
|
||||
tbs, s->C, s->C1, s->K1, s->C2, s->K2, s->F, Bp);
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds index of minimum K>=long_cb in Table 5.1.3-3 of 36.212
|
||||
*/
|
||||
int srslte_cbsegm_cbindex(uint32_t long_cb) {
|
||||
int j = 0;
|
||||
while (j < SRSLTE_NOF_TC_CB_SIZES && tc_cb_sizes[j] < long_cb) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j == SRSLTE_NOF_TC_CB_SIZES) {
|
||||
return SRSLTE_ERROR;
|
||||
} else {
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns Turbo coder interleaver size for Table 5.1.3-3 (36.212) index
|
||||
*/
|
||||
int srslte_cbsegm_cbsize(uint32_t index) {
|
||||
if (index < SRSLTE_NOF_TC_CB_SIZES) {
|
||||
return (int) tc_cb_sizes[index];
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
bool srslte_cbsegm_cbsize_isvalid(uint32_t size) {
|
||||
for (int i=0;i<SRSLTE_NOF_TC_CB_SIZES;i++) {
|
||||
if (tc_cb_sizes[i] == size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -32,6 +32,7 @@
|
|||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/fec/tc_interl.h"
|
||||
#include "srslte/fec/turbocoder.h"
|
||||
#include "srslte/fec/cbsegm.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
|
||||
/************************************************
|
||||
|
@ -76,7 +77,7 @@ int srslte_tc_interl_LTE_gen(srslte_tc_interl_t *h, uint32_t long_cb) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
cb_table_idx = srslte_find_cb_index(long_cb);
|
||||
cb_table_idx = srslte_cbsegm_cbindex(long_cb);
|
||||
if (cb_table_idx == -1) {
|
||||
fprintf(stderr, "Can't find long_cb=%d in valid TC CB table\n", long_cb);
|
||||
return -1;
|
||||
|
|
|
@ -68,8 +68,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
trblklen = (uint32_t) mxGetScalar(TRBLKLEN);
|
||||
rvidx = (uint32_t) mxGetScalar(RV);
|
||||
|
||||
srslte_harq_cbsegm_t cbsegm;
|
||||
srslte_harq_codeblock_segmentation(&cbsegm, trblklen);
|
||||
srslte_cbsegm_t cbsegm;
|
||||
srslte_cbsegm(&cbsegm, trblklen);
|
||||
cblen = 3*cbsegm.K1+12;
|
||||
|
||||
w_buff_f = calloc(1,sizeof(float) * cblen * 10);
|
||||
|
|
|
@ -152,7 +152,7 @@ int main(int argc, char **argv) {
|
|||
if (test_known_data) {
|
||||
frame_length = KNOWN_DATA_LEN;
|
||||
} else {
|
||||
frame_length = srslte_cb_size(srslte_find_cb_index(frame_length));
|
||||
frame_length = srslte_cbsegm_cbsize(srslte_cbsegm_cbindex(frame_length));
|
||||
}
|
||||
|
||||
coded_length = 3 * (frame_length) + SRSLTE_TCOD_TOTALTAIL;
|
||||
|
|
|
@ -66,7 +66,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
nof_bits = (nof_symbols-12)/3;
|
||||
|
||||
if (!srslte_cb_size_isvalid(nof_bits)) {
|
||||
if (!srslte_cbsegm_cbsize_isvalid(nof_bits)) {
|
||||
mexErrMsgTxt("Invalid codeblock size\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -41,23 +41,25 @@
|
|||
#include "srslte/utils/debug.h"
|
||||
|
||||
|
||||
/* Creates the DL PDSCH resource allocation grant from a DCI message
|
||||
/* Unpacks a DCI message and configures the DL grant object
|
||||
*/
|
||||
int srslte_dci_msg_to_ra_dl(srslte_dci_msg_t *msg, uint16_t msg_rnti,
|
||||
srslte_cell_t cell, uint32_t cfi,
|
||||
srslte_ra_pdsch_t *ra_dl)
|
||||
int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti,
|
||||
srslte_cell_t cell, uint32_t cfi, uint32_t sf_idx,
|
||||
srslte_ra_dl_dci_t *dl_dci,
|
||||
srslte_ra_dl_grant_t *grant)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (msg != NULL &&
|
||||
ra_dl != NULL &&
|
||||
srslte_cell_isvalid(&cell) &&
|
||||
grant != NULL &&
|
||||
srslte_cell_isvalid(&cell) &&
|
||||
cfi > 0 &&
|
||||
cfi < 4)
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
srslte_dci_msg_type_t type;
|
||||
|
||||
if (srslte_dci_msg_get_type(msg, &type, cell.nof_prb, msg_rnti)) {
|
||||
fprintf(stderr, "Can't get DCI message type\n");
|
||||
return ret;
|
||||
|
@ -68,28 +70,25 @@ int srslte_dci_msg_to_ra_dl(srslte_dci_msg_t *msg, uint16_t msg_rnti,
|
|||
srslte_dci_msg_type_fprint(stdout, type);
|
||||
}
|
||||
if (type.type == SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED) {
|
||||
bzero(ra_dl, sizeof(srslte_ra_pdsch_t));
|
||||
bzero(dl_dci, sizeof(srslte_ra_dl_dci_t));
|
||||
bzero(grant, sizeof(srslte_ra_dl_grant_t));
|
||||
|
||||
bool crc_is_crnti = false;
|
||||
if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) {
|
||||
crc_is_crnti = true;
|
||||
}
|
||||
if (srslte_dci_msg_unpack_pdsch(msg, ra_dl, cell.nof_prb, crc_is_crnti)) {
|
||||
if (srslte_dci_msg_unpack_pdsch(msg, dl_dci, cell.nof_prb, crc_is_crnti)) {
|
||||
fprintf(stderr, "Can't unpack PDSCH message\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
srslte_ra_dl_dci_to_grant(dl_dci, grant, cell, sf_idx, cfi, crc_is_crnti);
|
||||
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pdsch_fprint(stdout, ra_dl, cell.nof_prb);
|
||||
srslte_ra_pdsch_fprint(stdout, dl_dci, cell.nof_prb);
|
||||
srslte_ra_dl_grant_fprint(stdout, grant);
|
||||
}
|
||||
|
||||
if (srslte_ra_dl_alloc(&ra_dl->prb_alloc, ra_dl, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error computing resource allocation\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
srslte_ra_dl_alloc_re(&ra_dl->prb_alloc, cell.nof_prb, cell.nof_ports, cell.nof_prb<10?(cfi+1):cfi, cell.cp);
|
||||
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
} else {
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
|
@ -103,58 +102,77 @@ int srslte_dci_msg_to_ra_dl(srslte_dci_msg_t *msg, uint16_t msg_rnti,
|
|||
|
||||
/* Creates the UL PUSCH resource allocation grant from the random access respone message
|
||||
*/
|
||||
int srslte_dci_rar_to_ra_ul(uint32_t rba, uint32_t trunc_mcs, bool hopping_flag, uint32_t nof_prb, srslte_ra_pusch_t *ra) {
|
||||
bzero(ra, sizeof(srslte_ra_pusch_t));
|
||||
if (!hopping_flag) {
|
||||
ra->freq_hop_fl = SRSLTE_RA_PUSCH_HOP_DISABLED;
|
||||
int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, srslte_cell_t cell,
|
||||
uint32_t N_srs, uint32_t n_rb_ho,
|
||||
srslte_ra_ul_dci_t *ul_dci,
|
||||
srslte_ra_ul_grant_t *grant)
|
||||
{
|
||||
bzero(ul_dci, sizeof(srslte_ra_ul_dci_t));
|
||||
|
||||
if (!rar->hopping_flag) {
|
||||
ul_dci->freq_hop_fl = SRSLTE_RA_PUSCH_HOP_DISABLED;
|
||||
} else {
|
||||
fprintf(stderr, "FIXME: Frequency hopping in RAR not implemented\n");
|
||||
ra->freq_hop_fl = 1;
|
||||
ul_dci->freq_hop_fl = 1;
|
||||
}
|
||||
uint32_t riv = rba;
|
||||
uint32_t riv = rar->rba;
|
||||
// Truncate resource block assignment
|
||||
uint32_t b = 0;
|
||||
if (nof_prb <= 44) {
|
||||
b = (uint32_t) (ceilf(log2((float) nof_prb*(nof_prb+1)/2)));
|
||||
if (cell.nof_prb <= 44) {
|
||||
b = (uint32_t) (ceilf(log2((float) cell.nof_prb*(cell.nof_prb+1)/2)));
|
||||
riv = riv & ((1<<(b+1))-1);
|
||||
}
|
||||
ra->type2_alloc.riv = riv;
|
||||
ra->mcs_idx = trunc_mcs;
|
||||
ul_dci->type2_alloc.riv = riv;
|
||||
ul_dci->mcs_idx = rar->trunc_mcs;
|
||||
|
||||
srslte_ra_type2_from_riv(riv, &ra->type2_alloc.L_crb, &ra->type2_alloc.RB_start,
|
||||
nof_prb, nof_prb);
|
||||
srslte_ra_type2_from_riv(riv, &ul_dci->type2_alloc.L_crb, &ul_dci->type2_alloc.RB_start,
|
||||
cell.nof_prb, cell.nof_prb);
|
||||
|
||||
srslte_ra_mcs_from_idx_ul(ra->mcs_idx, srslte_ra_nprb_ul(ra, nof_prb), &ra->mcs);
|
||||
if (srslte_ra_ul_dci_to_grant(ul_dci, grant, cell, n_rb_ho, N_srs)) {
|
||||
fprintf(stderr, "Error computing resource allocation\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pusch_fprint(stdout, ul_dci, cell.nof_prb);
|
||||
srslte_ra_ul_grant_fprint(stdout, grant);
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Creates the UL PUSCH resource allocation grant from a DCI format 0 message
|
||||
*/
|
||||
int srslte_dci_msg_to_ra_ul(srslte_dci_msg_t *msg, uint32_t nof_prb, uint32_t n_rb_ho, srslte_ra_pusch_t *ra_ul)
|
||||
int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, srslte_cell_t cell,
|
||||
uint32_t N_srs, uint32_t n_rb_ho,
|
||||
srslte_ra_ul_dci_t *ul_dci,
|
||||
srslte_ra_ul_grant_t *grant)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (msg != NULL &&
|
||||
ra_ul != NULL)
|
||||
srslte_cell_isvalid(&cell) &&
|
||||
grant != NULL)
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
bzero(ra_ul, sizeof(srslte_ra_pusch_t));
|
||||
bzero(ul_dci, sizeof(srslte_ra_ul_dci_t));
|
||||
bzero(grant, sizeof(srslte_ra_ul_dci_t));
|
||||
|
||||
if (srslte_dci_msg_unpack_pusch(msg, ra_ul, nof_prb)) {
|
||||
if (srslte_dci_msg_unpack_pusch(msg, ul_dci, cell.nof_prb)) {
|
||||
fprintf(stderr, "Can't unpack PDSCH message\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pusch_fprint(stdout, ra_ul, nof_prb);
|
||||
}
|
||||
|
||||
if (srslte_ra_ul_alloc(&ra_ul->prb_alloc, ra_ul, n_rb_ho, nof_prb)) {
|
||||
if (srslte_ra_ul_dci_to_grant(ul_dci, grant, cell, n_rb_ho, N_srs)) {
|
||||
fprintf(stderr, "Error computing resource allocation\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pusch_fprint(stdout, ul_dci, cell.nof_prb);
|
||||
srslte_ra_ul_grant_fprint(stdout, grant);
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
|
@ -275,7 +293,7 @@ uint32_t srslte_dci_format_sizeof(srslte_dci_format_t format, uint32_t nof_prb)
|
|||
*
|
||||
* TODO: TPC and cyclic shift for DM RS not implemented
|
||||
*/
|
||||
int dci_format0_pack(srslte_ra_pusch_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
int dci_format0_pack(srslte_ra_ul_dci_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
|
||||
/* pack bits */
|
||||
uint8_t *y = msg->data;
|
||||
|
@ -337,7 +355,7 @@ int dci_format0_pack(srslte_ra_pusch_t *data, srslte_dci_msg_t *msg, uint32_t no
|
|||
*
|
||||
* TODO: TPC and cyclic shift for DM RS not implemented
|
||||
*/
|
||||
int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_pusch_t *data, uint32_t nof_prb) {
|
||||
int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t nof_prb) {
|
||||
|
||||
/* pack bits */
|
||||
uint8_t *y = msg->data;
|
||||
|
@ -384,19 +402,6 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_pusch_t *data, uint32_t
|
|||
// CQI request
|
||||
data->cqi_request = *y++ ? true : false;
|
||||
|
||||
// 8.6.2 First paragraph
|
||||
if (data->mcs_idx <= 28) {
|
||||
srslte_ra_mcs_from_idx_ul(data->mcs_idx, srslte_ra_nprb_ul(data, nof_prb), &data->mcs);
|
||||
} else if (data->mcs_idx == 29 && data->cqi_request && srslte_ra_nprb_ul(data, nof_prb) <= 4) {
|
||||
// 8.6.1 and 8.6.2 36.213 second paragraph
|
||||
data->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
data->mcs.tbs = 0;
|
||||
} else if (data->mcs_idx >= 29) {
|
||||
// Else leave TBS and use the previously used PUSCH modulation
|
||||
data->mcs.tbs = 0;
|
||||
data->rv_idx = data->mcs_idx - 28;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -406,7 +411,7 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_pusch_t *data, uint32_t
|
|||
* TODO: TPC commands
|
||||
*/
|
||||
|
||||
int dci_format1_pack(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
int dci_format1_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
|
||||
/* pack bits */
|
||||
uint8_t *y = msg->data;
|
||||
|
@ -459,7 +464,7 @@ int dci_format1_pack(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, uint32_t no
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t nof_prb) {
|
||||
int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t nof_prb) {
|
||||
|
||||
/* pack bits */
|
||||
uint8_t *y = msg->data;
|
||||
|
@ -496,10 +501,6 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t
|
|||
}
|
||||
/* unpack MCS according to 7.1.7 of 36.213 */
|
||||
data->mcs_idx = srslte_bit_unpack(&y, 5);
|
||||
if (srslte_ra_mcs_from_idx_dl(data->mcs_idx, srslte_ra_nprb_dl(data, nof_prb), &data->mcs)) {
|
||||
fprintf(stderr, "Error getting MCS\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
/* harq process number */
|
||||
data->harq_process = srslte_bit_unpack(&y, 3);
|
||||
|
@ -510,6 +511,9 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t
|
|||
data->rv_idx = srslte_bit_unpack(&y, 2);
|
||||
|
||||
// TPC not implemented
|
||||
|
||||
data->dci_format = SRSLTE_RA_DCI_FORMAT1;
|
||||
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
@ -518,7 +522,7 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t
|
|||
*
|
||||
* TODO: RA procedure initiated by PDCCH, TPC commands
|
||||
*/
|
||||
int dci_format1As_pack(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb,
|
||||
int dci_format1As_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb,
|
||||
bool crc_is_crnti) {
|
||||
|
||||
/* pack bits */
|
||||
|
@ -604,7 +608,7 @@ int dci_format1As_pack(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, uint32_t
|
|||
/* Unpacks DCI format 1A for compact scheduling of PDSCH words according to 36.212 5.3.3.1.3
|
||||
*
|
||||
*/
|
||||
int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t nof_prb,
|
||||
int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t nof_prb,
|
||||
bool crc_is_crnti) {
|
||||
|
||||
/* pack bits */
|
||||
|
@ -667,14 +671,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_
|
|||
data->type2_alloc.n_prb1a = *y++; // LSB indicates N_prb_1a for TBS
|
||||
}
|
||||
|
||||
uint32_t n_prb;
|
||||
if (crc_is_crnti) {
|
||||
n_prb = srslte_ra_nprb_dl(data, nof_prb);
|
||||
} else {
|
||||
n_prb = data->type2_alloc.n_prb1a == SRSLTE_RA_TYPE2_NPRB1A_2 ? 2 : 3;
|
||||
}
|
||||
data->mcs.tbs = srslte_ra_tbs_from_idx(data->mcs_idx, n_prb);
|
||||
data->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
data->dci_format = SRSLTE_RA_DCI_FORMAT1A;
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
@ -682,7 +679,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_
|
|||
/* Format 1C for compact scheduling of PDSCH words
|
||||
*
|
||||
*/
|
||||
int dci_format1Cs_pack(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
int dci_format1Cs_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
|
||||
/* pack bits */
|
||||
uint8_t *y = msg->data;
|
||||
|
@ -732,7 +729,7 @@ int dci_format1Cs_pack(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, uint32_t
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t nof_prb) {
|
||||
int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t nof_prb) {
|
||||
uint32_t L_p, RB_p;
|
||||
|
||||
/* pack bits */
|
||||
|
@ -759,15 +756,15 @@ int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_
|
|||
data->type2_alloc.riv = riv;
|
||||
|
||||
data->mcs_idx = srslte_bit_unpack(&y, 5);
|
||||
data->mcs.tbs = srslte_ra_tbs_from_idx_format1c(data->mcs_idx);
|
||||
data->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
|
||||
|
||||
data->dci_format = SRSLTE_RA_DCI_FORMAT1C;
|
||||
|
||||
msg->nof_bits = (y - msg->data);
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_dci_msg_pack_pdsch(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, srslte_dci_format_t format,
|
||||
int srslte_dci_msg_pack_pdsch(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, srslte_dci_format_t format,
|
||||
uint32_t nof_prb, bool crc_is_crnti) {
|
||||
switch (format) {
|
||||
case SRSLTE_DCI_FORMAT1:
|
||||
|
@ -783,7 +780,7 @@ int srslte_dci_msg_pack_pdsch(srslte_ra_pdsch_t *data, srslte_dci_msg_t *msg, sr
|
|||
}
|
||||
}
|
||||
|
||||
int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data, uint32_t nof_prb,
|
||||
int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t nof_prb,
|
||||
bool crc_is_crnti) {
|
||||
if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb)) {
|
||||
return dci_format1_unpack(msg, data, nof_prb);
|
||||
|
@ -796,11 +793,11 @@ int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg, srslte_ra_pdsch_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
int srslte_dci_msg_pack_pusch(srslte_ra_pusch_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
int srslte_dci_msg_pack_pusch(srslte_ra_ul_dci_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb) {
|
||||
return dci_format0_pack(data, msg, nof_prb);
|
||||
}
|
||||
|
||||
int srslte_dci_msg_unpack_pusch(srslte_dci_msg_t *msg, srslte_ra_pusch_t *data, uint32_t nof_prb) {
|
||||
int srslte_dci_msg_unpack_pusch(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t nof_prb) {
|
||||
return dci_format0_unpack(msg, data, nof_prb);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,248 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/phch/ra.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/fec/turbodecoder.h"
|
||||
#include "srslte/utils/vector.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
|
||||
|
||||
#define MAX_PDSCH_RE(cp) (2 * SRSLTE_CP_NSYMB(cp) * 12)
|
||||
|
||||
/* Calculate Codeblock Segmentation as in Section 5.1.2 of 36.212 */
|
||||
int srslte_harq_codeblock_segmentation(srslte_harq_cbsegm_t *s, uint32_t tbs) {
|
||||
uint32_t Bp, B, idx1;
|
||||
int ret;
|
||||
|
||||
if (tbs == 0) {
|
||||
bzero(s, sizeof(srslte_harq_cbsegm_t));
|
||||
ret = SRSLTE_SUCCESS;
|
||||
} else {
|
||||
B = tbs + 24;
|
||||
|
||||
/* Calculate CB sizes */
|
||||
if (B <= MAX_LONG_CB) {
|
||||
s->C = 1;
|
||||
Bp = B;
|
||||
} else {
|
||||
s->C = (uint32_t) ceilf((float) B / (MAX_LONG_CB - 24));
|
||||
Bp = B + 24 * s->C;
|
||||
}
|
||||
ret = srslte_find_cb_index((Bp-1) / s->C + 1);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
idx1 = (uint32_t) ret;
|
||||
ret = srslte_cb_size(idx1);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
s->K1 = (uint32_t) ret;
|
||||
if (idx1 > 0) {
|
||||
ret = srslte_cb_size(idx1 - 1);
|
||||
}
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
if (s->C == 1) {
|
||||
s->K2 = 0;
|
||||
s->C2 = 0;
|
||||
s->C1 = 1;
|
||||
} else {
|
||||
s->K2 = (uint32_t) ret;
|
||||
s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2);
|
||||
s->C1 = s->C - s->C2;
|
||||
}
|
||||
s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp;
|
||||
INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n",
|
||||
tbs, s->C, s->C1, s->K1, s->C2, s->K2, s->F, Bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srslte_harq_init(srslte_harq_t *q, srslte_cell_t cell) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL) {
|
||||
uint32_t i;
|
||||
bzero(q, sizeof(srslte_harq_t));
|
||||
|
||||
memcpy(&q->cell, &cell, sizeof(srslte_cell_t));
|
||||
|
||||
ret = srslte_ra_tbs_from_idx(26, cell.nof_prb);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
q->max_cb = (uint32_t) ret / (MAX_LONG_CB - 24) + 1;
|
||||
|
||||
q->pdsch_w_buff_f = srslte_vec_malloc(sizeof(float*) * q->max_cb);
|
||||
if (!q->pdsch_w_buff_f) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
q->pdsch_w_buff_c = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb);
|
||||
if (!q->pdsch_w_buff_c) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// FIXME: Use HARQ buffer limitation based on UE category
|
||||
q->w_buff_size = cell.nof_prb * MAX_PDSCH_RE(cell.cp) * 6 * 10;
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
q->pdsch_w_buff_f[i] = srslte_vec_malloc(sizeof(float) * q->w_buff_size);
|
||||
if (!q->pdsch_w_buff_f[i]) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
q->pdsch_w_buff_c[i] = srslte_vec_malloc(sizeof(uint8_t) * q->w_buff_size);
|
||||
if (!q->pdsch_w_buff_c[i]) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
bzero(q->pdsch_w_buff_c[i], sizeof(uint8_t) * q->w_buff_size);
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_harq_free(srslte_harq_t *q) {
|
||||
if (q) {
|
||||
uint32_t i;
|
||||
if (q->pdsch_w_buff_f) {
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->pdsch_w_buff_f[i]) {
|
||||
free(q->pdsch_w_buff_f[i]);
|
||||
}
|
||||
}
|
||||
free(q->pdsch_w_buff_f);
|
||||
}
|
||||
if (q->pdsch_w_buff_c) {
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->pdsch_w_buff_c[i]) {
|
||||
free(q->pdsch_w_buff_c[i]);
|
||||
}
|
||||
}
|
||||
free(q->pdsch_w_buff_c);
|
||||
}
|
||||
bzero(q, sizeof(srslte_harq_t));
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_harq_reset(srslte_harq_t *q) {
|
||||
int i;
|
||||
if (q->pdsch_w_buff_f) {
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->pdsch_w_buff_f[i]) {
|
||||
bzero(q->pdsch_w_buff_f[i], sizeof(float) * q->w_buff_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (q->pdsch_w_buff_c) {
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->pdsch_w_buff_c[i]) {
|
||||
bzero(q->pdsch_w_buff_c[i], sizeof(uint8_t) * q->w_buff_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
bzero(&q->mcs, sizeof(srslte_ra_mcs_t));
|
||||
bzero(&q->cb_segm, sizeof(srslte_harq_cbsegm_t));
|
||||
bzero(&q->dl_alloc, sizeof(srslte_ra_dl_alloc_t));
|
||||
}
|
||||
|
||||
static int harq_setup_common(srslte_harq_t *q, srslte_ra_mcs_t mcs, uint32_t rv, uint32_t sf_idx) {
|
||||
if (mcs.tbs != q->mcs.tbs) {
|
||||
srslte_harq_codeblock_segmentation(&q->cb_segm, mcs.tbs);
|
||||
if (q->cb_segm.C > q->max_cb) {
|
||||
fprintf(stderr, "Codeblock segmentation returned more CBs (%d) than allocated (%d)\n",
|
||||
q->cb_segm.C, q->max_cb);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
q->mcs = mcs;
|
||||
q->sf_idx = sf_idx;
|
||||
q->rv = rv;
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_harq_setup_dl(srslte_harq_t *q, srslte_ra_mcs_t mcs, uint32_t rv, uint32_t sf_idx, srslte_ra_dl_alloc_t *dl_alloc) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL &&
|
||||
rv < 4 &&
|
||||
sf_idx < 10)
|
||||
{
|
||||
ret = harq_setup_common(q, mcs, rv, sf_idx);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(&q->dl_alloc, dl_alloc, sizeof(srslte_ra_dl_alloc_t));
|
||||
|
||||
// Number of symbols, RE and bits per subframe for DL
|
||||
q->nof_re = q->dl_alloc.re_sf[q->sf_idx];
|
||||
q->nof_symb = 2*SRSLTE_CP_NSYMB(q->cell.cp)-q->dl_alloc.lstart;
|
||||
q->nof_bits = q->nof_re * srslte_mod_bits_x_symbol(q->mcs.mod);
|
||||
q->nof_prb = q->dl_alloc.slot[0].nof_prb;
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srslte_harq_setup_ul(srslte_harq_t *q, srslte_ra_mcs_t mcs, uint32_t rv, uint32_t sf_idx, srslte_ra_ul_alloc_t *ul_alloc) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL &&
|
||||
rv < 4 &&
|
||||
sf_idx < 10)
|
||||
{
|
||||
ret = harq_setup_common(q, mcs, rv, sf_idx);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(&q->ul_alloc, ul_alloc, sizeof(srslte_ra_ul_alloc_t));
|
||||
|
||||
// Number of symbols, RE and bits per subframe for UL
|
||||
q->nof_symb = 2*(SRSLTE_CP_NSYMB(q->cell.cp)-1);
|
||||
q->nof_re = q->nof_symb*q->ul_alloc.L_prb*SRSLTE_NRE;
|
||||
q->nof_bits = q->nof_re * srslte_mod_bits_x_symbol(q->mcs.mod);
|
||||
q->nof_prb = q->ul_alloc.L_prb;
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "prb_dl.h"
|
||||
#include "srslte/phch/pdsch.h"
|
||||
#include "srslte/phch/sch.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/utils/bit.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
|
@ -58,7 +59,7 @@ extern int indices_ptr;
|
|||
#endif
|
||||
|
||||
|
||||
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_alloc_t *prb_alloc,
|
||||
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant,
|
||||
uint32_t nsubframe, bool put) {
|
||||
uint32_t s, n, l, lp, lstart, lend, nof_refs;
|
||||
bool is_pbch, is_sss;
|
||||
|
@ -66,7 +67,7 @@ int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_a
|
|||
uint32_t offset = 0;
|
||||
|
||||
INFO("%s %d RE from %d PRB\n", put ? "Putting" : "Getting",
|
||||
prb_alloc->re_sf[nsubframe], prb_alloc->slot[0].nof_prb);
|
||||
grant->nof_re, grant->nof_prb);
|
||||
|
||||
#ifdef DEBUG_IDX
|
||||
indices_ptr = 0;
|
||||
|
@ -88,9 +89,9 @@ int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_a
|
|||
for (n = 0; n < q->cell.nof_prb; n++) {
|
||||
|
||||
// If this PRB is assigned
|
||||
if (prb_alloc->slot[s].prb_idx[n]) {
|
||||
if (grant->prb_idx[s][n]) {
|
||||
if (s == 0) {
|
||||
lstart = prb_alloc->lstart;
|
||||
lstart = grant->lstart;
|
||||
} else {
|
||||
lstart = 0;
|
||||
}
|
||||
|
@ -179,8 +180,8 @@ int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_a
|
|||
* 36.211 10.3 section 6.3.5
|
||||
*/
|
||||
int srslte_pdsch_put(srslte_pdsch_t *q, cf_t *symbols, cf_t *sf_symbols,
|
||||
srslte_ra_dl_alloc_t *prb_alloc, uint32_t subframe) {
|
||||
return srslte_pdsch_cp(q, symbols, sf_symbols, prb_alloc, subframe, true);
|
||||
srslte_ra_dl_grant_t *grant, uint32_t subframe) {
|
||||
return srslte_pdsch_cp(q, symbols, sf_symbols, grant, subframe, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,8 +192,8 @@ int srslte_pdsch_put(srslte_pdsch_t *q, cf_t *symbols, cf_t *sf_symbols,
|
|||
* 36.211 10.3 section 6.3.5
|
||||
*/
|
||||
int srslte_pdsch_get(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *symbols,
|
||||
srslte_ra_dl_alloc_t *prb_alloc, uint32_t subframe) {
|
||||
return srslte_pdsch_cp(q, sf_symbols, symbols, prb_alloc, subframe, false);
|
||||
srslte_ra_dl_grant_t *grant, uint32_t subframe) {
|
||||
return srslte_pdsch_cp(q, sf_symbols, symbols, grant, subframe, false);
|
||||
}
|
||||
|
||||
/** Initializes the PDCCH transmitter and receiver */
|
||||
|
@ -318,14 +319,18 @@ int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) {
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_pdsch_decode(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, 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,
|
||||
uint8_t *data)
|
||||
{
|
||||
if (q != NULL &&
|
||||
sf_symbols != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
cfg != NULL)
|
||||
{
|
||||
if (q->rnti_is_set) {
|
||||
return srslte_pdsch_decode_rnti(q, harq, sf_symbols, ce, noise_estimate, q->rnti, data);
|
||||
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;
|
||||
|
@ -337,22 +342,30 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_symbols
|
|||
|
||||
/** Decodes the PDSCH from the received symbols
|
||||
*/
|
||||
int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS],
|
||||
float noise_estimate, uint16_t rnti, uint8_t *data)
|
||||
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)
|
||||
{
|
||||
|
||||
/* Set pointers for layermapping & precoding */
|
||||
uint32_t i, n;
|
||||
cf_t *x[SRSLTE_MAX_LAYERS];
|
||||
|
||||
if (q != NULL &&
|
||||
sf_symbols != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
if (q != NULL &&
|
||||
sf_symbols != NULL &&
|
||||
data != NULL &&
|
||||
cfg != NULL)
|
||||
{
|
||||
|
||||
INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
||||
harq->sf_idx, rnti, srslte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
|
||||
cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->grant.nof_re,
|
||||
cfg->grant.nof_bits, cfg->rv);
|
||||
|
||||
if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) {
|
||||
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", cfg->grant.mcs.tbs, cfg->grant.nof_bits, (float) cfg->grant.mcs.tbs / cfg->grant.nof_bits);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
/* number of layers equals number of ports */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
|
@ -361,17 +374,17 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_sy
|
|||
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));
|
||||
|
||||
/* extract symbols */
|
||||
n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &harq->dl_alloc, harq->sf_idx);
|
||||
if (n != harq->nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n);
|
||||
n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->sf_idx);
|
||||
if (n != cfg->grant.nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
/* extract channel estimates */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
n = srslte_pdsch_get(q, ce[i], q->ce[i], &harq->dl_alloc, harq->sf_idx);
|
||||
if (n != harq->nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n);
|
||||
n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->sf_idx);
|
||||
if (n != cfg->grant.nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -380,12 +393,12 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_sy
|
|||
if (q->cell.nof_ports == 1) {
|
||||
/* no need for layer demapping */
|
||||
srslte_predecoding_single(&q->precoding, q->symbols[0], q->ce[0], q->d,
|
||||
harq->nof_re, noise_estimate);
|
||||
cfg->grant.nof_re, noise_estimate);
|
||||
} else {
|
||||
srslte_predecoding_diversity(&q->precoding, q->symbols[0], q->ce, x, q->cell.nof_ports,
|
||||
harq->nof_re, noise_estimate);
|
||||
cfg->grant.nof_re, noise_estimate);
|
||||
srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
|
||||
harq->nof_re / q->cell.nof_ports);
|
||||
cfg->grant.nof_re / q->cell.nof_ports);
|
||||
}
|
||||
|
||||
/* demodulate symbols
|
||||
|
@ -393,36 +406,38 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_sy
|
|||
* thus we don't need tot set it in the LLRs normalization
|
||||
*/
|
||||
srslte_demod_soft_sigma_set(&q->demod, sqrt(0.5));
|
||||
srslte_demod_soft_table_set(&q->demod, &q->mod[harq->mcs.mod]);
|
||||
srslte_demod_soft_demodulate(&q->demod, q->d, q->e, harq->nof_re);
|
||||
srslte_demod_soft_table_set(&q->demod, &q->mod[cfg->grant.mcs.mod]);
|
||||
srslte_demod_soft_demodulate(&q->demod, q->d, q->e, cfg->grant.nof_re);
|
||||
|
||||
/* descramble */
|
||||
if (rnti != q->rnti) {
|
||||
srslte_sequence_t seq;
|
||||
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * harq->sf_idx, q->cell.id, harq->nof_bits)) {
|
||||
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->grant.nof_bits)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
srslte_scrambling_f_offset(&seq, q->e, 0, harq->nof_bits);
|
||||
srslte_scrambling_f_offset(&seq, q->e, 0, cfg->grant.nof_bits);
|
||||
srslte_sequence_free(&seq);
|
||||
} else {
|
||||
srslte_scrambling_f_offset(&q->seq[harq->sf_idx], q->e, 0, harq->nof_bits);
|
||||
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->grant.nof_bits);
|
||||
}
|
||||
|
||||
return srslte_dlsch_decode(&q->dl_sch, harq, q->e, data);
|
||||
return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);
|
||||
|
||||
} else {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
}
|
||||
|
||||
int srslte_pdsch_encode(srslte_pdsch_t *q, srslte_harq_t *harq, uint8_t *data, cf_t *sf_symbols[SRSLTE_MAX_PORTS])
|
||||
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 &&
|
||||
harq != NULL)
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
cfg != NULL)
|
||||
{
|
||||
if (q->rnti_is_set) {
|
||||
return srslte_pdsch_encode_rnti(q, harq, data, q->rnti, sf_symbols);
|
||||
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;
|
||||
|
@ -434,7 +449,9 @@ int srslte_pdsch_encode(srslte_pdsch_t *q, srslte_harq_t *harq, uint8_t *data, c
|
|||
|
||||
/** Converts the PDSCH data bits to symbols mapped to the slot ready for transmission
|
||||
*/
|
||||
int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, uint8_t *data, uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS])
|
||||
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])
|
||||
{
|
||||
int i;
|
||||
/* Set pointers for layermapping & precoding */
|
||||
|
@ -443,7 +460,7 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, uint8_t *da
|
|||
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
cfg != NULL)
|
||||
{
|
||||
|
||||
for (i=0;i<q->cell.nof_ports;i++) {
|
||||
|
@ -452,24 +469,25 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, uint8_t *da
|
|||
}
|
||||
}
|
||||
|
||||
if (harq->mcs.tbs == 0) {
|
||||
if (cfg->grant.mcs.tbs == 0) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (harq->mcs.tbs > harq->nof_bits) {
|
||||
fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits);
|
||||
if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) {
|
||||
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", cfg->grant.mcs.tbs, cfg->grant.nof_bits, (float) cfg->grant.mcs.tbs / cfg->grant.nof_bits);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (harq->nof_re > q->max_re) {
|
||||
if (cfg->grant.nof_re > q->max_re) {
|
||||
fprintf(stderr,
|
||||
"Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
|
||||
harq->nof_re, q->max_re, q->cell.nof_prb);
|
||||
cfg->grant.nof_re, q->max_re, q->cell.nof_prb);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
||||
harq->sf_idx, srslte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
|
||||
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs,
|
||||
cfg->grant.nof_re, cfg->grant.nof_bits, cfg->rv);
|
||||
|
||||
/* number of layers equals number of ports */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
|
@ -477,36 +495,36 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, uint8_t *da
|
|||
}
|
||||
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));
|
||||
|
||||
if (srslte_dlsch_encode(&q->dl_sch, harq, data, q->e)) {
|
||||
if (srslte_dlsch_encode(&q->dl_sch, cfg, softbuffer, data, q->e)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (rnti != q->rnti) {
|
||||
srslte_sequence_t seq;
|
||||
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * harq->sf_idx, q->cell.id, harq->nof_bits)) {
|
||||
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->grant.nof_bits)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
srslte_scrambling_b_offset(&seq, (uint8_t*) q->e, 0, harq->nof_bits);
|
||||
srslte_scrambling_b_offset(&seq, (uint8_t*) q->e, 0, cfg->grant.nof_bits);
|
||||
srslte_sequence_free(&seq);
|
||||
} else {
|
||||
srslte_scrambling_b_offset(&q->seq[harq->sf_idx], (uint8_t*) q->e, 0, harq->nof_bits);
|
||||
srslte_scrambling_b_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->grant.nof_bits);
|
||||
}
|
||||
|
||||
srslte_mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->e, q->d, harq->nof_bits);
|
||||
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->grant.nof_bits);
|
||||
|
||||
/* TODO: only diversity supported */
|
||||
if (q->cell.nof_ports > 1) {
|
||||
srslte_layermap_diversity(q->d, x, q->cell.nof_ports, harq->nof_re);
|
||||
srslte_layermap_diversity(q->d, x, q->cell.nof_ports, cfg->grant.nof_re);
|
||||
srslte_precoding_diversity(&q->precoding, x, q->symbols, q->cell.nof_ports,
|
||||
harq->nof_re / q->cell.nof_ports);
|
||||
cfg->grant.nof_re / q->cell.nof_ports);
|
||||
} else {
|
||||
memcpy(q->symbols[0], q->d, harq->nof_re * sizeof(cf_t));
|
||||
memcpy(q->symbols[0], q->d, cfg->grant.nof_re * sizeof(cf_t));
|
||||
}
|
||||
|
||||
/* mapping to resource elements */
|
||||
for (i = 0; i < q->cell.nof_ports; i++) {
|
||||
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &harq->dl_alloc, harq->sf_idx);
|
||||
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->sf_idx);
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <math.h>
|
||||
|
||||
#include "srslte/phch/pusch.h"
|
||||
#include "srslte/phch/pusch_cfg.h"
|
||||
#include "srslte/phch/uci.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/utils/bit.h"
|
||||
|
@ -83,7 +84,7 @@ static int f_m(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t *hopping, uint32_t
|
|||
}
|
||||
}
|
||||
|
||||
int pusch_cp(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output, bool advance_input)
|
||||
int pusch_cp(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, uint32_t sf_idx, cf_t *input, cf_t *output, bool advance_input)
|
||||
{
|
||||
cf_t *in_ptr = input;
|
||||
cf_t *out_ptr = output;
|
||||
|
@ -93,27 +94,27 @@ int pusch_cp(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output,
|
|||
if (SRSLTE_CP_ISEXT(q->cell.cp)) {
|
||||
L_ref = 2;
|
||||
}
|
||||
INFO("PUSCH Freq hopping: %d\n", harq->ul_alloc.freq_hopping);
|
||||
INFO("PUSCH Freq hopping: %d\n", grant->freq_hopping);
|
||||
for (uint32_t slot=0;slot<2;slot++) {
|
||||
uint32_t n_prb_tilde = harq->ul_alloc.n_prb[slot];
|
||||
if (harq->ul_alloc.freq_hopping == 1) {
|
||||
uint32_t n_prb_tilde = grant->n_prb[slot];
|
||||
if (grant->freq_hopping == 1) {
|
||||
if (hopping->hop_mode == SRSLTE_PUSCH_HOP_MODE_INTER_SF) {
|
||||
n_prb_tilde = harq->ul_alloc.n_prb[hopping->current_tx_nb%2];
|
||||
n_prb_tilde = grant->n_prb[hopping->current_tx_nb%2];
|
||||
} else {
|
||||
n_prb_tilde = harq->ul_alloc.n_prb[slot];
|
||||
n_prb_tilde = grant->n_prb[slot];
|
||||
}
|
||||
}
|
||||
if (harq->ul_alloc.freq_hopping == 2) {
|
||||
if (grant->freq_hopping == 2) {
|
||||
/* Freq hopping type 2 as defined in 5.3.4 of 36.211 */
|
||||
uint32_t n_vrb_tilde = harq->ul_alloc.n_prb[0];
|
||||
uint32_t n_vrb_tilde = grant->n_prb[0];
|
||||
if (hopping->n_sb > 1) {
|
||||
n_vrb_tilde -= (hopping->hopping_offset-1)/2+1;
|
||||
}
|
||||
int i=0;
|
||||
if (hopping->hop_mode == SRSLTE_PUSCH_HOP_MODE_INTER_SF) {
|
||||
i = harq->sf_idx;
|
||||
i = sf_idx;
|
||||
} else {
|
||||
i = 2*harq->sf_idx+slot;
|
||||
i = 2*sf_idx+slot;
|
||||
}
|
||||
uint32_t n_rb_sb = q->cell.nof_prb;
|
||||
if (hopping->n_sb > 1) {
|
||||
|
@ -129,8 +130,8 @@ int pusch_cp(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output,
|
|||
}
|
||||
|
||||
}
|
||||
harq->ul_alloc.n_prb_tilde[slot] = n_prb_tilde;
|
||||
INFO("Allocating PUSCH %d PRB to index %d at slot %d\n",harq->ul_alloc.L_prb, n_prb_tilde,slot);
|
||||
grant->n_prb_tilde[slot] = n_prb_tilde;
|
||||
INFO("Allocating PUSCH %d PRB to index %d at slot %d\n",grant->L_prb, n_prb_tilde,slot);
|
||||
for (uint32_t l=0;l<SRSLTE_CP_NSYMB(q->cell.cp);l++) {
|
||||
if (l != L_ref) {
|
||||
uint32_t idx = SRSLTE_RE_IDX(q->cell.nof_prb, l+slot*SRSLTE_CP_NSYMB(q->cell.cp),
|
||||
|
@ -140,24 +141,24 @@ int pusch_cp(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output,
|
|||
} else {
|
||||
in_ptr = &input[idx];
|
||||
}
|
||||
memcpy(out_ptr, in_ptr, harq->ul_alloc.L_prb * SRSLTE_NRE * sizeof(cf_t));
|
||||
memcpy(out_ptr, in_ptr, grant->L_prb * SRSLTE_NRE * sizeof(cf_t));
|
||||
if (advance_input) {
|
||||
in_ptr += harq->ul_alloc.L_prb*SRSLTE_NRE;
|
||||
in_ptr += grant->L_prb*SRSLTE_NRE;
|
||||
} else {
|
||||
out_ptr += harq->ul_alloc.L_prb*SRSLTE_NRE;
|
||||
out_ptr += grant->L_prb*SRSLTE_NRE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SRSLTE_NRE*harq->ul_alloc.L_prb;
|
||||
return SRSLTE_NRE*grant->L_prb;
|
||||
}
|
||||
|
||||
int pusch_put(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output) {
|
||||
return pusch_cp(q, harq, input, output, true);
|
||||
int pusch_put(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, uint32_t sf_idx, cf_t *input, cf_t *output) {
|
||||
return pusch_cp(q, grant, sf_idx, input, output, true);
|
||||
}
|
||||
|
||||
int get(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output) {
|
||||
return pusch_cp(q, harq, input, output, false);
|
||||
int pusch_get(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, uint32_t sf_idx, cf_t *input, cf_t *output) {
|
||||
return pusch_cp(q, grant, sf_idx, input, output, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,53 +307,57 @@ int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti) {
|
|||
|
||||
/** Decodes the PUSCH from the received symbols
|
||||
*/
|
||||
int srslte_pusch_decode(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data)
|
||||
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)
|
||||
{
|
||||
|
||||
uint32_t n;
|
||||
|
||||
if (q != NULL &&
|
||||
sf_symbols != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
if (q != NULL &&
|
||||
sf_symbols != NULL &&
|
||||
data != NULL &&
|
||||
cfg != NULL)
|
||||
{
|
||||
|
||||
if (q->rnti_is_set) {
|
||||
INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
||||
harq->sf_idx, srslte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
|
||||
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs,
|
||||
cfg->grant.nof_re, cfg->grant.nof_bits, cfg->rv);
|
||||
|
||||
/* extract symbols */
|
||||
n = get(q, harq, sf_symbols, q->d);
|
||||
if (n != harq->nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n);
|
||||
n = pusch_get(q, &cfg->grant, cfg->sf_idx, sf_symbols, q->d);
|
||||
if (n != cfg->grant.nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
/* extract channel estimates */
|
||||
n = get(q, harq, ce, q->ce);
|
||||
if (n != harq->nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n);
|
||||
n = pusch_get(q, &cfg->grant, cfg->sf_idx, ce, q->ce);
|
||||
if (n != cfg->grant.nof_re) {
|
||||
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
srslte_predecoding_single(&q->equalizer, q->d, q->ce, q->z,
|
||||
harq->nof_re, noise_estimate);
|
||||
cfg->grant.nof_re, noise_estimate);
|
||||
|
||||
srslte_dft_predecoding(&q->dft_precoding, q->z, q->d,
|
||||
harq->ul_alloc.L_prb, harq->nof_symb);
|
||||
srslte_dft_predecoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->grant.nof_symb);
|
||||
|
||||
/* demodulate symbols
|
||||
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
|
||||
* thus we don't need tot set it in the LLRs normalization
|
||||
*/
|
||||
srslte_demod_soft_sigma_set(&q->demod, sqrt(0.5));
|
||||
srslte_demod_soft_table_set(&q->demod, &q->mod[harq->mcs.mod]);
|
||||
srslte_demod_soft_demodulate(&q->demod, q->d, q->q, harq->nof_re);
|
||||
srslte_demod_soft_table_set(&q->demod, &q->mod[cfg->grant.mcs.mod]);
|
||||
srslte_demod_soft_demodulate(&q->demod, q->d, q->q, cfg->grant.nof_re);
|
||||
|
||||
/* descramble */
|
||||
srslte_scrambling_f_offset(&q->seq[harq->sf_idx], q->q, 0, harq->nof_bits);
|
||||
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->q, 0, cfg->grant.nof_bits);
|
||||
|
||||
return srslte_ulsch_decode(&q->dl_sch, harq, q->q, data);
|
||||
return srslte_ulsch_decode(&q->dl_sch, cfg, softbuffer, q->q, data);
|
||||
} else {
|
||||
fprintf(stderr, "Must call srslte_pusch_set_rnti() before calling srslte_pusch_decode()\n");
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -362,29 +367,34 @@ int srslte_pusch_decode(srslte_pusch_t *q, srslte_harq_t *harq, cf_t *sf_symbols
|
|||
}
|
||||
}
|
||||
|
||||
int srslte_pusch_encode_rnti(srslte_pusch_t *q, srslte_harq_t *harq_process, uint8_t *data, uint16_t rnti, cf_t *sf_symbols)
|
||||
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, harq_process, data, uci_data, rnti, sf_symbols);
|
||||
return srslte_pusch_uci_encode_rnti(q, cfg, softbuffer, data, uci_data, rnti, sf_symbols);
|
||||
}
|
||||
|
||||
int srslte_pusch_encode(srslte_pusch_t *q, srslte_harq_t *harq_process, uint8_t *data, 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, 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, harq_process, data, uci_data, q->rnti, sf_symbols);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int srslte_pusch_uci_encode(srslte_pusch_t *q, srslte_harq_t *harq, uint8_t *data, srslte_uci_data_t uci_data, cf_t *sf_symbols)
|
||||
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, harq, data, uci_data, q->rnti, sf_symbols);
|
||||
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;
|
||||
|
@ -393,52 +403,54 @@ int srslte_pusch_uci_encode(srslte_pusch_t *q, srslte_harq_t *harq, uint8_t *dat
|
|||
|
||||
/** 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_harq_t *harq, uint8_t *data, srslte_uci_data_t uci_data, uint16_t rnti, cf_t *sf_symbols)
|
||||
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 ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
cfg != NULL)
|
||||
{
|
||||
if (harq->mcs.tbs > harq->nof_bits) {
|
||||
fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits);
|
||||
if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) {
|
||||
fprintf(stderr, "Invalid code rate %.2f\n", (float) cfg->grant.mcs.tbs / cfg->grant.nof_bits);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (harq->nof_re > q->max_re) {
|
||||
if (cfg->grant.nof_re > q->max_re) {
|
||||
fprintf(stderr, "Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)\n",
|
||||
harq->nof_re, q->max_re, q->cell.nof_prb);
|
||||
cfg->grant.nof_re, q->max_re, q->cell.nof_prb);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
INFO("Encoding PUSCH SF: %d, Mod %s, RNTI: %d, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
||||
harq->sf_idx, srslte_mod_string(harq->mcs.mod), rnti, harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
|
||||
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), rnti,
|
||||
cfg->grant.mcs.tbs, cfg->grant.nof_re, cfg->grant.nof_bits, cfg->rv);
|
||||
|
||||
bzero(q->q, harq->nof_bits);
|
||||
if (srslte_ulsch_uci_encode(&q->dl_sch, harq, data, uci_data, q->g, q->q)) {
|
||||
bzero(q->q, cfg->grant.nof_bits);
|
||||
if (srslte_ulsch_uci_encode(&q->dl_sch, cfg, softbuffer, data, uci_data, q->g, q->q)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (rnti != q->rnti) {
|
||||
srslte_sequence_t seq;
|
||||
if (srslte_sequence_pusch(&seq, rnti, 2 * harq->sf_idx, q->cell.id, harq->nof_bits)) {
|
||||
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->grant.nof_bits)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
srslte_scrambling_b_offset_pusch(&seq, (uint8_t*) q->q, 0, harq->nof_bits);
|
||||
srslte_scrambling_b_offset_pusch(&seq, (uint8_t*) q->q, 0, cfg->grant.nof_bits);
|
||||
srslte_sequence_free(&seq);
|
||||
} else {
|
||||
srslte_scrambling_b_offset_pusch(&q->seq[harq->sf_idx], (uint8_t*) q->q, 0, harq->nof_bits);
|
||||
srslte_scrambling_b_offset_pusch(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->grant.nof_bits);
|
||||
}
|
||||
|
||||
srslte_mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->q, q->d, harq->nof_bits);
|
||||
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->q, q->d, cfg->grant.nof_bits);
|
||||
|
||||
srslte_dft_precoding(&q->dft_precoding, q->d, q->z,
|
||||
harq->ul_alloc.L_prb, harq->nof_symb);
|
||||
srslte_dft_precoding(&q->dft_precoding, q->d, q->z, cfg->grant.L_prb, cfg->grant.nof_symb);
|
||||
|
||||
/* mapping to resource elements */
|
||||
pusch_put(q, harq, q->z, sf_symbols);
|
||||
pusch_put(q, &cfg->grant, cfg->sf_idx, q->z, sf_symbols);
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -108,44 +108,30 @@ uint32_t ra_re_x_prb(uint32_t subframe, uint32_t slot, uint32_t prb_idx, uint32_
|
|||
return re;
|
||||
}
|
||||
|
||||
void srslte_ra_prb_fprint(FILE *f, srslte_ra_prb_slot_t *prb, uint32_t nof_prb) {
|
||||
int i;
|
||||
if (prb->nof_prb > 0) {
|
||||
for (i=0;i<nof_prb;i++) {
|
||||
if (prb->prb_idx[i]) {
|
||||
fprintf(f, "%d, ", i);
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Compute PRB allocation for Uplink as defined in 8.1 and 8.4 of 36.213 */
|
||||
int srslte_ra_ul_alloc(srslte_ra_ul_alloc_t *prb_dist, srslte_ra_pusch_t *ra, uint32_t n_rb_ho, uint32_t nof_prb) {
|
||||
|
||||
bzero(prb_dist, sizeof(srslte_ra_ul_alloc_t));
|
||||
prb_dist->L_prb = ra->type2_alloc.L_crb;
|
||||
uint32_t n_prb_1 = ra->type2_alloc.RB_start;
|
||||
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) {
|
||||
bzero(grant, sizeof(srslte_ra_ul_grant_t));
|
||||
grant->L_prb = dci->type2_alloc.L_crb;
|
||||
uint32_t n_prb_1 = dci->type2_alloc.RB_start;
|
||||
uint32_t n_rb_pusch = 0;
|
||||
|
||||
if (n_rb_ho%2) {
|
||||
n_rb_ho++;
|
||||
}
|
||||
|
||||
if (ra->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_DISABLED || ra->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_TYPE2) {
|
||||
|
||||
if (dci->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_DISABLED || dci->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_TYPE2) {
|
||||
/* For no freq hopping or type2 freq hopping, n_prb is the same
|
||||
* n_prb_tilde is calculated during resource mapping
|
||||
*/
|
||||
for (uint32_t i=0;i<2;i++) {
|
||||
prb_dist->n_prb[i] = n_prb_1;
|
||||
grant->n_prb[i] = n_prb_1;
|
||||
}
|
||||
if (ra->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_DISABLED) {
|
||||
prb_dist->freq_hopping = 0;
|
||||
if (dci->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_DISABLED) {
|
||||
grant->freq_hopping = 0;
|
||||
} else {
|
||||
prb_dist->freq_hopping = 2;
|
||||
grant->freq_hopping = 2;
|
||||
}
|
||||
INFO("prb1: %d, prb2: %d, L: %d\n", prb_dist->n_prb[0], prb_dist->n_prb[1], prb_dist->L_prb);
|
||||
INFO("prb1: %d, prb2: %d, L: %d\n", grant->n_prb[0], grant->n_prb[1], grant->L_prb);
|
||||
} else {
|
||||
/* Type1 frequency hopping as defined in 8.4.1 of 36.213
|
||||
* frequency offset between 1st and 2nd slot is fixed.
|
||||
|
@ -153,108 +139,166 @@ int srslte_ra_ul_alloc(srslte_ra_ul_alloc_t *prb_dist, srslte_ra_pusch_t *ra, ui
|
|||
n_rb_pusch = nof_prb - n_rb_ho - (nof_prb%2);
|
||||
|
||||
// starting prb idx for slot 0 is as given by resource grant
|
||||
prb_dist->n_prb[0] = n_prb_1;
|
||||
grant->n_prb[0] = n_prb_1;
|
||||
if (n_prb_1 < n_rb_ho/2) {
|
||||
fprintf(stderr, "Invalid Frequency Hopping parameters. Offset: %d, n_prb_1: %d\n", n_rb_ho, n_prb_1);
|
||||
}
|
||||
uint32_t n_prb_1_tilde = n_prb_1;
|
||||
|
||||
// prb idx for slot 1
|
||||
switch(ra->freq_hop_fl) {
|
||||
switch(dci->freq_hop_fl) {
|
||||
case SRSLTE_RA_PUSCH_HOP_QUART:
|
||||
prb_dist->n_prb[1] = (n_rb_pusch/4+ n_prb_1_tilde)%n_rb_pusch;
|
||||
grant->n_prb[1] = (n_rb_pusch/4+ n_prb_1_tilde)%n_rb_pusch;
|
||||
break;
|
||||
case SRSLTE_RA_PUSCH_HOP_QUART_NEG:
|
||||
if (n_prb_1 < n_rb_pusch/4) {
|
||||
prb_dist->n_prb[1] = (n_rb_pusch+ n_prb_1_tilde -n_rb_pusch/4);
|
||||
grant->n_prb[1] = (n_rb_pusch+ n_prb_1_tilde -n_rb_pusch/4);
|
||||
} else {
|
||||
prb_dist->n_prb[1] = (n_prb_1_tilde -n_rb_pusch/4);
|
||||
grant->n_prb[1] = (n_prb_1_tilde -n_rb_pusch/4);
|
||||
}
|
||||
break;
|
||||
case SRSLTE_RA_PUSCH_HOP_HALF:
|
||||
prb_dist->n_prb[1] = (n_rb_pusch/2+ n_prb_1_tilde)%n_rb_pusch;
|
||||
grant->n_prb[1] = (n_rb_pusch/2+ n_prb_1_tilde)%n_rb_pusch;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
INFO("n_rb_pusch: %d, prb1: %d, prb2: %d, L: %d\n", n_rb_pusch, prb_dist->n_prb[0], prb_dist->n_prb[1], prb_dist->L_prb);
|
||||
prb_dist->freq_hopping = 1;
|
||||
INFO("n_rb_pusch: %d, prb1: %d, prb2: %d, L: %d\n", n_rb_pusch, grant->n_prb[0], grant->n_prb[1], grant->L_prb);
|
||||
grant->freq_hopping = 1;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant) {
|
||||
// 8.6.2 First paragraph
|
||||
if (dci->mcs_idx <= 28) {
|
||||
/* Table 8.6.1-1 on 36.213 */
|
||||
if (dci->mcs_idx < 11) {
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->L_prb);
|
||||
} else if (dci->mcs_idx < 21) {
|
||||
grant->mcs.mod = SRSLTE_MOD_16QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->L_prb);
|
||||
} else if (dci->mcs_idx < 29) {
|
||||
grant->mcs.mod = SRSLTE_MOD_64QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->L_prb);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid MCS index %d\n", dci->mcs_idx);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
} 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;
|
||||
grant->mcs.tbs = 0;
|
||||
} else if (dci->mcs_idx >= 29) {
|
||||
// Else use last TBS/Modulation and use mcs to obtain rv_idx
|
||||
grant->mcs.tbs = 0;
|
||||
grant->mcs.mod = 0;
|
||||
dci->rv_idx = dci->mcs_idx - 28;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/** Compute PRB allocation for Uplink as defined in 8.1 and 8.4 of 36.213 */
|
||||
int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, srslte_cell_t cell,
|
||||
uint32_t n_rb_ho, uint32_t N_srs)
|
||||
{
|
||||
|
||||
// Compute PRB allocation
|
||||
if (!srslte_ul_dci_to_grant_prb_allocation(dci, grant, n_rb_ho, cell.nof_prb)) {
|
||||
|
||||
// Compute MCS
|
||||
if (!ul_dci_to_grant_mcs(dci, grant)) {
|
||||
|
||||
// Fill rest of grant structure
|
||||
grant->lstart = 0;
|
||||
grant->nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs;
|
||||
grant->M_sc = grant->L_prb*SRSLTE_NRE;
|
||||
grant->M_sc_init = grant->M_sc; // FIXME: What should M_sc_init be?
|
||||
grant->nof_re = grant->nof_symb*grant->M_sc;
|
||||
grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
|
||||
grant->nof_bits = grant->nof_re * grant->Qm;
|
||||
} else {
|
||||
fprintf(stderr, "Error computing MCS\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error computing PRB allocation\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Computes the number of RE for each PRB in the prb_dist structure */
|
||||
void srslte_ra_dl_alloc_re(srslte_ra_dl_alloc_t *prb_dist, uint32_t nof_prb, uint32_t nof_ports,
|
||||
uint32_t nof_ctrl_symbols, srslte_cp_t cp) {
|
||||
uint32_t i, j, s;
|
||||
void srslte_dl_dci_to_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t cell,
|
||||
uint32_t sf_idx, uint32_t nof_ctrl_symbols)
|
||||
{
|
||||
uint32_t j, s;
|
||||
|
||||
/* Set start symbol according to Section 7.1.6.4 in 36.213 */
|
||||
prb_dist->lstart = nof_ctrl_symbols;
|
||||
// Compute number of RE per subframe
|
||||
for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) {
|
||||
prb_dist->re_sf[i] = 0;
|
||||
for (s = 0; s < 2; s++) {
|
||||
for (j = 0; j < nof_prb; j++) {
|
||||
if (prb_dist->slot[s].prb_idx[j]) {
|
||||
prb_dist->re_sf[i] += ra_re_x_prb(i, s, j,
|
||||
nof_prb, nof_ports, nof_ctrl_symbols, cp);
|
||||
}
|
||||
// Compute number of RE per PRB
|
||||
grant->nof_re = 0;
|
||||
for (s = 0; s < 2; s++) {
|
||||
for (j = 0; j < cell.nof_prb; j++) {
|
||||
if (grant->prb_idx[s][j]) {
|
||||
grant->nof_re += ra_re_x_prb(sf_idx, s, j,
|
||||
cell.nof_prb, cell.nof_ports, nof_ctrl_symbols, cell.cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Compute PRB allocation for Downlink as defined in 7.1.6 of 36.213 */
|
||||
int srslte_ra_dl_alloc(srslte_ra_dl_alloc_t *prb_dist, srslte_ra_pdsch_t *ra, uint32_t nof_prb) {
|
||||
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 i, j;
|
||||
uint32_t bitmask;
|
||||
uint32_t P = srslte_ra_type0_P(nof_prb);
|
||||
uint32_t n_rb_rbg_subset, n_rb_type1;
|
||||
|
||||
bzero(prb_dist, sizeof(srslte_ra_dl_alloc_t));
|
||||
switch (ra->alloc_type) {
|
||||
|
||||
bzero(grant, sizeof(srslte_ra_dl_grant_t));
|
||||
switch (dci->alloc_type) {
|
||||
case SRSLTE_RA_ALLOC_TYPE0:
|
||||
bitmask = ra->type0_alloc.rbg_bitmask;
|
||||
bitmask = dci->type0_alloc.rbg_bitmask;
|
||||
int nb = (int) ceilf((float) nof_prb / P);
|
||||
for (i = 0; i < nb; i++) {
|
||||
if (bitmask & (1 << (nb - i - 1))) {
|
||||
for (j = 0; j < P; j++) {
|
||||
if (i*P+j < nof_prb) {
|
||||
prb_dist->slot[0].prb_idx[i * P + j] = true;
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
grant->prb_idx[0][i * P + j] = true;
|
||||
grant->nof_prb++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(&prb_dist->slot[1], &prb_dist->slot[0], sizeof(srslte_ra_prb_slot_t));
|
||||
memcpy(&grant->prb_idx[1], &grant->prb_idx[0], SRSLTE_MAX_PRB*sizeof(bool));
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE1:
|
||||
n_rb_type1 = srslte_ra_type1_N_rb(nof_prb);
|
||||
if (ra->type1_alloc.rbg_subset < (nof_prb / P) % P) {
|
||||
if (dci->type1_alloc.rbg_subset < (nof_prb / P) % P) {
|
||||
n_rb_rbg_subset = ((nof_prb - 1) / (P * P)) * P + P;
|
||||
} else if (ra->type1_alloc.rbg_subset == ((nof_prb / P) % P)) {
|
||||
} else if (dci->type1_alloc.rbg_subset == ((nof_prb / P) % P)) {
|
||||
n_rb_rbg_subset = ((nof_prb - 1) / (P * P)) * P + ((nof_prb - 1) % P) + 1;
|
||||
} else {
|
||||
n_rb_rbg_subset = ((nof_prb - 1) / (P * P)) * P;
|
||||
}
|
||||
int shift = ra->type1_alloc.shift ? (n_rb_rbg_subset - n_rb_type1) : 0;
|
||||
bitmask = ra->type1_alloc.vrb_bitmask;
|
||||
int shift = dci->type1_alloc.shift ? (n_rb_rbg_subset - n_rb_type1) : 0;
|
||||
bitmask = dci->type1_alloc.vrb_bitmask;
|
||||
for (i = 0; i < n_rb_type1; i++) {
|
||||
if (bitmask & (1 << (n_rb_type1 - i - 1))) {
|
||||
prb_dist->slot[0].prb_idx[((i + shift) / P)
|
||||
* P * P + ra->type1_alloc.rbg_subset * P + (i + shift) % P] = true;
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
grant->prb_idx[0][((i + shift) / P)
|
||||
* P * P + dci->type1_alloc.rbg_subset * P + (i + shift) % P] = true;
|
||||
grant->nof_prb++;
|
||||
}
|
||||
}
|
||||
memcpy(&prb_dist->slot[1], &prb_dist->slot[0], sizeof(srslte_ra_prb_slot_t));
|
||||
memcpy(&grant->prb_idx[1], &grant->prb_idx[0], SRSLTE_MAX_PRB*sizeof(bool));
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE2:
|
||||
if (ra->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) {
|
||||
for (i = 0; i < ra->type2_alloc.L_crb; i++) {
|
||||
prb_dist->slot[0].prb_idx[i + ra->type2_alloc.RB_start] = true;
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
if (dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) {
|
||||
for (i = 0; i < dci->type2_alloc.L_crb; i++) {
|
||||
grant->prb_idx[0][i + dci->type2_alloc.RB_start] = true;
|
||||
grant->nof_prb++;
|
||||
}
|
||||
memcpy(&prb_dist->slot[1], &prb_dist->slot[0], sizeof(srslte_ra_prb_slot_t));
|
||||
memcpy(&grant->prb_idx[1], &grant->prb_idx[0], SRSLTE_MAX_PRB*sizeof(bool));
|
||||
} else {
|
||||
/* Mapping of Virtual to Physical RB for distributed type is defined in
|
||||
* 6.2.3.2 of 36.211
|
||||
|
@ -262,7 +306,7 @@ int srslte_ra_dl_alloc(srslte_ra_dl_alloc_t *prb_dist, srslte_ra_pdsch_t *ra, ui
|
|||
int N_gap, N_tilde_vrb, n_tilde_vrb, n_tilde_prb, n_tilde2_prb, N_null,
|
||||
N_row, n_vrb;
|
||||
int n_tilde_prb_odd, n_tilde_prb_even;
|
||||
if (ra->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1) {
|
||||
if (dci->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1) {
|
||||
N_tilde_vrb = srslte_ra_type2_n_vrb_dl(nof_prb, true);
|
||||
N_gap = srslte_ra_type2_ngap(nof_prb, true);
|
||||
} else {
|
||||
|
@ -271,8 +315,8 @@ int srslte_ra_dl_alloc(srslte_ra_dl_alloc_t *prb_dist, srslte_ra_pdsch_t *ra, ui
|
|||
}
|
||||
N_row = (int) ceilf((float) N_tilde_vrb / (4 * P)) * P;
|
||||
N_null = 4 * N_row - N_tilde_vrb;
|
||||
for (i = 0; i < ra->type2_alloc.L_crb; i++) {
|
||||
n_vrb = i + ra->type2_alloc.RB_start;
|
||||
for (i = 0; i < dci->type2_alloc.L_crb; i++) {
|
||||
n_vrb = i + dci->type2_alloc.RB_start;
|
||||
n_tilde_vrb = n_vrb % N_tilde_vrb;
|
||||
n_tilde_prb = 2 * N_row * (n_tilde_vrb % 2) + n_tilde_vrb / 2
|
||||
+ N_tilde_vrb * (n_vrb / N_tilde_vrb);
|
||||
|
@ -295,19 +339,18 @@ int srslte_ra_dl_alloc(srslte_ra_dl_alloc_t *prb_dist, srslte_ra_pdsch_t *ra, ui
|
|||
+ N_tilde_vrb * (n_vrb / N_tilde_vrb);
|
||||
|
||||
if (n_tilde_prb_odd < N_tilde_vrb / 2) {
|
||||
prb_dist->slot[0].prb_idx[n_tilde_prb_odd] = true;
|
||||
grant->prb_idx[0][n_tilde_prb_odd] = true;
|
||||
} else {
|
||||
prb_dist->slot[0].prb_idx[n_tilde_prb_odd + N_gap
|
||||
grant->prb_idx[0][n_tilde_prb_odd + N_gap
|
||||
- N_tilde_vrb / 2] = true;
|
||||
}
|
||||
prb_dist->slot[0].nof_prb++;
|
||||
grant->nof_prb++;
|
||||
if (n_tilde_prb_even < N_tilde_vrb / 2) {
|
||||
prb_dist->slot[1].prb_idx[n_tilde_prb_even] = true;
|
||||
grant->prb_idx[1][n_tilde_prb_even] = true;
|
||||
} else {
|
||||
prb_dist->slot[1].prb_idx[n_tilde_prb_even + N_gap
|
||||
grant->prb_idx[1][n_tilde_prb_even + N_gap
|
||||
- N_tilde_vrb / 2] = true;
|
||||
}
|
||||
prb_dist->slot[1].nof_prb++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -318,46 +361,83 @@ int srslte_ra_dl_alloc(srslte_ra_dl_alloc_t *prb_dist, srslte_ra_pdsch_t *ra, ui
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Returns the number of allocated PRB for Uplink */
|
||||
uint32_t srslte_ra_nprb_ul(srslte_ra_pusch_t *ra, uint32_t nof_prb) {
|
||||
return ra->type2_alloc.L_crb;
|
||||
/* 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;
|
||||
switch(dci->dci_format) {
|
||||
case SRSLTE_RA_DCI_FORMAT1:
|
||||
/* Table 7.1.7.1-1 on 36.213 */
|
||||
if (dci->mcs_idx < 10) {
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->nof_prb);
|
||||
} else if (dci->mcs_idx < 17) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_16QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->nof_prb);
|
||||
} else if (dci->mcs_idx < 29) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_64QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->nof_prb);
|
||||
} else if (dci->mcs_idx == 29) {
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = 0;
|
||||
} else if (dci->mcs_idx == 30) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_16QAM;
|
||||
grant->mcs.tbs = 0;
|
||||
} else if (dci->mcs_idx == 31) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_64QAM;
|
||||
grant->mcs.tbs = 0;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_RA_DCI_FORMAT1A:
|
||||
/* Downlink Transport Block size determination as defined in 7.1.7.2 on 36.213 */
|
||||
if (crc_is_crnti) {
|
||||
n_prb = grant->nof_prb;
|
||||
} else {
|
||||
n_prb = dci->type2_alloc.n_prb1a == SRSLTE_RA_TYPE2_NPRB1A_2 ? 2 : 3;
|
||||
}
|
||||
if (dci->mcs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {
|
||||
grant->mcs.tbs = tbs_table[dci->mcs_idx][n_prb - 1];
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_RA_DCI_FORMAT1C:
|
||||
/* Downlink Transport Block size for Format 1C as defined in 7.1.7.2.2-1 on 36.213 */
|
||||
if (dci->mcs_idx < 32) {
|
||||
grant->mcs.tbs = tbs_format1c_table[dci->mcs_idx];
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Returns the number of allocated PRB for Downlink */
|
||||
uint32_t srslte_ra_nprb_dl(srslte_ra_pdsch_t *ra, uint32_t nof_prb) {
|
||||
uint32_t nprb;
|
||||
uint32_t nof_rbg, P;
|
||||
switch (ra->alloc_type) {
|
||||
case SRSLTE_RA_ALLOC_TYPE0:
|
||||
// Get the number of allocated RBG except the last RBG
|
||||
nof_rbg = srslte_bit_count(ra->type0_alloc.rbg_bitmask & 0xFFFFFFFE);
|
||||
P = srslte_ra_type0_P(nof_prb);
|
||||
if (nof_rbg > (uint32_t) ceilf((float) nof_prb / P)) {
|
||||
nof_rbg = (uint32_t) ceilf((float) nof_prb / P) - 1;
|
||||
/** Obtains a DL grant from a DCI grant for PDSCH */
|
||||
int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, srslte_cell_t cell,
|
||||
uint32_t sf_idx, uint32_t cfi, bool crc_is_crnti)
|
||||
{
|
||||
// Compute PRB allocation
|
||||
if (!dl_dci_to_grant_prb_allocation(dci, grant, cell.nof_prb)) {
|
||||
// Compute number of RE
|
||||
srslte_dl_dci_to_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi);
|
||||
// Compute MCS
|
||||
if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) {
|
||||
// Fill rest of grant structure
|
||||
grant->lstart = cell.nof_prb<10?(cfi+1):cfi;
|
||||
grant->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-grant->lstart;
|
||||
grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
|
||||
grant->nof_bits = grant->nof_re * grant->Qm;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
nprb = nof_rbg * P;
|
||||
|
||||
// last RBG may have smaller size. Add if set
|
||||
uint32_t P_last = (nof_prb % P);
|
||||
if (!P_last)
|
||||
P_last = P;
|
||||
nprb += P_last * (ra->type0_alloc.rbg_bitmask & 1);
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE1:
|
||||
nprb = srslte_bit_count(ra->type1_alloc.vrb_bitmask);
|
||||
if (nprb > srslte_ra_type1_N_rb(nof_prb)) {
|
||||
fprintf(stderr, "Number of RB (%d) can not exceed %d\n", nprb,
|
||||
srslte_ra_type1_N_rb(nof_prb));
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE2:
|
||||
nprb = ra->type2_alloc.L_crb;
|
||||
break;
|
||||
default:
|
||||
return SRSLTE_ERROR;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
return nprb;
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* RBG size for type0 scheduling as in table 7.1.6.1-1 of 36.213 */
|
||||
|
@ -443,59 +523,7 @@ uint32_t srslte_ra_type2_n_vrb_dl(uint32_t nof_prb, bool ngap_is_1) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Converts MCS index to srslte_ra_mcs_t structure for Downlink as defined inTable 7.1.7.1-1 on 36.213 */
|
||||
int srslte_ra_mcs_from_idx_dl(uint32_t mcs_idx, uint32_t nof_prb, srslte_ra_mcs_t *mcs) {
|
||||
if (mcs_idx < 10) {
|
||||
mcs->mod = SRSLTE_MOD_QPSK;
|
||||
mcs->tbs = srslte_ra_tbs_from_idx(mcs_idx, nof_prb);
|
||||
} else if (mcs_idx < 17) {
|
||||
mcs->mod = SRSLTE_MOD_16QAM;
|
||||
mcs->tbs = srslte_ra_tbs_from_idx(mcs_idx - 1, nof_prb);
|
||||
} else if (mcs_idx < 29) {
|
||||
mcs->mod = SRSLTE_MOD_64QAM;
|
||||
mcs->tbs = srslte_ra_tbs_from_idx(mcs_idx - 2, nof_prb);
|
||||
} else if (mcs_idx == 29) {
|
||||
mcs->mod = SRSLTE_MOD_QPSK;
|
||||
mcs->tbs = 0;
|
||||
} else if (mcs_idx == 30) {
|
||||
mcs->mod = SRSLTE_MOD_16QAM;
|
||||
mcs->tbs = 0;
|
||||
} else if (mcs_idx == 31) {
|
||||
mcs->mod = SRSLTE_MOD_64QAM;
|
||||
mcs->tbs = 0;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Converts MCS index to srslte_ra_mcs_t structure for Uplink as defined in Table 8.6.1-1 on 36.213 */
|
||||
int srslte_ra_mcs_from_idx_ul(uint32_t mcs_idx, uint32_t nof_prb, srslte_ra_mcs_t *mcs) {
|
||||
if (mcs_idx < 11) {
|
||||
mcs->mod = SRSLTE_MOD_QPSK;
|
||||
mcs->tbs = srslte_ra_tbs_from_idx(mcs_idx, nof_prb);
|
||||
} else if (mcs_idx < 21) {
|
||||
mcs->mod = SRSLTE_MOD_16QAM;
|
||||
mcs->tbs = srslte_ra_tbs_from_idx(mcs_idx - 1, nof_prb);
|
||||
} else if (mcs_idx < 29) {
|
||||
mcs->mod = SRSLTE_MOD_64QAM;
|
||||
mcs->tbs = srslte_ra_tbs_from_idx(mcs_idx - 2, nof_prb);
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Downlink Transport Block size for Format 1C as defined in 7.1.7.2.2-1 on 36.213 */
|
||||
int srslte_ra_tbs_from_idx_format1c(uint32_t tbs_idx) {
|
||||
if (tbs_idx < 32) {
|
||||
return tbs_format1c_table[tbs_idx];
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Downlink Transport Block size determination as defined in 7.1.7.2 on 36.213 */
|
||||
/* Table 7.1.7.2.1-1: Transport block size table on 36.213 */
|
||||
int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb) {
|
||||
if (tbs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {
|
||||
return tbs_table[tbs_idx][n_prb - 1];
|
||||
|
@ -523,39 +551,42 @@ int srslte_ra_tbs_to_table_idx(uint32_t tbs, uint32_t n_prb) {
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
void srslte_ra_pusch_fprint(FILE *f, srslte_ra_pusch_t *ra, uint32_t nof_prb) {
|
||||
void srslte_ra_pusch_fprint(FILE *f, srslte_ra_ul_dci_t *dci, uint32_t nof_prb) {
|
||||
fprintf(f, " - Resource Allocation Type 2 mode :\t%s\n",
|
||||
ra->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC ? "Localized" : "Distributed");
|
||||
dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC ? "Localized" : "Distributed");
|
||||
|
||||
fprintf(f, " + Frequency Hopping:\t\t\t");
|
||||
if (ra->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_DISABLED) {
|
||||
if (dci->freq_hop_fl == SRSLTE_RA_PUSCH_HOP_DISABLED) {
|
||||
fprintf(f, "No\n");
|
||||
} else {
|
||||
fprintf(f, "Yes\n");
|
||||
}
|
||||
fprintf(f, " + Resource Indicator Value:\t\t%d\n", ra->type2_alloc.riv);
|
||||
if (ra->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) {
|
||||
fprintf(f, " + Resource Indicator Value:\t\t%d\n", dci->type2_alloc.riv);
|
||||
if (dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) {
|
||||
fprintf(f, " + VRB Assignment:\t\t\t%d VRB starting with VRB %d\n",
|
||||
ra->type2_alloc.L_crb, ra->type2_alloc.RB_start);
|
||||
dci->type2_alloc.L_crb, dci->type2_alloc.RB_start);
|
||||
} else {
|
||||
fprintf(f, " + VRB Assignment:\t\t\t%d VRB starting with VRB %d\n",
|
||||
ra->type2_alloc.L_crb, ra->type2_alloc.RB_start);
|
||||
dci->type2_alloc.L_crb, dci->type2_alloc.RB_start);
|
||||
fprintf(f, " + VRB gap selection:\t\t\tGap %d\n",
|
||||
ra->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1 ? 1 : 2);
|
||||
dci->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1 ? 1 : 2);
|
||||
fprintf(f, " + VRB gap:\t\t\t\t%d\n",
|
||||
srslte_ra_type2_ngap(nof_prb, ra->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1));
|
||||
srslte_ra_type2_ngap(nof_prb, dci->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1));
|
||||
|
||||
}
|
||||
|
||||
fprintf(f, " - Number of PRBs:\t\t\t%d\n", srslte_ra_nprb_ul(ra, nof_prb));
|
||||
fprintf(f, " - Modulation and coding scheme index:\t%d\n", ra->mcs_idx);
|
||||
fprintf(f, " - Modulation type:\t\t\t%s\n", srslte_mod_string(ra->mcs.mod));
|
||||
fprintf(f, " - Transport block size:\t\t%d\n", ra->mcs.tbs);
|
||||
fprintf(f, " - New data indicator:\t\t\t%s\n", ra->ndi ? "Yes" : "No");
|
||||
fprintf(f, " - Redundancy version:\t\t\t%d\n", ra->rv_idx);
|
||||
fprintf(f, " - Modulation and coding scheme index:\t%d\n", dci->mcs_idx);
|
||||
fprintf(f, " - New data indicator:\t\t\t%s\n", dci->ndi ? "Yes" : "No");
|
||||
fprintf(f, " - Redundancy version:\t\t\t%d\n", dci->rv_idx);
|
||||
fprintf(f, " - TPC command for PUCCH:\t\t--\n");
|
||||
}
|
||||
|
||||
void srslte_ra_ul_grant_fprint(FILE *f, srslte_ra_ul_grant_t *grant) {
|
||||
fprintf(f, " - Number of PRBs:\t\t\t%d\n", grant->L_prb);
|
||||
fprintf(f, " - Modulation type:\t\t\t%s\n", srslte_mod_string(grant->mcs.mod));
|
||||
fprintf(f, " - Transport block size:\t\t%d\n", grant->mcs.tbs);
|
||||
}
|
||||
|
||||
char *ra_type_string(srslte_ra_type_t alloc_type) {
|
||||
switch (alloc_type) {
|
||||
case SRSLTE_RA_ALLOC_TYPE0:
|
||||
|
@ -569,54 +600,65 @@ char *ra_type_string(srslte_ra_type_t alloc_type) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void srslte_ra_pdsch_fprint(FILE *f, srslte_ra_pdsch_t *ra, uint32_t nof_prb) {
|
||||
void srslte_ra_pdsch_fprint(FILE *f, srslte_ra_dl_dci_t *dci, uint32_t nof_prb) {
|
||||
fprintf(f, " - Resource Allocation Type:\t\t%s\n",
|
||||
ra_type_string(ra->alloc_type));
|
||||
switch (ra->alloc_type) {
|
||||
ra_type_string(dci->alloc_type));
|
||||
switch (dci->alloc_type) {
|
||||
case SRSLTE_RA_ALLOC_TYPE0:
|
||||
fprintf(f, " + Resource Block Group Size:\t\t%d\n", srslte_ra_type0_P(nof_prb));
|
||||
fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", ra->type0_alloc.rbg_bitmask);
|
||||
fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", dci->type0_alloc.rbg_bitmask);
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE1:
|
||||
fprintf(f, " + Resource Block Group Size:\t\t%d\n", srslte_ra_type0_P(nof_prb));
|
||||
fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", ra->type1_alloc.vrb_bitmask);
|
||||
fprintf(f, " + RBG Subset:\t\t\t%d\n", ra->type1_alloc.rbg_subset);
|
||||
fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", dci->type1_alloc.vrb_bitmask);
|
||||
fprintf(f, " + RBG Subset:\t\t\t%d\n", dci->type1_alloc.rbg_subset);
|
||||
fprintf(f, " + RBG Shift:\t\t\t\t%s\n",
|
||||
ra->type1_alloc.shift ? "Yes" : "No");
|
||||
dci->type1_alloc.shift ? "Yes" : "No");
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE2:
|
||||
fprintf(f, " + Type:\t\t\t\t%s\n",
|
||||
ra->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC ? "Localized" : "Distributed");
|
||||
fprintf(f, " + Resource Indicator Value:\t\t%d\n", ra->type2_alloc.riv);
|
||||
if (ra->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) {
|
||||
dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC ? "Localized" : "Distributed");
|
||||
fprintf(f, " + Resource Indicator Value:\t\t%d\n", dci->type2_alloc.riv);
|
||||
if (dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) {
|
||||
fprintf(f, " + VRB Assignment:\t\t\t%d VRB starting with VRB %d\n",
|
||||
ra->type2_alloc.L_crb, ra->type2_alloc.RB_start);
|
||||
dci->type2_alloc.L_crb, dci->type2_alloc.RB_start);
|
||||
} else {
|
||||
fprintf(f, " + VRB Assignment:\t\t\t%d VRB starting with VRB %d\n",
|
||||
ra->type2_alloc.L_crb, ra->type2_alloc.RB_start);
|
||||
dci->type2_alloc.L_crb, dci->type2_alloc.RB_start);
|
||||
fprintf(f, " + VRB gap selection:\t\t\tGap %d\n",
|
||||
ra->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1 ? 1 : 2);
|
||||
dci->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1 ? 1 : 2);
|
||||
fprintf(f, " + VRB gap:\t\t\t\t%d\n",
|
||||
srslte_ra_type2_ngap(nof_prb, ra->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1));
|
||||
srslte_ra_type2_ngap(nof_prb, dci->type2_alloc.n_gap == SRSLTE_RA_TYPE2_NG1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
srslte_ra_dl_alloc_t alloc;
|
||||
srslte_ra_dl_alloc(&alloc, ra, nof_prb);
|
||||
for (int s = 0; s < 2; s++) {
|
||||
fprintf(f, " - PRB Bitmap Assignment %dst slot:\n", s);
|
||||
srslte_ra_prb_fprint(f, &alloc.slot[s], nof_prb);
|
||||
}
|
||||
|
||||
fprintf(f, " - Number of PRBs:\t\t\t%d\n", srslte_ra_nprb_dl(ra, nof_prb));
|
||||
fprintf(f, " - Modulation and coding scheme index:\t%d\n", ra->mcs_idx);
|
||||
fprintf(f, " - Modulation type:\t\t\t%s\n", srslte_mod_string(ra->mcs.mod));
|
||||
fprintf(f, " - Transport block size:\t\t%d\n", ra->mcs.tbs);
|
||||
fprintf(f, " - HARQ process:\t\t\t%d\n", ra->harq_process);
|
||||
fprintf(f, " - New data indicator:\t\t\t%s\n", ra->ndi ? "Yes" : "No");
|
||||
fprintf(f, " - Redundancy version:\t\t\t%d\n", ra->rv_idx);
|
||||
fprintf(f, " - Modulation and coding scheme index:\t%d\n", dci->mcs_idx);
|
||||
fprintf(f, " - HARQ process:\t\t\t%d\n", dci->harq_process);
|
||||
fprintf(f, " - New data indicator:\t\t\t%s\n", dci->ndi ? "Yes" : "No");
|
||||
fprintf(f, " - Redundancy version:\t\t\t%d\n", dci->rv_idx);
|
||||
fprintf(f, " - TPC command for PUCCH:\t\t--\n");
|
||||
}
|
||||
|
||||
void srslte_ra_dl_grant_fprint(FILE *f, srslte_ra_dl_grant_t *grant) {
|
||||
srslte_ra_prb_fprint(f, grant);
|
||||
fprintf(f, " - Number of PRBs:\t\t\t%d\n", grant->nof_prb);
|
||||
fprintf(f, " - Modulation type:\t\t\t%s\n", srslte_mod_string(grant->mcs.mod));
|
||||
fprintf(f, " - Transport block size:\t\t%d\n", grant->mcs.tbs);
|
||||
}
|
||||
|
||||
void srslte_ra_prb_fprint(FILE *f, srslte_ra_dl_grant_t *grant) {
|
||||
if (grant->nof_prb > 0) {
|
||||
for (int j=0;j<2;j++) {
|
||||
fprintf(f, " - PRB Bitmap Assignment %dst slot:\n", j);
|
||||
for (int i=0;i<SRSLTE_MAX_PRB;i++) {
|
||||
if (grant->prb_idx[j][i]) {
|
||||
fprintf(f, "%d, ", i);
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "srslte/phch/pdsch.h"
|
||||
#include "srslte/phch/pusch.h"
|
||||
#include "srslte/phch/sch.h"
|
||||
#include "srslte/phch/uci.h"
|
||||
|
@ -55,6 +56,33 @@ float beta_cqi_offset[16] = {-1.0, -1.0, 1.125, 1.25, 1.375, 1.625, 1.750, 2.0,
|
|||
3.125, 3.5, 4.0, 5.0, 6.25};
|
||||
|
||||
|
||||
uint32_t srslte_sch_find_Ioffset_ack(float beta) {
|
||||
for (int i=0;i<16;i++) {
|
||||
if (beta_harq_offset[i] >= beta) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t srslte_sch_find_Ioffset_ri(float beta) {
|
||||
for (int i=0;i<16;i++) {
|
||||
if (beta_ri_offset[i] >= beta) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t srslte_sch_find_Ioffset_cqi(float beta) {
|
||||
for (int i=0;i<16;i++) {
|
||||
if (beta_cqi_offset[i] >= beta) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int srslte_sch_init(srslte_sch_t *q) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q) {
|
||||
|
@ -69,22 +97,22 @@ int srslte_sch_init(srslte_sch_t *q) {
|
|||
goto clean;
|
||||
}
|
||||
|
||||
if (srslte_tcod_init(&q->encoder, MAX_LONG_CB)) {
|
||||
if (srslte_tcod_init(&q->encoder, SRSLTE_TCOD_MAX_LEN_CB)) {
|
||||
fprintf(stderr, "Error initiating Turbo Coder\n");
|
||||
goto clean;
|
||||
}
|
||||
if (srslte_tdec_init(&q->decoder, MAX_LONG_CB)) {
|
||||
if (srslte_tdec_init(&q->decoder, SRSLTE_TCOD_MAX_LEN_CB)) {
|
||||
fprintf(stderr, "Error initiating Turbo Decoder\n");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
// Allocate floats for reception (LLRs)
|
||||
q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * MAX_LONG_CB);
|
||||
q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB);
|
||||
if (!q->cb_in) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
q->cb_out = srslte_vec_malloc(sizeof(float) * (3 * MAX_LONG_CB + 12));
|
||||
q->cb_out = srslte_vec_malloc(sizeof(float) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 12));
|
||||
if (!q->cb_out) {
|
||||
goto clean;
|
||||
}
|
||||
|
@ -128,7 +156,10 @@ uint32_t srslte_sch_last_noi(srslte_sch_t *q) {
|
|||
/* Encode a transport block according to 36.212 5.3.2
|
||||
*
|
||||
*/
|
||||
static int encode_tb(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_t *e_bits, uint32_t nof_e_bits)
|
||||
static int encode_tb(srslte_sch_t *q,
|
||||
srslte_softbuffer_tx_t *soft_buffer, srslte_cbsegm_t *cb_segm,
|
||||
uint32_t Qm, uint32_t rv, uint32_t nof_e_bits,
|
||||
uint8_t *data, uint8_t *e_bits)
|
||||
{
|
||||
uint8_t parity[24];
|
||||
uint8_t *p_parity = parity;
|
||||
|
@ -136,30 +167,31 @@ static int encode_tb(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_
|
|||
uint32_t i;
|
||||
uint32_t cb_len, rp, wp, rlen, F, n_e;
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
uint32_t Qm = srslte_mod_bits_x_symbol(harq->mcs.mod);
|
||||
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
e_bits != NULL &&
|
||||
cb_segm != NULL &&
|
||||
soft_buffer != NULL)
|
||||
{
|
||||
|
||||
uint32_t Gp = nof_e_bits / Qm;
|
||||
|
||||
uint32_t gamma = Gp;
|
||||
if (harq->cb_segm.C > 0) {
|
||||
gamma = Gp%harq->cb_segm.C;
|
||||
if (cb_segm->C > 0) {
|
||||
gamma = Gp%cb_segm->C;
|
||||
}
|
||||
|
||||
if (harq->rv == 0) {
|
||||
if (rv == 0) {
|
||||
/* Compute transport block CRC */
|
||||
par = srslte_crc_checksum(&q->crc_tb, data, harq->mcs.tbs);
|
||||
par = srslte_crc_checksum(&q->crc_tb, data, cb_segm->tbs);
|
||||
|
||||
/* parity bits will be appended later */
|
||||
srslte_bit_pack(par, &p_parity, 24);
|
||||
|
||||
if (SRSLTE_VERBOSE_ISDEBUG()) {
|
||||
DEBUG("DATA: ", 0);
|
||||
srslte_vec_fprint_b(stdout, data, harq->mcs.tbs);
|
||||
srslte_vec_fprint_b(stdout, data, cb_segm->tbs);
|
||||
DEBUG("PARITY: ", 0);
|
||||
srslte_vec_fprint_b(stdout, parity, 24);
|
||||
}
|
||||
|
@ -167,37 +199,37 @@ static int encode_tb(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_
|
|||
|
||||
wp = 0;
|
||||
rp = 0;
|
||||
for (i = 0; i < harq->cb_segm.C; i++) {
|
||||
for (i = 0; i < cb_segm->C; i++) {
|
||||
|
||||
/* Get read lengths */
|
||||
if (i < harq->cb_segm.C2) {
|
||||
cb_len = harq->cb_segm.K2;
|
||||
if (i < cb_segm->C2) {
|
||||
cb_len = cb_segm->K2;
|
||||
} else {
|
||||
cb_len = harq->cb_segm.K1;
|
||||
cb_len = cb_segm->K1;
|
||||
}
|
||||
if (harq->cb_segm.C > 1) {
|
||||
if (cb_segm->C > 1) {
|
||||
rlen = cb_len - 24;
|
||||
} else {
|
||||
rlen = cb_len;
|
||||
}
|
||||
if (i == 0) {
|
||||
F = harq->cb_segm.F;
|
||||
F = cb_segm->F;
|
||||
} else {
|
||||
F = 0;
|
||||
}
|
||||
if (i <= harq->cb_segm.C - gamma - 1) {
|
||||
n_e = Qm * (Gp/harq->cb_segm.C);
|
||||
if (i <= cb_segm->C - gamma - 1) {
|
||||
n_e = Qm * (Gp/cb_segm->C);
|
||||
} else {
|
||||
n_e = Qm * ((uint32_t) ceilf((float) Gp/harq->cb_segm.C));
|
||||
n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C));
|
||||
}
|
||||
|
||||
INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i,
|
||||
cb_len, rlen - F, wp, rp, F, n_e);
|
||||
|
||||
if (harq->rv == 0) {
|
||||
if (rv == 0) {
|
||||
|
||||
/* Copy data to another buffer, making space for the Codeblock CRC */
|
||||
if (i < harq->cb_segm.C - 1) {
|
||||
if (i < cb_segm->C - 1) {
|
||||
// Copy data
|
||||
memcpy(&q->cb_in[F], &data[rp], (rlen - F) * sizeof(uint8_t));
|
||||
} else {
|
||||
|
@ -212,7 +244,7 @@ static int encode_tb(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_
|
|||
q->cb_in[j] = 0;
|
||||
}
|
||||
/* Attach Codeblock CRC */
|
||||
if (harq->cb_segm.C > 1) {
|
||||
if (cb_segm->C > 1) {
|
||||
srslte_crc_attach(&q->crc_cb, q->cb_in, rlen);
|
||||
}
|
||||
/* Set the filler bits to <NULL> */
|
||||
|
@ -229,9 +261,9 @@ static int encode_tb(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_
|
|||
}
|
||||
|
||||
/* Rate matching */
|
||||
if (srslte_rm_turbo_tx(harq->pdsch_w_buff_c[i], harq->w_buff_size,
|
||||
if (srslte_rm_turbo_tx(soft_buffer->buffer_b[i], soft_buffer->buff_size,
|
||||
(uint8_t*) q->cb_out, 3 * cb_len + 12,
|
||||
&e_bits[wp], n_e, harq->rv))
|
||||
&e_bits[wp], n_e, rv))
|
||||
{
|
||||
fprintf(stderr, "Error in rate matching\n");
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -251,21 +283,25 @@ static int encode_tb(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_
|
|||
/* Decode a transport block according to 36.212 5.3.2
|
||||
*
|
||||
*/
|
||||
static int decode_tb(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_t *data, uint32_t nof_e_bits)
|
||||
static int decode_tb(srslte_sch_t *q,
|
||||
srslte_softbuffer_rx_t *softbuffer, srslte_cbsegm_t *cb_segm,
|
||||
uint32_t Qm, uint32_t rv, uint32_t nof_e_bits,
|
||||
float *e_bits, uint8_t *data)
|
||||
{
|
||||
uint8_t parity[24];
|
||||
uint8_t *p_parity = parity;
|
||||
uint32_t par_rx, par_tx;
|
||||
uint32_t i;
|
||||
uint32_t cb_len, rp, wp, rlen, F, n_e;
|
||||
uint32_t Qm = srslte_mod_bits_x_symbol(harq->mcs.mod);
|
||||
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
harq != NULL)
|
||||
if (q != NULL &&
|
||||
data != NULL &&
|
||||
softbuffer != NULL &&
|
||||
e_bits != NULL &&
|
||||
cb_segm != NULL)
|
||||
{
|
||||
|
||||
if (harq->mcs.tbs == 0 || harq->cb_segm.C == 0) {
|
||||
if (cb_segm->tbs == 0 || cb_segm->C == 0) {
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -275,43 +311,43 @@ static int decode_tb(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_
|
|||
uint32_t Gp = nof_e_bits / Qm;
|
||||
uint32_t gamma=Gp;
|
||||
|
||||
if (harq->cb_segm.C>0) {
|
||||
gamma = Gp%harq->cb_segm.C;
|
||||
if (cb_segm->C>0) {
|
||||
gamma = Gp%cb_segm->C;
|
||||
}
|
||||
|
||||
bool early_stop = true;
|
||||
for (i = 0; i < harq->cb_segm.C && early_stop; i++) {
|
||||
for (i = 0; i < cb_segm->C && early_stop; i++) {
|
||||
|
||||
/* Get read/write lengths */
|
||||
if (i < harq->cb_segm.C2) {
|
||||
cb_len = harq->cb_segm.K2;
|
||||
if (i < cb_segm->C2) {
|
||||
cb_len = cb_segm->K2;
|
||||
} else {
|
||||
cb_len = harq->cb_segm.K1;
|
||||
cb_len = cb_segm->K1;
|
||||
}
|
||||
if (harq->cb_segm.C == 1) {
|
||||
if (cb_segm->C == 1) {
|
||||
rlen = cb_len;
|
||||
} else {
|
||||
rlen = cb_len - 24;
|
||||
}
|
||||
if (i == 0) {
|
||||
F = harq->cb_segm.F;
|
||||
F = cb_segm->F;
|
||||
} else {
|
||||
F = 0;
|
||||
}
|
||||
|
||||
if (i <= harq->cb_segm.C - gamma - 1) {
|
||||
n_e = Qm * (Gp/harq->cb_segm.C);
|
||||
if (i <= cb_segm->C - gamma - 1) {
|
||||
n_e = Qm * (Gp/cb_segm->C);
|
||||
} else {
|
||||
n_e = Qm * ((uint32_t) ceilf((float) Gp/harq->cb_segm.C));
|
||||
n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C));
|
||||
}
|
||||
|
||||
INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i,
|
||||
cb_len, rlen - F, wp, rp, F, n_e);
|
||||
|
||||
/* Rate Unmatching */
|
||||
if (srslte_rm_turbo_rx(harq->pdsch_w_buff_f[i], harq->w_buff_size,
|
||||
if (srslte_rm_turbo_rx(softbuffer->buffer_f[i], softbuffer->buff_size,
|
||||
&e_bits[rp], n_e,
|
||||
(float*) q->cb_out, 3 * cb_len + 12, harq->rv, F)) {
|
||||
(float*) q->cb_out, 3 * cb_len + 12, rv, F)) {
|
||||
fprintf(stderr, "Error in rate matching\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
@ -334,12 +370,12 @@ static int decode_tb(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_
|
|||
srslte_tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len);
|
||||
q->nof_iterations++;
|
||||
|
||||
if (harq->cb_segm.C > 1) {
|
||||
if (cb_segm->C > 1) {
|
||||
len_crc = cb_len;
|
||||
cb_in_ptr = q->cb_in;
|
||||
crc_ptr = &q->crc_cb;
|
||||
} else {
|
||||
len_crc = harq->mcs.tbs+24;
|
||||
len_crc = cb_segm->tbs+24;
|
||||
cb_in_ptr = &q->cb_in[F];
|
||||
crc_ptr = &q->crc_tb;
|
||||
}
|
||||
|
@ -362,7 +398,7 @@ static int decode_tb(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_
|
|||
// If CB CRC is not correct, early_stop will be false and wont continue with rest of CBs
|
||||
|
||||
/* Copy data to another buffer, removing the Codeblock CRC */
|
||||
if (i < harq->cb_segm.C - 1) {
|
||||
if (i < cb_segm->C - 1) {
|
||||
memcpy(&data[wp], &q->cb_in[F], (rlen - F) * sizeof(uint8_t));
|
||||
} else {
|
||||
DEBUG("Last CB, appending parity: %d to %d from %d and 24 from %d\n",
|
||||
|
@ -385,7 +421,7 @@ static int decode_tb(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_
|
|||
INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp);
|
||||
|
||||
// Compute transport block CRC
|
||||
par_rx = srslte_crc_checksum(&q->crc_tb, data, harq->mcs.tbs);
|
||||
par_rx = srslte_crc_checksum(&q->crc_tb, data, cb_segm->tbs);
|
||||
|
||||
// check parity bits
|
||||
par_tx = srslte_bit_unpack(&p_parity, 24);
|
||||
|
@ -408,23 +444,36 @@ static int decode_tb(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_
|
|||
}
|
||||
}
|
||||
|
||||
int srslte_dlsch_decode(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_t *data)
|
||||
int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
|
||||
float *e_bits, uint8_t *data)
|
||||
{
|
||||
return decode_tb(q, harq, e_bits, data, harq->nof_bits);
|
||||
return decode_tb(q,
|
||||
softbuffer, &cfg->cb_segm,
|
||||
cfg->grant.Qm, cfg->rv, cfg->grant.nof_bits,
|
||||
e_bits, data);
|
||||
}
|
||||
|
||||
int srslte_dlsch_encode(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_t *e_bits) {
|
||||
return encode_tb(q, harq, data, e_bits, harq->nof_bits);
|
||||
int srslte_dlsch_encode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data, uint8_t *e_bits)
|
||||
{
|
||||
return encode_tb(q,
|
||||
softbuffer, &cfg->cb_segm,
|
||||
cfg->grant.Qm, cfg->rv, cfg->grant.nof_bits,
|
||||
data, e_bits);
|
||||
}
|
||||
|
||||
int srslte_ulsch_decode(srslte_sch_t *q, srslte_harq_t *harq, float *e_bits, uint8_t *data)
|
||||
int srslte_ulsch_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
|
||||
float *e_bits, uint8_t *data)
|
||||
{
|
||||
return decode_tb(q, harq, e_bits, data, harq->nof_bits);
|
||||
return decode_tb(q,
|
||||
softbuffer, &cfg->cb_segm,
|
||||
cfg->grant.Qm, cfg->rv, cfg->grant.nof_bits,
|
||||
e_bits, data);
|
||||
}
|
||||
|
||||
|
||||
/* UL-SCH channel interleaver according to 5.5.2.8 of 36.212 */
|
||||
void ulsch_interleave(uint8_t *g_bits, uint32_t Q_m, uint32_t H_prime_total, uint32_t N_pusch_symbs, uint8_t *q_bits)
|
||||
void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, uint8_t *q_bits)
|
||||
{
|
||||
|
||||
uint32_t rows = H_prime_total/N_pusch_symbs;
|
||||
|
@ -433,11 +482,11 @@ void ulsch_interleave(uint8_t *g_bits, uint32_t Q_m, uint32_t H_prime_total, uin
|
|||
uint32_t idx = 0;
|
||||
for(uint32_t j=0; j<rows; j++) {
|
||||
for(uint32_t i=0; i<cols; i++) {
|
||||
for(uint32_t k=0; k<Q_m; k++) {
|
||||
if (q_bits[j*Q_m + i*rows*Q_m + k] >= 10) {
|
||||
q_bits[j*Q_m + i*rows*Q_m + k] -= 10;
|
||||
for(uint32_t k=0; k<Qm; k++) {
|
||||
if (q_bits[j*Qm + i*rows*Qm + k] >= 10) {
|
||||
q_bits[j*Qm + i*rows*Qm + k] -= 10;
|
||||
} else {
|
||||
q_bits[j*Q_m + i*rows*Q_m + k] = g_bits[idx];
|
||||
q_bits[j*Qm + i*rows*Qm + k] = g_bits[idx];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
@ -446,15 +495,18 @@ void ulsch_interleave(uint8_t *g_bits, uint32_t Q_m, uint32_t H_prime_total, uin
|
|||
|
||||
}
|
||||
|
||||
int srslte_ulsch_encode(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, uint8_t *g_bits, uint8_t *q_bits)
|
||||
int srslte_ulsch_encode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data, uint8_t *g_bits, uint8_t *q_bits)
|
||||
{
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
return srslte_ulsch_uci_encode(q, harq, data, uci_data, g_bits, q_bits);
|
||||
return srslte_ulsch_uci_encode(q, cfg, softbuffer, data, uci_data, g_bits, q_bits);
|
||||
}
|
||||
|
||||
|
||||
int srslte_ulsch_uci_encode(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data, srslte_uci_data_t uci_data, uint8_t *g_bits, uint8_t *q_bits)
|
||||
int srslte_ulsch_uci_encode(srslte_sch_t *q,
|
||||
srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data, srslte_uci_data_t uci_data,
|
||||
uint8_t *g_bits, uint8_t *q_bits)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -462,20 +514,19 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data,
|
|||
uint32_t Q_prime_cqi = 0;
|
||||
uint32_t Q_prime_ack = 0;
|
||||
uint32_t Q_prime_ri = 0;
|
||||
uint32_t Q_m = srslte_mod_bits_x_symbol(harq->mcs.mod);
|
||||
|
||||
uint32_t nof_symbols = 12*harq->ul_alloc.L_prb*SRSLTE_NRE;
|
||||
uint32_t nb_q = nof_symbols * Q_m;
|
||||
|
||||
uint32_t nb_q = cfg->grant.nof_bits;
|
||||
uint32_t Qm = cfg->grant.Qm;
|
||||
|
||||
bzero(q_bits, sizeof(uint8_t) * nb_q);
|
||||
|
||||
// Encode RI
|
||||
if (uci_data.uci_ri_len > 0) {
|
||||
float beta = beta_ri_offset[uci_data.I_offset_ri];
|
||||
if (harq->mcs.tbs == 0) {
|
||||
if (cfg->cb_segm.tbs == 0) {
|
||||
beta /= beta_cqi_offset[uci_data.I_offset_cqi];
|
||||
}
|
||||
ret = srslte_uci_encode_ri(uci_data.uci_ri, uci_data.uci_cqi_len, beta, harq, nb_q/Q_m, q_bits);
|
||||
ret = srslte_uci_encode_ri(cfg, uci_data.uci_ri, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -484,37 +535,39 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data,
|
|||
|
||||
// Encode CQI
|
||||
if (uci_data.uci_cqi_len > 0) {
|
||||
|
||||
ret = srslte_uci_encode_cqi_pusch(&q->uci_cqi, uci_data.uci_cqi, uci_data.uci_cqi_len,
|
||||
ret = srslte_uci_encode_cqi_pusch(&q->uci_cqi, cfg,
|
||||
uci_data.uci_cqi, uci_data.uci_cqi_len,
|
||||
beta_cqi_offset[uci_data.I_offset_cqi],
|
||||
Q_prime_ri, harq, g_bits);
|
||||
Q_prime_ri, g_bits);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
Q_prime_cqi = (uint32_t) ret;
|
||||
}
|
||||
|
||||
e_offset += Q_prime_cqi*Q_m;
|
||||
e_offset += Q_prime_cqi*Qm;
|
||||
|
||||
// Encode UL-SCH
|
||||
if (harq->mcs.tbs > 0) {
|
||||
uint32_t G = nb_q/Q_m - Q_prime_ri - Q_prime_cqi;
|
||||
ret = encode_tb(q, harq, data, &g_bits[e_offset], G*Q_m);
|
||||
if (cfg->cb_segm.tbs > 0) {
|
||||
uint32_t G = nb_q/Qm - Q_prime_ri - Q_prime_cqi;
|
||||
ret = encode_tb(q, softbuffer, &cfg->cb_segm,
|
||||
Qm, cfg->rv, G*Qm,
|
||||
data, &g_bits[e_offset]);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Interleave UL-SCH (and RI and CQI)
|
||||
ulsch_interleave(g_bits, Q_m, nb_q/Q_m, harq->nof_symb, q_bits);
|
||||
ulsch_interleave(g_bits, Qm, nb_q/Qm, cfg->grant.nof_symb, q_bits);
|
||||
|
||||
// Encode (and interleave) ACK
|
||||
if (uci_data.uci_ack_len > 0) {
|
||||
float beta = beta_harq_offset[uci_data.I_offset_ack];
|
||||
if (harq->mcs.tbs == 0) {
|
||||
if (cfg->cb_segm.tbs == 0) {
|
||||
beta /= beta_cqi_offset[uci_data.I_offset_cqi];
|
||||
}
|
||||
ret = srslte_uci_encode_ack(uci_data.uci_ack, uci_data.uci_cqi_len, beta, harq, nb_q/Q_m, q_bits);
|
||||
ret = srslte_uci_encode_ack(cfg, uci_data.uci_ack, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -523,8 +576,6 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, srslte_harq_t *harq, uint8_t *data,
|
|||
|
||||
INFO("Q_prime_ack=%d, Q_prime_cqi=%d, Q_prime_ri=%d\n",Q_prime_ack, Q_prime_cqi, Q_prime_ri);
|
||||
|
||||
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/phch/ra.h"
|
||||
#include "srslte/fec/turbodecoder.h"
|
||||
#include "srslte/phch/softbuffer.h"
|
||||
#include "srslte/utils/vector.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
|
||||
#define MAX_PDSCH_RE(cp) (2 * SRSLTE_CP_NSYMB(cp) * 12)
|
||||
|
||||
int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, srslte_cell_t cell) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL) {
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
bzero(q, sizeof(srslte_softbuffer_rx_t));
|
||||
|
||||
ret = srslte_ra_tbs_from_idx(26, cell.nof_prb);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1;
|
||||
|
||||
q->buffer_f = srslte_vec_malloc(sizeof(float*) * q->max_cb);
|
||||
if (!q->buffer_f) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// FIXME: Use HARQ buffer limitation based on UE category
|
||||
q->buff_size = cell.nof_prb * MAX_PDSCH_RE(cell.cp) * 6 * 10;
|
||||
for (uint32_t i=0;i<q->max_cb;i++) {
|
||||
q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * q->buff_size);
|
||||
if (!q->buffer_f[i]) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
srslte_softbuffer_rx_reset(q);
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *q) {
|
||||
if (q) {
|
||||
if (q->buffer_f) {
|
||||
for (uint32_t i=0;i<q->max_cb;i++) {
|
||||
if (q->buffer_f[i]) {
|
||||
free(q->buffer_f[i]);
|
||||
}
|
||||
}
|
||||
free(q->buffer_f);
|
||||
}
|
||||
bzero(q, sizeof(srslte_softbuffer_rx_t));
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_softbuffer_rx_reset(srslte_softbuffer_rx_t *q) {
|
||||
int i;
|
||||
if (q->buffer_f) {
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->buffer_f[i]) {
|
||||
bzero(q->buffer_f[i], sizeof(float) * q->buff_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, srslte_cell_t cell) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL) {
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
bzero(q, sizeof(srslte_softbuffer_tx_t));
|
||||
|
||||
ret = srslte_ra_tbs_from_idx(26, cell.nof_prb);
|
||||
if (ret != SRSLTE_ERROR) {
|
||||
q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1;
|
||||
|
||||
q->buffer_b = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb);
|
||||
if (!q->buffer_b) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// FIXME: Use HARQ buffer limitation based on UE category
|
||||
q->buff_size = cell.nof_prb * MAX_PDSCH_RE(cell.cp) * 6 * 10;
|
||||
for (uint32_t i=0;i<q->max_cb;i++) {
|
||||
q->buffer_b[i] = srslte_vec_malloc(sizeof(float) * q->buff_size);
|
||||
if (!q->buffer_b[i]) {
|
||||
perror("malloc");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
srslte_softbuffer_tx_reset(q);
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_softbuffer_tx_free(srslte_softbuffer_tx_t *q) {
|
||||
if (q) {
|
||||
if (q->buffer_b) {
|
||||
for (uint32_t i=0;i<q->max_cb;i++) {
|
||||
if (q->buffer_b[i]) {
|
||||
free(q->buffer_b[i]);
|
||||
}
|
||||
}
|
||||
free(q->buffer_b);
|
||||
}
|
||||
bzero(q, sizeof(srslte_softbuffer_tx_t));
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_softbuffer_tx_reset(srslte_softbuffer_tx_t *q) {
|
||||
int i;
|
||||
if (q->buffer_b) {
|
||||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->buffer_b[i]) {
|
||||
bzero(q->buffer_b[i], sizeof(uint8_t) * q->buff_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@
|
|||
#include <math.h>
|
||||
|
||||
#include "srslte/phch/uci.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/fec/cbsegm.h"
|
||||
#include "srslte/fec/convcoder.h"
|
||||
#include "srslte/fec/crc.h"
|
||||
#include "srslte/fec/rm_conv.h"
|
||||
|
@ -114,22 +114,21 @@ void srslte_uci_cqi_free(srslte_uci_cqi_pusch_t *q) {
|
|||
|
||||
}
|
||||
|
||||
static uint32_t Q_prime_cqi(uint32_t O, float beta, uint32_t Q_prime_ri, srslte_harq_t *harq) {
|
||||
uint32_t M_sc = harq->ul_alloc.L_prb * SRSLTE_NRE;
|
||||
static uint32_t Q_prime_cqi(srslte_pusch_cfg_t *cfg,
|
||||
uint32_t O, float beta, uint32_t Q_prime_ri)
|
||||
{
|
||||
|
||||
uint32_t K = harq->cb_segm.C1*harq->cb_segm.K1 +
|
||||
harq->cb_segm.C2*harq->cb_segm.K2;
|
||||
uint32_t K = cfg->cb_segm.C1*cfg->cb_segm.K1 + cfg->cb_segm.C2*cfg->cb_segm.K2;
|
||||
|
||||
uint32_t Q_prime = 0;
|
||||
uint32_t L = (O<11)?0:8;
|
||||
uint32_t x = 999999;
|
||||
|
||||
if (K > 0) {
|
||||
uint32_t M_sc_init = harq->nof_prb * SRSLTE_NRE;
|
||||
uint32_t L = (O<11)?0:8;
|
||||
uint32_t x = (uint32_t) ceilf((float) (O+L)*M_sc_init*harq->nof_symb*beta/K);
|
||||
|
||||
Q_prime = SRSLTE_MIN(x, M_sc * harq->nof_symb - Q_prime_ri);
|
||||
} else {
|
||||
Q_prime = 12*harq->ul_alloc.L_prb*SRSLTE_NRE - Q_prime_ri;
|
||||
x = (uint32_t) ceilf((float) (O+L)*cfg->grant.M_sc_init*cfg->grant.nof_symb*beta/K);
|
||||
}
|
||||
|
||||
Q_prime = SRSLTE_MIN(x, cfg->grant.M_sc * cfg->grant.nof_symb - Q_prime_ri);
|
||||
|
||||
return Q_prime;
|
||||
}
|
||||
|
@ -217,21 +216,23 @@ int srslte_uci_encode_cqi_pucch(uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_b
|
|||
|
||||
/* Encode UCI CQI/PMI as described in 5.2.2.6 of 36.212
|
||||
*/
|
||||
int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t *q, uint8_t *cqi_data, uint32_t cqi_len, float beta, uint32_t Q_prime_ri,
|
||||
srslte_harq_t *harq, uint8_t *q_bits)
|
||||
int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t *q, srslte_pusch_cfg_t *cfg,
|
||||
uint8_t *cqi_data, uint32_t cqi_len,
|
||||
float beta, uint32_t Q_prime_ri,
|
||||
uint8_t *q_bits)
|
||||
{
|
||||
if (beta < 0) {
|
||||
fprintf(stderr, "Error beta is reserved\n");
|
||||
return -1;
|
||||
}
|
||||
uint32_t Q_prime = Q_prime_cqi(cqi_len, beta, Q_prime_ri, harq);
|
||||
uint32_t Q_m = srslte_mod_bits_x_symbol(harq->mcs.mod);
|
||||
|
||||
uint32_t Q_prime = Q_prime_cqi(cfg, cqi_len, beta, Q_prime_ri);
|
||||
|
||||
int ret = SRSLTE_ERROR;
|
||||
if (cqi_len <= 11) {
|
||||
ret = encode_cqi_short(q, cqi_data, cqi_len, q_bits, Q_prime*Q_m);
|
||||
ret = encode_cqi_short(q, cqi_data, cqi_len, q_bits, Q_prime*cfg->grant.Qm);
|
||||
} else {
|
||||
ret = encode_cqi_long(q, cqi_data, cqi_len, q_bits, Q_prime*Q_m);
|
||||
ret = encode_cqi_long(q, cqi_data, cqi_len, q_bits, Q_prime*cfg->grant.Qm);
|
||||
}
|
||||
if (ret) {
|
||||
return ret;
|
||||
|
@ -242,7 +243,7 @@ int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t *q, uint8_t *cqi_data, ui
|
|||
|
||||
/* Inserts UCI-ACK bits into the correct positions in the g buffer before interleaving */
|
||||
static int uci_ulsch_interleave_ack(uint8_t ack_coded_bits[6], uint32_t ack_q_bit_idx,
|
||||
uint32_t Q_m, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp,
|
||||
uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp,
|
||||
uint8_t *q_bits) {
|
||||
|
||||
const uint32_t ack_column_set_norm[4] = {2, 3, 8, 9};
|
||||
|
@ -253,9 +254,9 @@ static int uci_ulsch_interleave_ack(uint8_t ack_coded_bits[6], uint32_t ack_q_bi
|
|||
uint32_t row = H_prime_total/N_pusch_symbs-1-ack_q_bit_idx/4;
|
||||
uint32_t colidx = (3*ack_q_bit_idx)%4;
|
||||
uint32_t col = SRSLTE_CP_ISNORM(cp)?ack_column_set_norm[colidx]:ack_column_set_ext[colidx];
|
||||
for(uint32_t k=0; k<Q_m; k++) {
|
||||
q_bits[row *Q_m +
|
||||
(H_prime_total/N_pusch_symbs)*col*Q_m + k] = ack_coded_bits[k];
|
||||
for(uint32_t k=0; k<Qm; k++) {
|
||||
q_bits[row *Qm +
|
||||
(H_prime_total/N_pusch_symbs)*col*Qm + k] = ack_coded_bits[k];
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
} else {
|
||||
|
@ -267,7 +268,7 @@ static int uci_ulsch_interleave_ack(uint8_t ack_coded_bits[6], uint32_t ack_q_bi
|
|||
|
||||
/* Inserts UCI-RI bits into the correct positions in the g buffer before interleaving */
|
||||
static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_idx,
|
||||
uint32_t Q_m, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp,
|
||||
uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp,
|
||||
uint8_t *q_bits) {
|
||||
|
||||
static uint32_t ri_column_set_norm[4] = {1, 4, 7, 10};
|
||||
|
@ -278,8 +279,8 @@ static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_i
|
|||
uint32_t colidx = (3*ri_q_bit_idx)%4;
|
||||
uint32_t col = SRSLTE_CP_ISNORM(cp)?ri_column_set_norm[colidx]:ri_column_set_ext[colidx];
|
||||
printf("r=%d-%d\n",H_prime_total/N_pusch_symbs,1+ri_q_bit_idx/4);
|
||||
for(uint32_t k=0; k<Q_m; k++) {
|
||||
q_bits[row *Q_m + (H_prime_total/N_pusch_symbs)*col*Q_m + k] = 10+ri_coded_bits[k];
|
||||
for(uint32_t k=0; k<Qm; k++) {
|
||||
q_bits[row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k] = 10+ri_coded_bits[k];
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
} else {
|
||||
|
@ -290,17 +291,15 @@ static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_i
|
|||
|
||||
}
|
||||
|
||||
static uint32_t Q_prime_ri_ack(uint32_t O, uint32_t O_cqi, float beta, srslte_harq_t *harq) {
|
||||
static uint32_t Q_prime_ri_ack(srslte_pusch_cfg_t *cfg,
|
||||
uint32_t O, uint32_t O_cqi, float beta) {
|
||||
|
||||
if (beta < 0) {
|
||||
fprintf(stderr, "Error beta is reserved\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t M_sc = harq->ul_alloc.L_prb * SRSLTE_NRE;
|
||||
|
||||
uint32_t K = harq->cb_segm.C1*harq->cb_segm.K1 +
|
||||
harq->cb_segm.C2*harq->cb_segm.K2;
|
||||
uint32_t K = cfg->cb_segm.C1*cfg->cb_segm.K1 + cfg->cb_segm.C2*cfg->cb_segm.K2;
|
||||
|
||||
// If not carrying UL-SCH, get Q_prime according to 5.2.4.1
|
||||
if (K == 0) {
|
||||
|
@ -311,19 +310,17 @@ static uint32_t Q_prime_ri_ack(uint32_t O, uint32_t O_cqi, float beta, srslte_ha
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t M_sc_init = harq->nof_prb * SRSLTE_NRE;
|
||||
|
||||
uint32_t x = (uint32_t) ceilf((float) O*M_sc_init*harq->nof_symb*beta/K);
|
||||
uint32_t x = (uint32_t) ceilf((float) O*cfg->grant.M_sc_init*cfg->grant.nof_symb*beta/K);
|
||||
|
||||
uint32_t Q_prime = SRSLTE_MIN(x, 4*M_sc);
|
||||
uint32_t Q_prime = SRSLTE_MIN(x, 4*cfg->grant.M_sc);
|
||||
|
||||
return Q_prime;
|
||||
}
|
||||
|
||||
static void encode_ri_ack(uint8_t data, uint8_t q_encoded_bits[6], uint8_t Q_m) {
|
||||
static void encode_ri_ack(uint8_t data, uint8_t q_encoded_bits[6], uint8_t Qm) {
|
||||
q_encoded_bits[0] = data;
|
||||
q_encoded_bits[1] = 2;
|
||||
for (uint32_t i=2;i<Q_m;i++) {
|
||||
for (uint32_t i=2;i<Qm;i++) {
|
||||
q_encoded_bits[i] = 3;
|
||||
}
|
||||
}
|
||||
|
@ -331,23 +328,23 @@ static void encode_ri_ack(uint8_t data, uint8_t q_encoded_bits[6], uint8_t Q_m)
|
|||
/* Encode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212
|
||||
* Currently only supporting 1-bit HARQ
|
||||
*/
|
||||
int srslte_uci_encode_ack(uint8_t data, uint32_t O_cqi,
|
||||
float beta, srslte_harq_t *harq,
|
||||
uint32_t H_prime_total, uint8_t *q_bits)
|
||||
int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
||||
uint8_t data,
|
||||
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
||||
uint8_t *q_bits)
|
||||
{
|
||||
if (beta < 0) {
|
||||
fprintf(stderr, "Error beta is reserved\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t Q_m = srslte_mod_bits_x_symbol(harq->mcs.mod);
|
||||
uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq);
|
||||
uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta);
|
||||
uint8_t q_encoded_bits[6];
|
||||
|
||||
encode_ri_ack(data, q_encoded_bits, Q_m);
|
||||
encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
|
||||
|
||||
for (uint32_t i=0;i<Qprime;i++) {
|
||||
uci_ulsch_interleave_ack(q_encoded_bits, i, Q_m, H_prime_total, harq->nof_symb, harq->cell.cp, q_bits);
|
||||
uci_ulsch_interleave_ack(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->grant.nof_symb, cfg->cp, q_bits);
|
||||
}
|
||||
|
||||
return (int) Qprime;
|
||||
|
@ -357,23 +354,22 @@ int srslte_uci_encode_ack(uint8_t data, uint32_t O_cqi,
|
|||
/* Encode UCI RI bits as described in 5.2.2.6 of 36.212
|
||||
* Currently only supporting 1-bit RI
|
||||
*/
|
||||
int srslte_uci_encode_ri(uint8_t data, uint32_t O_cqi, float beta,
|
||||
srslte_harq_t *harq, uint32_t H_prime_total,
|
||||
int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
|
||||
uint8_t data,
|
||||
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
||||
uint8_t *q_bits)
|
||||
{
|
||||
if (beta < 0) {
|
||||
fprintf(stderr, "Error beta is reserved\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t Q_m = srslte_mod_bits_x_symbol(harq->mcs.mod);
|
||||
uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq);
|
||||
uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta);
|
||||
uint8_t q_encoded_bits[6];
|
||||
|
||||
encode_ri_ack(data, q_encoded_bits, Q_m);
|
||||
encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
|
||||
|
||||
for (uint32_t i=0;i<Qprime;i++) {
|
||||
uci_ulsch_interleave_ri(q_encoded_bits, i, Q_m, H_prime_total, harq->nof_symb, harq->cell.cp, q_bits);
|
||||
uci_ulsch_interleave_ri(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->grant.nof_symb, cfg->cp, q_bits);
|
||||
}
|
||||
|
||||
return (int) Qprime;
|
||||
|
|
|
@ -39,7 +39,7 @@ void usage(char *prog) {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
srslte_dci_msg_t msg;
|
||||
srslte_ra_pdsch_t ra_dl;
|
||||
srslte_ra_dl_dci_t ra_dl;
|
||||
int len, rlen;
|
||||
int nof_prb;
|
||||
int nwords;
|
||||
|
@ -91,7 +91,7 @@ int main(int argc, char **argv) {
|
|||
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_pdsch_t));
|
||||
bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
srslte_dci_msg_unpack_pdsch(&msg, &ra_dl, nof_prb, false);
|
||||
srslte_ra_pdsch_fprint(stdout, &ra_dl, nof_prb);
|
||||
break;
|
||||
|
|
|
@ -46,16 +46,14 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
{
|
||||
srslte_sch_t dlsch;
|
||||
uint8_t *trblkin;
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_dl_alloc_t prb_alloc;
|
||||
srslte_harq_t harq_process;
|
||||
uint32_t rv;
|
||||
srslte_pdsch_cfg_t cfg;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
|
||||
if (nrhs < NOF_INPUTS) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (srslte_sch_init(&dlsch)) {
|
||||
mexErrMsgTxt("Error initiating DL-SCH\n");
|
||||
return;
|
||||
|
@ -63,18 +61,14 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
srslte_cell_t cell;
|
||||
cell.nof_prb = 100;
|
||||
cell.id=1;
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
mexErrMsgTxt("Error initiating HARQ\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
if (mcs.tbs == 0) {
|
||||
|
||||
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
if (cfg.grant.mcs.tbs == 0) {
|
||||
mexErrMsgTxt("Error trblklen is zero\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &rv)) {
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &cfg.rv)) {
|
||||
mexErrMsgTxt("Field RV not found in dlsch config\n");
|
||||
return;
|
||||
}
|
||||
|
@ -82,36 +76,42 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation");
|
||||
|
||||
if (!strcmp(mod_str, "QPSK")) {
|
||||
mcs.mod = SRSLTE_MOD_QPSK;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_QPSK;
|
||||
cfg.grant.Qm = 2;
|
||||
} else if (!strcmp(mod_str, "16QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_16QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_16QAM;
|
||||
cfg.grant.Qm = 4;
|
||||
} else if (!strcmp(mod_str, "64QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_64QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_64QAM;
|
||||
cfg.grant.Qm = 6;
|
||||
} else {
|
||||
mexErrMsgTxt("Unknown modulation\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mxFree(mod_str);
|
||||
|
||||
if (srslte_harq_setup_dl(&harq_process, mcs, rv, 0, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
mexErrMsgTxt("Error initiating DL-SCH soft buffer\n");
|
||||
return;
|
||||
}
|
||||
harq_process.nof_bits = mxGetScalar(OUTLEN);
|
||||
|
||||
uint8_t *e_bits = srslte_vec_malloc(harq_process.nof_bits* sizeof(uint8_t));
|
||||
|
||||
cfg.grant.nof_bits = mxGetScalar(OUTLEN);
|
||||
uint8_t *e_bits = srslte_vec_malloc(cfg.grant.nof_bits * sizeof(uint8_t));
|
||||
if (!e_bits) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (srslte_dlsch_encode(&dlsch, &harq_process, trblkin, e_bits)) {
|
||||
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
||||
mexErrMsgTxt("Error computing CB segmentation\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_dlsch_encode(&dlsch, &cfg, &softbuffer, trblkin, e_bits)) {
|
||||
mexErrMsgTxt("Error encoding TB\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nlhs >= 1) {
|
||||
mexutils_write_uint8(e_bits, &plhs[0], harq_process.nof_bits, 1);
|
||||
mexutils_write_uint8(e_bits, &plhs[0], cfg.grant.nof_bits, 1);
|
||||
}
|
||||
|
||||
srslte_sch_free(&dlsch);
|
||||
|
|
|
@ -200,7 +200,7 @@ void base_free() {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
srslte_ra_pdsch_t ra_dl;
|
||||
srslte_ra_dl_dci_t ra_dl;
|
||||
int i;
|
||||
int frame_cnt;
|
||||
int ret;
|
||||
|
@ -264,7 +264,7 @@ int main(int argc, char **argv) {
|
|||
srslte_dci_msg_type_fprint(stdout, type);
|
||||
switch(type.type) {
|
||||
case SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED:
|
||||
bzero(&ra_dl, sizeof(srslte_ra_pdsch_t));
|
||||
bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
if (srslte_dci_msg_unpack_pdsch(&dci_msg, &ra_dl, cell.nof_prb, rnti != SRSLTE_SIRNTI)) {
|
||||
fprintf(stderr, "Can't unpack PDSCH message\n");
|
||||
} else {
|
||||
|
|
|
@ -109,7 +109,7 @@ int main(int argc, char **argv) {
|
|||
srslte_pdcch_t pdcch;
|
||||
srslte_dci_msg_t dci_tx[2], dci_rx[2], dci_tmp;
|
||||
srslte_dci_location_t dci_locations[2];
|
||||
srslte_ra_pdsch_t ra_dl;
|
||||
srslte_ra_dl_dci_t ra_dl;
|
||||
srslte_regs_t regs;
|
||||
int i, j;
|
||||
cf_t *ce[SRSLTE_MAX_PORTS];
|
||||
|
@ -160,7 +160,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
nof_dcis = 2;
|
||||
bzero(&ra_dl, sizeof(srslte_ra_pdsch_t));
|
||||
bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
ra_dl.harq_process = 0;
|
||||
ra_dl.mcs_idx = 5;
|
||||
ra_dl.ndi = 0;
|
||||
|
|
|
@ -57,13 +57,8 @@ uint32_t sf_idx = 0;
|
|||
|
||||
srslte_dci_format_t dci_format = SRSLTE_DCI_FORMAT1A;
|
||||
srslte_filesource_t fsrc;
|
||||
srslte_pdcch_t pdcch;
|
||||
srslte_pdsch_t pdsch;
|
||||
srslte_harq_t harq_process;
|
||||
cf_t *input_buffer, *fft_buffer, *ce[SRSLTE_MAX_PORTS];
|
||||
srslte_regs_t regs;
|
||||
srslte_ofdm_t fft;
|
||||
srslte_chest_dl_t chest;
|
||||
srslte_ue_dl_t ue_dl;
|
||||
cf_t *input_buffer;
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [rovfcenmps] -i input_file\n", prog);
|
||||
|
@ -132,7 +127,6 @@ void parse_args(int argc, char **argv) {
|
|||
}
|
||||
|
||||
int base_init() {
|
||||
int i;
|
||||
|
||||
if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) {
|
||||
fprintf(stderr, "Error opening file %s\n", input_file_name);
|
||||
|
@ -147,98 +141,31 @@ int base_init() {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
fft_buffer = malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
|
||||
if (!fft_buffer) {
|
||||
perror("malloc");
|
||||
if (srslte_ue_dl_init(&ue_dl, cell)) {
|
||||
fprintf(stderr, "Error initializing UE DL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0;i<SRSLTE_MAX_PORTS;i++) {
|
||||
ce[i] = malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
|
||||
if (!ce[i]) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (srslte_chest_dl_init(&chest, cell)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initializing FFT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (srslte_regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (srslte_regs_set_cfi(®s, cfi)) {
|
||||
fprintf(stderr, "Error setting CFI %d\n", cfi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (srslte_pdcch_init(&pdcch, ®s, cell)) {
|
||||
fprintf(stderr, "Error creating PDCCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_pdsch_init(&pdsch, cell)) {
|
||||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
srslte_pdsch_set_rnti(&pdsch, rnti);
|
||||
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
exit(-1);
|
||||
}
|
||||
srslte_ue_dl_set_rnti(&ue_dl, rnti);
|
||||
|
||||
DEBUG("Memory init OK\n",0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void base_free() {
|
||||
int i;
|
||||
|
||||
srslte_filesource_free(&fsrc);
|
||||
|
||||
free(input_buffer);
|
||||
free(fft_buffer);
|
||||
|
||||
srslte_filesource_free(&fsrc);
|
||||
for (i=0;i<SRSLTE_MAX_PORTS;i++) {
|
||||
free(ce[i]);
|
||||
}
|
||||
srslte_chest_dl_free(&chest);
|
||||
srslte_ofdm_rx_free(&fft);
|
||||
|
||||
srslte_pdcch_free(&pdcch);
|
||||
srslte_pdsch_free(&pdsch);
|
||||
srslte_harq_free(&harq_process);
|
||||
srslte_regs_free(®s);
|
||||
srslte_ue_dl_free(&ue_dl);
|
||||
free(input_buffer);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
srslte_ra_pdsch_t ra_dl;
|
||||
int i;
|
||||
int nof_frames;
|
||||
int ret;
|
||||
uint8_t *data;
|
||||
srslte_dci_location_t locations[MAX_CANDIDATES];
|
||||
uint32_t nof_locations = 0;
|
||||
srslte_dci_msg_t dci_msg;
|
||||
|
||||
data = malloc(100000);
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
if (base_init()) {
|
||||
|
@ -246,67 +173,30 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (rnti == SRSLTE_SIRNTI) {
|
||||
INFO("Initializing common search space for SI-RNTI\n",0);
|
||||
nof_locations = srslte_pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi);
|
||||
}
|
||||
|
||||
uint8_t *data = malloc(100000);
|
||||
|
||||
ret = -1;
|
||||
nof_frames = 0;
|
||||
do {
|
||||
srslte_filesource_read(&fsrc, input_buffer, flen);
|
||||
INFO("Reading %d samples sub-frame %d\n", flen, sf_idx);
|
||||
|
||||
srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);
|
||||
|
||||
/* Get channel estimates for each port */
|
||||
srslte_chest_dl_estimate(&chest, fft_buffer, ce, sf_idx);
|
||||
|
||||
if (rnti != SRSLTE_SIRNTI) {
|
||||
INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);
|
||||
nof_locations = srslte_pdcch_ue_locations(&pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, rnti);
|
||||
ret = srslte_ue_dl_decode(&ue_dl, input_buffer, data, sf_idx);
|
||||
if(ret > 0) {
|
||||
printf("PDSCH Decoded OK!\n");
|
||||
} else if (ret == 0) {
|
||||
printf("No DCI grant found\n");
|
||||
} else if (ret < 0) {
|
||||
printf("Error decoding PDSCH\n");
|
||||
}
|
||||
|
||||
uint16_t crc_rem = 0;
|
||||
if (srslte_pdcch_extract_llr(&pdcch, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest), sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (srslte_pdcch_decode_msg(&pdcch, &dci_msg, &locations[i], dci_format, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
if (srslte_dci_msg_to_ra_dl(&dci_msg, rnti, cell, cfi, &ra_dl)) {
|
||||
fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
|
||||
goto goout;
|
||||
}
|
||||
if (ra_dl.mcs.tbs > 0) {
|
||||
if (srslte_harq_setup_dl(&harq_process, ra_dl.mcs, ra_dl.rv_idx, sf_idx, &ra_dl.prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
goto goout;
|
||||
}
|
||||
if (srslte_pdsch_decode(&pdsch, &harq_process, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest), data)) {
|
||||
fprintf(stderr, "Error decoding PDSCH\n");
|
||||
goto goout;
|
||||
} else {
|
||||
printf("PDSCH Decoded OK!\n");
|
||||
}
|
||||
} else {
|
||||
printf("Received DCI with no resource allocation\n");
|
||||
}
|
||||
sf_idx = (sf_idx+1)%10;
|
||||
}
|
||||
|
||||
sf_idx = (sf_idx+1)%10;
|
||||
nof_frames++;
|
||||
} while (nof_frames <= max_frames);
|
||||
} while (nof_frames <= max_frames && ret == 0);
|
||||
|
||||
ret = 0;
|
||||
|
||||
goout:
|
||||
base_free();
|
||||
exit(ret);
|
||||
if (ret > 0) {
|
||||
exit(0);
|
||||
} else {
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,45 +127,49 @@ int main(int argc, char **argv) {
|
|||
uint32_t i, j;
|
||||
uint8_t *data = NULL;
|
||||
cf_t *ce[SRSLTE_MAX_PORTS];
|
||||
uint32_t nof_re;
|
||||
cf_t *slot_symbols[SRSLTE_MAX_PORTS];
|
||||
int ret = -1;
|
||||
struct timeval t[3];
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_dl_alloc_t prb_alloc;
|
||||
srslte_harq_t harq_process;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_softbuffer_tx_t softbuffer_tx;
|
||||
srslte_softbuffer_rx_t softbuffer_rx;
|
||||
uint32_t rv;
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
bzero(&pdsch, sizeof(srslte_pdsch_t));
|
||||
bzero(&harq_process, sizeof(srslte_harq_t));
|
||||
bzero(&pdsch_cfg, sizeof(srslte_pdsch_cfg_t));
|
||||
bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
|
||||
bzero(slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
|
||||
|
||||
nof_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE;
|
||||
pdsch_cfg.grant.nof_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE;
|
||||
|
||||
mcs.mod = modulation;
|
||||
pdsch_cfg.grant.mcs.mod = modulation;
|
||||
|
||||
prb_alloc.slot[0].nof_prb = cell.nof_prb;
|
||||
for (i=0;i<prb_alloc.slot[0].nof_prb;i++) {
|
||||
prb_alloc.slot[0].prb_idx[i] = true;
|
||||
pdsch_cfg.grant.nof_prb = cell.nof_prb;
|
||||
for (i=0;i<pdsch_cfg.grant.nof_prb;i++) {
|
||||
pdsch_cfg.grant.prb_idx[0][i] = true;
|
||||
}
|
||||
memcpy(&prb_alloc.slot[1], &prb_alloc.slot[0], sizeof(srslte_ra_prb_slot_t));
|
||||
memcpy(&pdsch_cfg.grant.prb_idx[1], &pdsch_cfg.grant.prb_idx[0], SRSLTE_MAX_PRB * sizeof(bool));
|
||||
|
||||
srslte_dl_dci_to_grant_nof_re(&pdsch_cfg.grant, cell, pdsch_cfg.sf_idx, cell.nof_prb<10?(cfi+1):cfi);
|
||||
// Fill rest of grant structure
|
||||
pdsch_cfg.grant.lstart = cell.nof_prb<10?(cfi+1):cfi;
|
||||
pdsch_cfg.grant.nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-pdsch_cfg.grant.lstart;
|
||||
pdsch_cfg.grant.Qm = srslte_mod_bits_x_symbol(pdsch_cfg.grant.mcs.mod);
|
||||
pdsch_cfg.grant.nof_bits = pdsch_cfg.grant.nof_re * pdsch_cfg.grant.Qm;
|
||||
|
||||
srslte_ra_dl_alloc_re(&prb_alloc, cell.nof_prb, cell.nof_ports, cell.nof_prb<10?(cfi+1):cfi, cell.cp);
|
||||
|
||||
/* init memory */
|
||||
for (i=0;i<cell.nof_ports;i++) {
|
||||
ce[i] = malloc(sizeof(cf_t) * nof_re);
|
||||
ce[i] = malloc(sizeof(cf_t) * SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp));
|
||||
if (!ce[i]) {
|
||||
perror("malloc");
|
||||
goto quit;
|
||||
}
|
||||
for (j=0;j<nof_re;j++) {
|
||||
for (j=0;j<pdsch_cfg.grant.nof_re;j++) {
|
||||
ce[i][j] = 1;
|
||||
}
|
||||
slot_symbols[i] = calloc(sizeof(cf_t) , nof_re);
|
||||
slot_symbols[i] = calloc(sizeof(cf_t) , SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp));
|
||||
if (!slot_symbols[i]) {
|
||||
perror("malloc");
|
||||
goto quit;
|
||||
|
@ -185,33 +189,35 @@ int main(int argc, char **argv) {
|
|||
|
||||
srslte_pdsch_set_rnti(&pdsch, 1234);
|
||||
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
if (srslte_softbuffer_tx_init(&softbuffer_tx, cell)) {
|
||||
fprintf(stderr, "Error initiating TX soft buffer\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if (srslte_softbuffer_rx_init(&softbuffer_rx, cell)) {
|
||||
fprintf(stderr, "Error initiating RX soft buffer\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
for (mcs.tbs = tbs;mcs.tbs<=tbs+nof_tbs;mcs.tbs++) {
|
||||
for (pdsch_cfg.grant.mcs.tbs = tbs;pdsch_cfg.grant.mcs.tbs<=tbs+nof_tbs;pdsch_cfg.grant.mcs.tbs++) {
|
||||
if (SRSLTE_VERBOSE_ISNONE()) {
|
||||
printf("Decoding TBS: %d\r",mcs.tbs);
|
||||
printf("Decoding TBS: %d\r",pdsch_cfg.grant.mcs.tbs);
|
||||
}
|
||||
for (i=0;i<mcs.tbs;i++) {
|
||||
for (i=0;i<pdsch_cfg.grant.mcs.tbs;i++) {
|
||||
data[i] = rand()%2;
|
||||
}
|
||||
|
||||
for (rv=0;rv<=rv_idx;rv++) {
|
||||
if (srslte_harq_setup_dl(&harq_process, mcs, rv, subframe, &prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
goto quit;
|
||||
}
|
||||
srslte_cbsegm(&pdsch_cfg.cb_segm, pdsch_cfg.grant.mcs.tbs);
|
||||
|
||||
if (srslte_pdsch_encode(&pdsch, &harq_process, data, slot_symbols)) {
|
||||
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* combine outputs */
|
||||
for (i=0;i<cell.nof_ports;i++) {
|
||||
for (j=0;j<nof_re;j++) {
|
||||
for (j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
|
||||
if (i > 0) {
|
||||
slot_symbols[0][j] += slot_symbols[i][j];
|
||||
}
|
||||
|
@ -220,16 +226,16 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
gettimeofday(&t[1], NULL);
|
||||
int r = srslte_pdsch_decode(&pdsch, &harq_process, slot_symbols[0], ce, 0, data);
|
||||
int r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data);
|
||||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
if (r) {
|
||||
printf("Error decoding TBS: %d\n", mcs.tbs);
|
||||
printf("Error decoding TBS: %d\n", pdsch_cfg.grant.mcs.tbs);
|
||||
ret = -1;
|
||||
goto quit;
|
||||
} else {
|
||||
if (nof_tbs == 0) {
|
||||
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) mcs.tbs/t[0].tv_usec);
|
||||
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) pdsch_cfg.grant.mcs.tbs/t[0].tv_usec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +243,8 @@ int main(int argc, char **argv) {
|
|||
ret = 0;
|
||||
quit:
|
||||
srslte_pdsch_free(&pdsch);
|
||||
srslte_harq_free(&harq_process);
|
||||
srslte_softbuffer_tx_free(&softbuffer_tx);
|
||||
srslte_softbuffer_rx_free(&softbuffer_rx);
|
||||
|
||||
for (i=0;i<cell.nof_ports;i++) {
|
||||
if (ce[i]) {
|
||||
|
|
|
@ -54,20 +54,20 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
srslte_pdsch_t pdsch;
|
||||
srslte_chest_dl_t chest;
|
||||
srslte_ofdm_t fft;
|
||||
uint32_t cfi, sf_idx;
|
||||
cf_t *input_fft, *input_signal;
|
||||
int nof_re;
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_dl_alloc_t dl_alloc;
|
||||
srslte_harq_t harq_process;
|
||||
uint32_t rv;
|
||||
srslte_pdsch_cfg_t cfg;
|
||||
srslte_softbuffer_rx_t softbuffer;
|
||||
uint32_t rnti32;
|
||||
uint32_t cfi;
|
||||
|
||||
if (nrhs < NOF_INPUTS) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bzero(&cfg, sizeof(srslte_pdsch_cfg_t));
|
||||
|
||||
if (mexutils_read_cell(ENBCFG, &cell)) {
|
||||
help();
|
||||
return;
|
||||
|
@ -82,7 +82,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
help();
|
||||
return;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &sf_idx)) {
|
||||
if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &cfg.sf_idx)) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
@ -93,8 +93,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
srslte_pdsch_set_rnti(&pdsch, (uint16_t) (rnti32 & 0xffff));
|
||||
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
mexErrMsgTxt("Error initiating HARQ process\n");
|
||||
if (srslte_softbuffer_rx_init(&softbuffer, cell)) {
|
||||
mexErrMsgTxt("Error initiating soft buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -108,16 +108,19 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
nof_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE;
|
||||
|
||||
mcs.tbs = mxGetScalar(TBS);
|
||||
if (mcs.tbs == 0) {
|
||||
cfg.grant.mcs.tbs = mxGetScalar(TBS);
|
||||
if (cfg.grant.mcs.tbs == 0) {
|
||||
mexErrMsgTxt("Error trblklen is zero\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
||||
mexErrMsgTxt("Error computing CB segmentation\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mexutils_read_uint32_struct(PDSCHCFG, "RV", &rv)) {
|
||||
if (mexutils_read_uint32_struct(PDSCHCFG, "RV", &cfg.rv)) {
|
||||
mexErrMsgTxt("Field RV not found in pdsch config\n");
|
||||
return;
|
||||
}
|
||||
|
@ -125,11 +128,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
char *mod_str = mexutils_get_char_struct(PDSCHCFG, "Modulation");
|
||||
|
||||
if (!strcmp(mod_str, "QPSK")) {
|
||||
mcs.mod = SRSLTE_MOD_QPSK;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else if (!strcmp(mod_str, "16QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_16QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_16QAM;
|
||||
} else if (!strcmp(mod_str, "64QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_64QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_64QAM;
|
||||
} else {
|
||||
mexErrMsgTxt("Unknown modulation\n");
|
||||
return;
|
||||
|
@ -146,27 +149,28 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
|
||||
// Only localized PRB supported
|
||||
dl_alloc.slot[0].nof_prb = mexutils_read_f(p, &prbset);
|
||||
cfg.grant.nof_prb = mexutils_read_f(p, &prbset);
|
||||
|
||||
for (i=0;i<cell.nof_prb;i++) {
|
||||
dl_alloc.slot[0].prb_idx[i] = false;
|
||||
for (int j=0;j<dl_alloc.slot[0].nof_prb && !dl_alloc.slot[0].prb_idx[i];j++) {
|
||||
cfg.grant.prb_idx[0][i] = false;
|
||||
for (int j=0;j<cfg.grant.nof_prb && !cfg.grant.prb_idx[0][i];j++) {
|
||||
if ((int) prbset[j] == i) {
|
||||
dl_alloc.slot[0].prb_idx[i] = true;
|
||||
cfg.grant.prb_idx[0][i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(&dl_alloc.slot[1], &dl_alloc.slot[0], sizeof(srslte_ra_prb_slot_t));
|
||||
memcpy(&cfg.grant.prb_idx[1], &cfg.grant.prb_idx[0], SRSLTE_MAX_PRB*sizeof(bool));
|
||||
|
||||
free(prbset);
|
||||
|
||||
srslte_ra_dl_alloc_re(&dl_alloc, cell.nof_prb, cell.nof_ports, cell.nof_prb<10?(cfi+1):cfi, cell.cp);
|
||||
srslte_dl_dci_to_grant_nof_re(&cfg.grant, cell, cfg.sf_idx, cell.nof_prb<10?(cfi+1):cfi);
|
||||
|
||||
if (srslte_harq_setup_dl(&harq_process, mcs, rv, sf_idx, &dl_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill rest of grant structure
|
||||
cfg.grant.lstart = cell.nof_prb<10?(cfi+1):cfi;
|
||||
cfg.grant.nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-cfg.grant.lstart;
|
||||
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
|
||||
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
|
||||
|
||||
/** Allocate input buffers */
|
||||
if (mexutils_read_cf(INPUT, &input_signal) < 0) {
|
||||
mexErrMsgTxt("Error reading input signal\n");
|
||||
|
@ -174,7 +178,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
|
||||
|
||||
// Set Channel estimates to 1.0 (ignore fading)
|
||||
cf_t *ce[SRSLTE_MAX_PORTS];
|
||||
for (i=0;i<cell.nof_ports;i++) {
|
||||
ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
|
||||
|
@ -195,7 +198,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
if (cearray_ptr)
|
||||
free(cearray_ptr);
|
||||
} else {
|
||||
srslte_chest_dl_estimate(&chest, input_fft, ce, sf_idx);
|
||||
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
|
||||
}
|
||||
float noise_power;
|
||||
if (nrhs > NOF_INPUTS + 1) {
|
||||
|
@ -204,28 +207,28 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
noise_power = srslte_chest_dl_get_noise_estimate(&chest);
|
||||
}
|
||||
|
||||
uint8_t *data = malloc(sizeof(uint8_t) * mcs.tbs);
|
||||
uint8_t *data = malloc(sizeof(uint8_t) * cfg.grant.mcs.tbs);
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
int r = srslte_pdsch_decode(&pdsch, &harq_process, input_fft, ce, noise_power, data);
|
||||
int r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data);
|
||||
|
||||
|
||||
if (nlhs >= 1) {
|
||||
plhs[0] = mxCreateLogicalScalar(r == 0);
|
||||
}
|
||||
if (nlhs >= 2) {
|
||||
mexutils_write_uint8(data, &plhs[1], mcs.tbs, 1);
|
||||
mexutils_write_uint8(data, &plhs[1], cfg.grant.mcs.tbs, 1);
|
||||
}
|
||||
if (nlhs >= 3) {
|
||||
mexutils_write_cf(pdsch.symbols[0], &plhs[2], harq_process.dl_alloc.re_sf[sf_idx], 1);
|
||||
mexutils_write_cf(pdsch.symbols[0], &plhs[2], cfg.grant.nof_re, 1);
|
||||
}
|
||||
if (nlhs >= 4) {
|
||||
mexutils_write_cf(pdsch.d, &plhs[3], harq_process.dl_alloc.re_sf[sf_idx], 1);
|
||||
mexutils_write_cf(pdsch.d, &plhs[3], cfg.grant.nof_re, 1);
|
||||
}
|
||||
if (nlhs >= 5) {
|
||||
mexutils_write_f(pdsch.e, &plhs[4], harq_process.dl_alloc.re_sf[sf_idx] * srslte_mod_bits_x_symbol(mcs.mod), 1);
|
||||
mexutils_write_f(pdsch.e, &plhs[4], cfg.grant.nof_bits, 1);
|
||||
}
|
||||
|
||||
srslte_chest_dl_free(&chest);
|
||||
|
|
|
@ -261,7 +261,7 @@ int main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
INFO("%d/%d, ack_rx: %d, ns: %d, distance: %d\n",
|
||||
INFO("%d/%d, ack_rx: %d, ns: %d, distance: %f\n",
|
||||
ngroup, nseq, ack_rx, numsubframe, distance);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ int main(int argc, char **argv) {
|
|||
printf("Error decoding ACK\n");
|
||||
exit(-1);
|
||||
}
|
||||
INFO("%d/%d, ack_tx: %d, ack_rx: %d, ns: %d, distance: %d\n",
|
||||
INFO("%d/%d, ack_tx: %d, ack_rx: %d, ns: %d, distance: %f\n",
|
||||
ngroup, nseq, ack[ngroup][nseq], ack_rx, nsf, distance);
|
||||
if (ack[ngroup][nseq] != ack_rx) {
|
||||
printf("Invalid received ACK: %d!=%d\n", ack[ngroup][nseq], ack_rx);
|
||||
|
|
|
@ -80,20 +80,19 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
|
||||
|
||||
|
||||
|
||||
uint32_t sf_idx=0;
|
||||
if (mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx)) {
|
||||
srslte_pusch_cfg_t cfg;
|
||||
bzero(&cfg, sizeof(srslte_pusch_cfg_t));
|
||||
if (mexutils_read_uint32_struct(UECFG, "NSubframe", &cfg.sf_idx)) {
|
||||
mexErrMsgTxt("Field NSubframe not found in UE config\n");
|
||||
return;
|
||||
}
|
||||
srslte_ra_mcs_t mcs;
|
||||
char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation");
|
||||
if (!strcmp(mod_str, "QPSK")) {
|
||||
mcs.mod = SRSLTE_MOD_QPSK;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else if (!strcmp(mod_str, "16QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_16QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_16QAM;
|
||||
} else if (!strcmp(mod_str, "64QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_64QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_64QAM;
|
||||
} else {
|
||||
mexErrMsgTxt("Unknown modulation\n");
|
||||
return;
|
||||
|
@ -108,27 +107,32 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
mexErrMsgTxt("Error field PRBSet not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
bzero(&prb_alloc, sizeof(srslte_ra_ul_alloc_t));
|
||||
prb_alloc.L_prb = mexutils_read_f(p, &prbset);
|
||||
prb_alloc.n_prb[0] = prbset[0];
|
||||
prb_alloc.n_prb[1] = prbset[0];
|
||||
cfg.grant.L_prb = mexutils_read_f(p, &prbset);
|
||||
cfg.grant.n_prb[0] = prbset[0];
|
||||
cfg.grant.n_prb[1] = prbset[0];
|
||||
cfg.grant.lstart = 0;
|
||||
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1);
|
||||
cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE;
|
||||
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be?
|
||||
cfg.grant.nof_re = cfg.grant.nof_symb*cfg.grant.M_sc;
|
||||
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
|
||||
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
|
||||
|
||||
free(prbset);
|
||||
|
||||
mexPrintf("L_prb: %d, n_prb: %d\n", prb_alloc.L_prb, prb_alloc.n_prb[2*sf_idx]);
|
||||
mexPrintf("L_prb: %d, n_prb: %d\n", cfg.grant.L_prb, cfg.grant.n_prb[0]);
|
||||
|
||||
uint8_t *trblkin = NULL;
|
||||
mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
|
||||
srslte_harq_t harq_process;
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
mexErrMsgTxt("Error initiating HARQ process\n");
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
mexErrMsgTxt("Error initiating soft buffer\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, 0, sf_idx, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
||||
mexErrMsgTxt("Error computing CB segmentation\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp);
|
||||
|
@ -156,36 +160,39 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
free(tmp);
|
||||
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetCQI", &uci_data.I_offset_cqi)) {
|
||||
float beta;
|
||||
if (mexutils_read_float_struct(PUSCHCFG, "BetaCQI", &beta)) {
|
||||
uci_data.I_offset_cqi = 7;
|
||||
} else {
|
||||
uci_data.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta);
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetRI", &uci_data.I_offset_ri)) {
|
||||
if (mexutils_read_float_struct(PUSCHCFG, "BetaRI", &beta)) {
|
||||
uci_data.I_offset_ri = 2;
|
||||
} else {
|
||||
uci_data.I_offset_ri = srslte_sch_find_Ioffset_ri(beta);
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetACK", &uci_data.I_offset_ack)) {
|
||||
if (mexutils_read_float_struct(PUSCHCFG, "BetaACK", &beta)) {
|
||||
uci_data.I_offset_ack = 0;
|
||||
} else {
|
||||
uci_data.I_offset_ack = srslte_sch_find_Ioffset_ack(beta);
|
||||
}
|
||||
mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d (%d), RI_len: %d (%d)\n", mcs.tbs,
|
||||
mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d (%d), RI_len: %d (%d)\n", cfg.grant.mcs.tbs,
|
||||
uci_data.uci_cqi_len, uci_data.uci_ack_len, uci_data.uci_ack, uci_data.uci_ri_len, uci_data.uci_ri);
|
||||
|
||||
|
||||
mexPrintf("NofRE: %d, NofBits: %d, TBS: %d\n", harq_process.nof_re, harq_process.nof_bits, harq_process.mcs.tbs);
|
||||
int r = srslte_pusch_uci_encode(&pusch, &harq_process, trblkin, uci_data, sf_symbols);
|
||||
mexPrintf("I_cqi: %d, I_ri: %d, I_ack=%d\n", uci_data.I_offset_cqi, uci_data.I_offset_ri, uci_data.I_offset_ack);
|
||||
|
||||
mexPrintf("NofRE: %d, NofBits: %d, TBS: %d\n", cfg.grant.nof_re, cfg.grant.nof_bits, cfg.grant.mcs.tbs);
|
||||
int r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols);
|
||||
if (r < 0) {
|
||||
mexErrMsgTxt("Error encoding PUSCH\n");
|
||||
return;
|
||||
}
|
||||
uint32_t rv=0;
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &rv)) {
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &cfg.rv)) {
|
||||
mexErrMsgTxt("Field RV not found in pdsch config\n");
|
||||
return;
|
||||
}
|
||||
if (rv > 0) {
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, rv, sf_idx, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
r = srslte_pusch_uci_encode(&pusch, &harq_process, trblkin, uci_data, sf_symbols);
|
||||
if (cfg.rv > 0) {
|
||||
r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols);
|
||||
if (r < 0) {
|
||||
mexErrMsgTxt("Error encoding PUSCH\n");
|
||||
return;
|
||||
|
@ -210,7 +217,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
mexutils_write_cf(sf_symbols, &plhs[1], nof_re, 1);
|
||||
}
|
||||
if (nlhs >= 3) {
|
||||
mexutils_write_cf(pusch.z, &plhs[2], harq_process.nof_re, 1);
|
||||
mexutils_write_cf(pusch.z, &plhs[2], cfg.grant.nof_re, 1);
|
||||
}
|
||||
srslte_pusch_free(&pusch);
|
||||
free(trblkin);
|
||||
|
|
|
@ -135,29 +135,49 @@ int main(int argc, char **argv) {
|
|||
cf_t *sf_symbols = NULL;
|
||||
int ret = -1;
|
||||
struct timeval t[3];
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
srslte_harq_t harq_process;
|
||||
srslte_pusch_cfg_t cfg;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
mcs.tbs = tbs;
|
||||
mcs.mod = modulation;
|
||||
|
||||
bzero(&prb_alloc, sizeof(srslte_ra_ul_alloc_t));
|
||||
|
||||
bzero(&cfg, sizeof(srslte_pusch_cfg_t));
|
||||
|
||||
srslte_ra_ul_dci_t dci;
|
||||
dci.freq_hop_fl = freq_hop;
|
||||
if (riv < 0) {
|
||||
dci.type2_alloc.L_crb = L_prb;
|
||||
dci.type2_alloc.RB_start = n_prb;
|
||||
} else {
|
||||
srslte_ra_type2_from_riv((uint32_t) riv, &dci.type2_alloc.L_crb, &dci.type2_alloc.RB_start, cell.nof_prb, cell.nof_prb);
|
||||
}
|
||||
cfg.grant.mcs.tbs = tbs;
|
||||
cfg.grant.mcs.mod = modulation;
|
||||
|
||||
// Compute PRB allocation
|
||||
if (!srslte_ul_dci_to_grant_prb_allocation(&dci, &cfg.grant, 0, cell.nof_prb)) {
|
||||
cfg.grant.lstart = 0;
|
||||
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1);
|
||||
cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE;
|
||||
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be?
|
||||
cfg.grant.nof_re = cfg.grant.nof_symb*cfg.grant.M_sc;
|
||||
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
|
||||
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
|
||||
}
|
||||
|
||||
if (srslte_pusch_init(&pusch, cell)) {
|
||||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
goto quit;
|
||||
}
|
||||
srslte_pusch_set_rnti(&pusch, 1234);
|
||||
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
printf("Encoding rv_idx=%d\n",rv_idx);
|
||||
cfg.rv = 0;
|
||||
cfg.sf_idx = subframe;
|
||||
|
||||
uint8_t tmp[20];
|
||||
for (uint32_t i=0;i<20;i++) {
|
||||
|
@ -167,28 +187,18 @@ int main(int argc, char **argv) {
|
|||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
uci_data.I_offset_cqi = 7;
|
||||
uci_data.I_offset_ri = 2;
|
||||
uci_data.I_offset_ack = 0;
|
||||
uci_data.I_offset_ack = 4;
|
||||
|
||||
uci_data.uci_cqi_len = 0;
|
||||
uci_data.uci_cqi_len = 8;
|
||||
uci_data.uci_ri_len = 0;
|
||||
uci_data.uci_ack_len = 0;
|
||||
uci_data.uci_ack_len = 1;
|
||||
|
||||
uci_data.uci_cqi = tmp;
|
||||
uci_data.uci_ri = 1;
|
||||
uci_data.uci_ack = 1;
|
||||
uci_data.uci_ri = 0;
|
||||
uci_data.uci_ack = 0;
|
||||
|
||||
srslte_ra_pusch_t dci;
|
||||
dci.freq_hop_fl = freq_hop;
|
||||
if (riv < 0) {
|
||||
dci.type2_alloc.L_crb = L_prb;
|
||||
dci.type2_alloc.RB_start = n_prb;
|
||||
} else {
|
||||
srslte_ra_type2_from_riv((uint32_t) riv, &dci.type2_alloc.L_crb, &dci.type2_alloc.RB_start, cell.nof_prb, cell.nof_prb);
|
||||
}
|
||||
srslte_ra_ul_alloc(&prb_alloc, &dci, 0, cell.nof_prb);
|
||||
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, 0, subframe, &prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
||||
fprintf(stderr, "Error configuring CB segmentation\n");
|
||||
goto quit;
|
||||
}
|
||||
srslte_pusch_hopping_cfg_t ul_hopping;
|
||||
|
@ -206,34 +216,29 @@ int main(int argc, char **argv) {
|
|||
goto quit;
|
||||
}
|
||||
|
||||
data = malloc(sizeof(uint8_t) * mcs.tbs);
|
||||
data = malloc(sizeof(uint8_t) * cfg.grant.mcs.tbs);
|
||||
if (!data) {
|
||||
perror("malloc");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
for (uint32_t i=0;i<mcs.tbs;i++) {
|
||||
for (uint32_t i=0;i<cfg.grant.mcs.tbs;i++) {
|
||||
data[i] = 1;
|
||||
}
|
||||
|
||||
if (srslte_pusch_uci_encode(&pusch, &harq_process, data, uci_data, sf_symbols)) {
|
||||
if (srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, data, uci_data, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (rv_idx > 0) {
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, rv_idx, subframe, &prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if (srslte_pusch_uci_encode(&pusch, &harq_process, data, uci_data, sf_symbols)) {
|
||||
cfg.rv = rv_idx;
|
||||
if (srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, data, uci_data, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
srslte_ofdm_t fft;
|
||||
|
@ -251,13 +256,13 @@ int main(int argc, char **argv) {
|
|||
ret = -1;
|
||||
goto quit;
|
||||
} else {
|
||||
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) mcs.tbs/t[0].tv_usec);
|
||||
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) cfg.grant.mcs.tbs/t[0].tv_usec);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
quit:
|
||||
srslte_pusch_free(&pusch);
|
||||
srslte_harq_free(&harq_process);
|
||||
srslte_softbuffer_tx_free(&softbuffer);
|
||||
|
||||
if (sf_symbols) {
|
||||
free(sf_symbols);
|
||||
|
|
|
@ -48,17 +48,18 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
{
|
||||
srslte_sch_t ulsch;
|
||||
uint8_t *trblkin;
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
srslte_harq_t harq_process;
|
||||
uint32_t rv;
|
||||
srslte_pusch_cfg_t cfg;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
|
||||
uint32_t rv;
|
||||
|
||||
if (nrhs < NOF_INPUTS) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
bzero(&cfg, sizeof(srslte_pusch_cfg_t));
|
||||
|
||||
if (srslte_sch_init(&ulsch)) {
|
||||
mexErrMsgTxt("Error initiating ULSCH\n");
|
||||
return;
|
||||
|
@ -67,12 +68,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
cell.nof_prb = 100;
|
||||
cell.id=1;
|
||||
cell.cp=SRSLTE_CP_NORM;
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
mexErrMsgTxt("Error initiating HARQ\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
|
||||
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi);
|
||||
uint8_t *tmp;
|
||||
|
@ -87,7 +89,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
free(tmp);
|
||||
|
||||
mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d, RI_len: %d\n", mcs.tbs,
|
||||
mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d, RI_len: %d\n", cfg.grant.mcs.tbs,
|
||||
uci_data.uci_cqi_len, uci_data.uci_ack_len, uci_data.uci_ri_len);
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &rv)) {
|
||||
|
@ -95,24 +97,31 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
return;
|
||||
}
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetCQI", &uci_data.I_offset_cqi)) {
|
||||
float beta;
|
||||
if (mexutils_read_float_struct(PUSCHCFG, "BetaCQI", &beta)) {
|
||||
uci_data.I_offset_cqi = 7;
|
||||
} else {
|
||||
uci_data.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta);
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetRI", &uci_data.I_offset_ri)) {
|
||||
if (mexutils_read_float_struct(PUSCHCFG, "BetaRI", &beta)) {
|
||||
uci_data.I_offset_ri = 2;
|
||||
} else {
|
||||
uci_data.I_offset_ri = srslte_sch_find_Ioffset_ri(beta);
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetACK", &uci_data.I_offset_ack)) {
|
||||
if (mexutils_read_float_struct(PUSCHCFG, "BetaACK", &beta)) {
|
||||
uci_data.I_offset_ack = 0;
|
||||
} else {
|
||||
uci_data.I_offset_ack = srslte_sch_find_Ioffset_ack(beta);
|
||||
}
|
||||
|
||||
char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation");
|
||||
|
||||
if (!strcmp(mod_str, "QPSK")) {
|
||||
mcs.mod = SRSLTE_MOD_QPSK;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else if (!strcmp(mod_str, "16QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_16QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_16QAM;
|
||||
} else if (!strcmp(mod_str, "64QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_64QAM;
|
||||
cfg.grant.mcs.mod = SRSLTE_MOD_64QAM;
|
||||
} else {
|
||||
mexErrMsgTxt("Unknown modulation\n");
|
||||
return;
|
||||
|
@ -128,49 +137,56 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
return;
|
||||
}
|
||||
|
||||
prb_alloc.L_prb = mexutils_read_f(p, &prbset);
|
||||
prb_alloc.n_prb[0] = prbset[0];
|
||||
prb_alloc.n_prb[1] = prbset[0];
|
||||
cfg.grant.L_prb = mexutils_read_f(p, &prbset);
|
||||
cfg.grant.n_prb[0] = prbset[0];
|
||||
cfg.grant.n_prb[1] = prbset[0];
|
||||
free(prbset);
|
||||
|
||||
mexPrintf("Q_m: %d, NPRB: %d, RV: %d\n", srslte_mod_bits_x_symbol(mcs.mod), prb_alloc.L_prb, rv);
|
||||
cfg.grant.L_prb = mexutils_read_f(p, &prbset);
|
||||
cfg.grant.n_prb[0] = prbset[0];
|
||||
cfg.grant.n_prb[1] = prbset[0];
|
||||
cfg.grant.lstart = 0;
|
||||
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1);
|
||||
cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE;
|
||||
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be?
|
||||
cfg.grant.nof_re = cfg.grant.nof_symb*cfg.grant.M_sc;
|
||||
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
|
||||
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
|
||||
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, 0, 0, &prb_alloc)) {
|
||||
mexPrintf("Q_m: %d, NPRB: %d, RV: %d\n", srslte_mod_bits_x_symbol(cfg.grant.mcs.mod), cfg.grant.L_prb, cfg.rv);
|
||||
|
||||
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *q_bits = srslte_vec_malloc(harq_process.nof_bits * sizeof(uint8_t));
|
||||
uint8_t *q_bits = srslte_vec_malloc(cfg.grant.nof_bits * sizeof(uint8_t));
|
||||
if (!q_bits) {
|
||||
return;
|
||||
}
|
||||
uint8_t *g_bits = srslte_vec_malloc(harq_process.nof_bits * sizeof(uint8_t));
|
||||
uint8_t *g_bits = srslte_vec_malloc(cfg.grant.nof_bits * sizeof(uint8_t));
|
||||
if (!g_bits) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (srslte_ulsch_uci_encode(&ulsch, &harq_process, trblkin, uci_data, g_bits, q_bits))
|
||||
if (srslte_ulsch_uci_encode(&ulsch, &cfg, &softbuffer, trblkin, uci_data, g_bits, q_bits))
|
||||
{
|
||||
mexErrMsgTxt("Error encoding TB\n");
|
||||
return;
|
||||
}
|
||||
if (rv > 0) {
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, rv, 0, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_ulsch_uci_encode(&ulsch, &harq_process, trblkin, uci_data, g_bits, q_bits)) {
|
||||
cfg.rv = rv;
|
||||
if (srslte_ulsch_uci_encode(&ulsch, &cfg, &softbuffer, trblkin, uci_data, g_bits, q_bits)) {
|
||||
mexErrMsgTxt("Error encoding TB\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nlhs >= 1) {
|
||||
mexutils_write_uint8(q_bits, &plhs[0], harq_process.nof_bits, 1);
|
||||
mexutils_write_uint8(q_bits, &plhs[0], cfg.grant.nof_bits, 1);
|
||||
}
|
||||
|
||||
srslte_sch_free(&ulsch);
|
||||
srslte_harq_free(&harq_process);
|
||||
srslte_softbuffer_tx_free(&softbuffer);
|
||||
|
||||
free(trblkin);
|
||||
free(g_bits);
|
||||
|
|
|
@ -286,7 +286,7 @@ int main(int argc, char **argv) {
|
|||
frame_cnt++;
|
||||
|
||||
printf("[%5d]: Pos: %5d, PSR: %4.1f (~%4.1f) Pdet: %4.2f, "
|
||||
"FA: %4.2f, CFO: %+4.1f KHz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f\%\r",
|
||||
"FA: %4.2f, CFO: %+4.1f KHz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f%%\r",
|
||||
frame_cnt,
|
||||
peak_idx,
|
||||
peak_value, mean_peak,
|
||||
|
|
|
@ -296,7 +296,7 @@ int main(int argc, char **argv) {
|
|||
frame_cnt++;
|
||||
|
||||
printf("[%5d]: Pos: %5d, PSR: %4.1f (~%4.1f) Pdet: %4.2f, "
|
||||
"FA: %4.2f, CFO: %+4.1f KHz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f\%\r",
|
||||
"FA: %4.2f, CFO: %+4.1f KHz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f%%\r",
|
||||
frame_cnt,
|
||||
peak_idx,
|
||||
peak_value, mean_peak,
|
||||
|
|
|
@ -84,11 +84,9 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
|
|||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
for (uint32_t i=0;i<SRSLTE_UE_UL_NOF_HARQ_PROCESSES; i++) {
|
||||
if (srslte_harq_init(&q->harq_process[i], q->cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
if (srslte_softbuffer_rx_init(&q->softbuffer, q->cell)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
q->sf_symbols = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t));
|
||||
if (!q->sf_symbols) {
|
||||
|
@ -125,9 +123,7 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) {
|
|||
srslte_phich_free(&q->phich);
|
||||
srslte_pdcch_free(&q->pdcch);
|
||||
srslte_pdsch_free(&q->pdsch);
|
||||
for (uint32_t i=0;i<SRSLTE_UE_UL_NOF_HARQ_PROCESSES; i++) {
|
||||
srslte_harq_free(&q->harq_process[i]);
|
||||
}
|
||||
srslte_softbuffer_rx_free(&q->softbuffer);
|
||||
if (q->sf_symbols) {
|
||||
free(q->sf_symbols);
|
||||
}
|
||||
|
@ -136,9 +132,7 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) {
|
|||
free(q->ce[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bzero(q, sizeof(srslte_ue_dl_t));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +146,8 @@ void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q, uint16_t rnti) {
|
|||
}
|
||||
|
||||
void srslte_ue_dl_reset(srslte_ue_dl_t *q) {
|
||||
srslte_harq_reset(&q->harq_process[0]);
|
||||
srslte_softbuffer_rx_reset(&q->softbuffer);
|
||||
bzero(&q->pdsch_cfg, sizeof(srslte_pdsch_cfg_t));
|
||||
}
|
||||
|
||||
srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1,SRSLTE_DCI_FORMAT1A}; // SRSLTE_DCI_FORMAT1B should go here also
|
||||
|
@ -212,22 +207,26 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_
|
|||
int ret = SRSLTE_ERROR;
|
||||
|
||||
q->nof_detected++;
|
||||
if (srslte_dci_msg_to_ra_dl(dci_msg, rnti, q->cell, cfi, &q->ra_dl)) {
|
||||
|
||||
srslte_ra_dl_dci_t dl_dci;
|
||||
|
||||
if (srslte_dci_msg_to_dl_grant(dci_msg, rnti, q->cell, cfi, sf_idx, &dl_dci, &q->pdsch_cfg.grant)) {
|
||||
fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (rnti != SRSLTE_SIRNTI) {
|
||||
rvidx = q->ra_dl.rv_idx;
|
||||
if (srslte_cbsegm(&q->pdsch_cfg.cb_segm, q->pdsch_cfg.grant.mcs.tbs)) {
|
||||
fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", q->pdsch_cfg.grant.mcs.tbs);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
if (srslte_harq_setup_dl(&q->harq_process[0], q->ra_dl.mcs, rvidx, sf_idx, &q->ra_dl.prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
return SRSLTE_ERROR;
|
||||
q->pdsch_cfg.sf_idx = sf_idx;
|
||||
if (rnti == SRSLTE_SIRNTI) {
|
||||
q->pdsch_cfg.rv = rvidx;
|
||||
} else {
|
||||
q->pdsch_cfg.rv = dl_dci.rv_idx;
|
||||
}
|
||||
if (q->harq_process[0].mcs.mod > 0 && q->harq_process[0].mcs.tbs >= 0) {
|
||||
ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->harq_process[0], q->sf_symbols,
|
||||
q->ce, 0,
|
||||
rnti, data);
|
||||
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, 0, rnti, data);
|
||||
|
||||
if (ret == SRSLTE_ERROR) {
|
||||
q->pkt_errors++;
|
||||
|
@ -236,7 +235,7 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_
|
|||
} else if (ret == SRSLTE_SUCCESS) {
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
INFO("Decoded Message: ", 0);
|
||||
srslte_vec_fprint_hex(stdout, data, q->ra_dl.mcs.tbs);
|
||||
srslte_vec_fprint_hex(stdout, data, q->pdsch_cfg.grant.mcs.tbs);
|
||||
}
|
||||
}
|
||||
q->pkts_total++;
|
||||
|
@ -317,7 +316,7 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u
|
|||
}
|
||||
|
||||
if (found_dci == 1 && ret == SRSLTE_SUCCESS) {
|
||||
return q->ra_dl.mcs.tbs;
|
||||
return q->pdsch_cfg.grant.mcs.tbs;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
int srslte_ue_ul_init(srslte_ue_ul_t *q,
|
||||
srslte_cell_t cell)
|
||||
srslte_cell_t cell)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
|
@ -74,11 +74,9 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q,
|
|||
fprintf(stderr, "Error creating PUSCH object\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
for (uint32_t i=0;i<SRSLTE_UE_UL_NOF_HARQ_PROCESSES; i++) {
|
||||
if (srslte_harq_init(&q->harq_process[i], q->cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
if (srslte_softbuffer_tx_init(&q->softbuffer, q->cell)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
if (srslte_refsignal_ul_init(&q->dmrs, cell)) {
|
||||
fprintf(stderr, "Error initiating srslte_refsignal_ul\n");
|
||||
|
@ -113,9 +111,8 @@ void srslte_ue_ul_free(srslte_ue_ul_t *q) {
|
|||
srslte_ofdm_rx_free(&q->fft);
|
||||
srslte_pusch_free(&q->pusch);
|
||||
srslte_pucch_free(&q->pucch);
|
||||
for (uint32_t i=0;i<SRSLTE_UE_UL_NOF_HARQ_PROCESSES; i++) {
|
||||
srslte_harq_free(&q->harq_process[i]);
|
||||
}
|
||||
srslte_softbuffer_tx_free(&q->softbuffer);
|
||||
|
||||
srslte_cfo_free(&q->cfo);
|
||||
srslte_refsignal_ul_free(&q->dmrs);
|
||||
|
||||
|
@ -154,14 +151,14 @@ void srslte_ue_ul_set_rnti(srslte_ue_ul_t *q, uint16_t rnti) {
|
|||
}
|
||||
|
||||
void srslte_ue_ul_reset(srslte_ue_ul_t *q) {
|
||||
srslte_harq_reset(&q->harq_process[0]);
|
||||
srslte_softbuffer_tx_reset(&q->softbuffer);
|
||||
}
|
||||
|
||||
void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg,
|
||||
srslte_pusch_hopping_cfg_t *pusch_hopping_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg,
|
||||
srslte_pucch_sched_t *pucch_sched)
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg,
|
||||
srslte_pusch_hopping_cfg_t *pusch_hopping_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg,
|
||||
srslte_pucch_sched_t *pucch_sched)
|
||||
{
|
||||
srslte_refsignal_ul_set_pusch_cfg(&q->dmrs, dmrs_cfg);
|
||||
srslte_pusch_set_hopping_cfg(&q->pusch, pusch_hopping_cfg);
|
||||
|
@ -274,11 +271,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
|||
}
|
||||
|
||||
if (q->normalize_en) {
|
||||
uint32_t n_prb = 1;
|
||||
if (q->harq_process[0].ul_alloc.L_prb > 0) {
|
||||
n_prb = q->harq_process[0].ul_alloc.L_prb;
|
||||
}
|
||||
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(n_prb);
|
||||
float norm_factor = (float) q->cell.nof_prb/10;
|
||||
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
}
|
||||
srslte_vec_save_file("pucch", output_signal, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
|
@ -288,64 +281,84 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_ul, uint8_t *data, uint32_t sf_idx, cf_t *output_signal)
|
||||
int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, uint8_t *data, uint32_t sf_idx, uint32_t rv, cf_t *output_signal)
|
||||
{
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
return srslte_ue_ul_pusch_uci_encode_rnti(q, ra_ul, data, uci_data, sf_idx, q->current_rnti, output_signal);
|
||||
return srslte_ue_ul_pusch_uci_encode_rnti(q, grant, data, uci_data, sf_idx, rv, q->current_rnti, output_signal);
|
||||
}
|
||||
|
||||
int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_ul, uint8_t *data, uint32_t sf_idx, uint16_t rnti, cf_t *output_signal)
|
||||
int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, uint8_t *data, uint32_t sf_idx, uint32_t rv, uint16_t rnti, cf_t *output_signal)
|
||||
{
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
return srslte_ue_ul_pusch_uci_encode_rnti(q, ra_ul, data, uci_data, sf_idx, rnti, output_signal);
|
||||
return srslte_ue_ul_pusch_uci_encode_rnti(q, grant, data, uci_data, sf_idx, rv,rnti, output_signal);
|
||||
}
|
||||
|
||||
int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_ul, uint8_t *data, srslte_uci_data_t uci_data, uint32_t sf_idx, cf_t *output_signal)
|
||||
int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, uint8_t *data, srslte_uci_data_t uci_data, uint32_t sf_idx, uint32_t rv, cf_t *output_signal)
|
||||
{
|
||||
return srslte_ue_ul_pusch_uci_encode_rnti(q, ra_ul, data, uci_data, sf_idx, q->current_rnti, output_signal);
|
||||
return srslte_ue_ul_pusch_uci_encode_rnti(q, grant, data, uci_data, sf_idx, rv, q->current_rnti, output_signal);
|
||||
}
|
||||
|
||||
int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_ul, uint8_t *data, srslte_uci_data_t uci_data,
|
||||
uint32_t sf_idx, uint16_t rnti,
|
||||
cf_t *output_signal)
|
||||
int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant,
|
||||
uint8_t *data, srslte_uci_data_t uci_data,
|
||||
uint32_t sf_idx, uint32_t rv, uint16_t rnti,
|
||||
cf_t *output_signal)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL &&
|
||||
ra_ul != NULL &&
|
||||
grant != NULL &&
|
||||
data != NULL &&
|
||||
output_signal != NULL)
|
||||
{
|
||||
|
||||
if (ra_ul->prb_alloc.L_prb == 0) {
|
||||
if (grant->L_prb == 0) {
|
||||
fprintf(stderr, "Invalid UL PRB allocation (L_prb=0)\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
if (srslte_harq_setup_ul(&q->harq_process[0], ra_ul->mcs, ra_ul->rv_idx, sf_idx, &ra_ul->prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (srslte_pusch_encode_rnti(&q->pusch, &q->harq_process[0], data, rnti, q->sf_symbols)) {
|
||||
memcpy(&q->pusch_cfg.grant, grant, sizeof(srslte_ra_ul_grant_t));
|
||||
q->pusch_cfg.sf_idx = sf_idx;
|
||||
q->pusch_cfg.rv = rv;
|
||||
q->pusch_cfg.cp = q->cell.cp;
|
||||
srslte_cbsegm(&q->pusch_cfg.cb_segm, grant->mcs.tbs);
|
||||
|
||||
return srslte_ue_ul_pusch_encode_cfg(q, &q->pusch_cfg, data, uci_data, rnti, output_signal);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
|
||||
uint8_t *data, srslte_uci_data_t uci_data,
|
||||
uint16_t rnti,
|
||||
cf_t *output_signal)
|
||||
{
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL &&
|
||||
cfg != NULL &&
|
||||
data != NULL &&
|
||||
output_signal != NULL)
|
||||
{
|
||||
if (srslte_pusch_encode_rnti(&q->pusch, cfg, &q->softbuffer, data, rnti, q->sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// FIXME: Pregenerate for all possible number of prb
|
||||
if (srslte_refsignal_dmrs_pusch_gen(&q->dmrs, q->harq_process[0].ul_alloc.L_prb, sf_idx, q->refsignal))
|
||||
if (srslte_refsignal_dmrs_pusch_gen(&q->dmrs, cfg->grant.L_prb, cfg->sf_idx, q->refsignal))
|
||||
{
|
||||
fprintf(stderr, "Error generating PUSCH DRMS signals\n");
|
||||
return ret;
|
||||
}
|
||||
srslte_refsignal_dmrs_pusch_put(&q->dmrs, q->refsignal,
|
||||
q->harq_process[0].ul_alloc.L_prb,
|
||||
q->harq_process[0].ul_alloc.n_prb_tilde,
|
||||
q->sf_symbols);
|
||||
cfg->grant.L_prb,
|
||||
cfg->grant.n_prb_tilde,
|
||||
q->sf_symbols);
|
||||
|
||||
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal);
|
||||
|
||||
|
@ -354,7 +367,7 @@ int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_
|
|||
}
|
||||
|
||||
if (q->normalize_en) {
|
||||
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(q->harq_process[0].ul_alloc.L_prb);
|
||||
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(cfg->grant.L_prb);
|
||||
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_t
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool dl_buffer::get_ul_grant(pdcch_ul_search_t mode, sched_grant *grant)
|
||||
bool dl_buffer::get_ul_grant(pdcch_ul_search_t mode, ul_sched_grant *grant)
|
||||
{
|
||||
if (signal_buffer) {
|
||||
if (!sf_symbols_and_ce_done) {
|
||||
|
@ -102,19 +102,12 @@ bool dl_buffer::get_ul_grant(pdcch_ul_search_t mode, sched_grant *grant)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (srslte_dci_msg_to_ra_ul(&dci_msg, cell.nof_prb,
|
||||
params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET),
|
||||
(srslte_ra_pusch_t*) grant->get_grant_ptr()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return grant->create_from_dci(&dci_msg, cell, 0, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, sched_grant *grant)
|
||||
bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, dl_sched_grant *grant)
|
||||
{
|
||||
if (signal_buffer && is_ready()) {
|
||||
INFO("DL Buffer TTI %d: Getting DL grant\n", tti);
|
||||
|
@ -145,18 +138,11 @@ bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, sched_grant *grant)
|
|||
return false;
|
||||
}
|
||||
|
||||
grant->set_ncce(srslte_ue_dl_get_ncce(&ue_dl));
|
||||
|
||||
if (srslte_dci_msg_to_ra_dl(&dci_msg, grant->get_rnti(), cell, cfi,
|
||||
(srslte_ra_pdsch_t*) grant->get_grant_ptr())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return grant->create_from_dci(&dci_msg, cell, cfi, tti%10, srslte_ue_dl_get_ncce(&ue_dl));
|
||||
}
|
||||
}
|
||||
|
||||
bool dl_buffer::decode_ack(sched_grant pusch_grant)
|
||||
bool dl_buffer::decode_ack(ul_sched_grant *grant)
|
||||
{
|
||||
if (signal_buffer && is_ready()) {
|
||||
if (!sf_symbols_and_ce_done) {
|
||||
|
@ -166,13 +152,11 @@ bool dl_buffer::decode_ack(sched_grant pusch_grant)
|
|||
sf_symbols_and_ce_done = true;
|
||||
}
|
||||
|
||||
srslte_ra_pusch_t *ra_ul = (srslte_ra_pusch_t*) pusch_grant.get_grant_ptr();
|
||||
|
||||
return srslte_ue_dl_decode_phich(&ue_dl, tti%10, ra_ul->prb_alloc.n_prb[0], ra_ul->n_dmrs);
|
||||
return srslte_ue_dl_decode_phich(&ue_dl, tti%10, grant->get_I_lowest(), grant->get_n_dmrs());
|
||||
}
|
||||
}
|
||||
|
||||
bool dl_buffer::decode_data(sched_grant pdsch_grant, uint8_t *payload)
|
||||
bool dl_buffer::decode_data(dl_sched_grant *grant, uint8_t *payload)
|
||||
{
|
||||
if (signal_buffer && is_ready()) {
|
||||
INFO("DL Buffer TTI %d: Decoding PDSCH\n", tti);
|
||||
|
@ -184,18 +168,13 @@ bool dl_buffer::decode_data(sched_grant pdsch_grant, uint8_t *payload)
|
|||
sf_symbols_and_ce_done = true;
|
||||
}
|
||||
|
||||
srslte_ra_pdsch_t *ra_dl = (srslte_ra_pdsch_t*) pdsch_grant.get_grant_ptr();
|
||||
if (srslte_harq_setup_dl(&ue_dl.harq_process[0], ra_dl->mcs,
|
||||
ra_dl->rv_idx, tti%10, &ra_dl->prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
if (ue_dl.harq_process[0].mcs.mod > 0 && ue_dl.harq_process[0].mcs.tbs >= 0) {
|
||||
int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.harq_process[0], ue_dl.sf_symbols,
|
||||
ue_dl.ce, 0, pdsch_grant.get_rnti(), payload);
|
||||
grant->get_pdsch_cfg(tti%10, &ue_dl.pdsch_cfg);
|
||||
if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) {
|
||||
int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, &ue_dl.softbuffer, ue_dl.sf_symbols,
|
||||
ue_dl.ce, 0, grant->get_rnti(), payload);
|
||||
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_vec_save_file((char*) "pdsch_d", ue_dl.pdsch.d, ue_dl.harq_process[0].nof_re*sizeof(cf_t));
|
||||
srslte_vec_save_file((char*) "pdsch_d", ue_dl.pdsch.d, ue_dl.pdsch_cfg.grant.nof_re*sizeof(cf_t));
|
||||
}
|
||||
if (ret == SRSLTE_SUCCESS) {
|
||||
return true;
|
||||
|
|
|
@ -102,15 +102,10 @@ void phy::set_timeadv(uint32_t ta_cmd) {
|
|||
INFO("Set TA: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, n_ta, time_adv_sec*1e6);
|
||||
}
|
||||
|
||||
void phy::rar_ul_grant(uint32_t rba, uint32_t trunc_mcs, bool hopping_flag, sched_grant *grant)
|
||||
void phy::rar_ul_grant(srslte_dci_rar_grant_t *rar, ul_sched_grant *grant)
|
||||
{
|
||||
uint32_t n_ho = params_db.get_param(phy_params::PUSCH_HOPPING_OFFSET);
|
||||
srslte_ra_pusch_t *ra_pusch = (srslte_ra_pusch_t*) grant->get_grant_ptr();
|
||||
srslte_dci_rar_to_ra_ul(rba, trunc_mcs, hopping_flag, cell.nof_prb, ra_pusch);
|
||||
srslte_ra_ul_alloc(&ra_pusch->prb_alloc, ra_pusch, n_ho, cell.nof_prb);
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
srslte_ra_pusch_fprint(stdout, ra_pusch, cell.nof_prb);
|
||||
}
|
||||
grant->create_from_rar(rar, cell, 0, params_db.get_param(phy_params::PUSCH_HOPPING_OFFSET));
|
||||
}
|
||||
|
||||
void phy::set_param(phy_params::phy_param_t param, int64_t value) {
|
||||
|
|
|
@ -51,7 +51,7 @@ void prach::free_cell()
|
|||
free(signal_buffer);
|
||||
}
|
||||
srslte_cfo_free(&cfo_h);
|
||||
srslte_prach_free(&prach);
|
||||
srslte_prach_free(&prach_obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_)
|
|||
cell = cell_;
|
||||
params_db = params_db_;
|
||||
preamble_idx = -1;
|
||||
if (srslte_prach_init(&prach, srslte_symbol_sz(cell.nof_prb),
|
||||
if (srslte_prach_init(&prach_obj, srslte_symbol_sz(cell.nof_prb),
|
||||
srslte_prach_get_preamble_format(params_db->get_param(phy_params::PRACH_CONFIG_INDEX)),
|
||||
params_db->get_param(phy_params::PRACH_ROOT_SEQ_IDX),
|
||||
params_db->get_param(phy_params::PRACH_HIGH_SPEED_FLAG)?true:false,
|
||||
|
@ -68,13 +68,13 @@ bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_)
|
|||
return false;
|
||||
}
|
||||
|
||||
len = prach.N_seq + prach.N_cp;
|
||||
len = prach_obj.N_seq + prach_obj.N_cp;
|
||||
for (uint32_t i=0;i<64;i++) {
|
||||
buffer[i] = (cf_t*) srslte_vec_malloc(len*sizeof(cf_t));
|
||||
if(!buffer[i]) {
|
||||
return false;
|
||||
}
|
||||
if(srslte_prach_gen(&prach, i, params_db->get_param(phy_params::PRACH_FREQ_OFFSET), buffer[i])){
|
||||
if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_params::PRACH_FREQ_OFFSET), buffer[i])){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <string.h>
|
||||
#include <strings.h>
|
||||
#include <pthread.h>
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "srslte/ue_itf/sched_grant.h"
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
sched_grant::sched_grant(direction_t direction, uint16_t rnti_)
|
||||
{
|
||||
rnti = rnti_;
|
||||
dir = direction;
|
||||
}
|
||||
|
||||
/* Returns the RNTI associated with the UL/DL scheduling grant */
|
||||
uint16_t sched_grant::get_rnti() {
|
||||
return rnti;
|
||||
}
|
||||
|
||||
uint32_t sched_grant::get_rv() {
|
||||
if (dir == UPLINK) {
|
||||
return ul_grant.rv_idx;
|
||||
} else {
|
||||
return dl_grant.rv_idx;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sched_grant::get_tbs() {
|
||||
if (dir == UPLINK) {
|
||||
return ul_grant.mcs.tbs;
|
||||
} else {
|
||||
return dl_grant.mcs.tbs;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sched_grant::get_ncce()
|
||||
{
|
||||
return ncce;
|
||||
}
|
||||
|
||||
bool srslte::ue::sched_grant::is_sps_release()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void sched_grant::set_ncce(uint32_t ncce_)
|
||||
{
|
||||
ncce = ncce_;
|
||||
}
|
||||
|
||||
uint32_t sched_grant::get_current_tx_nb()
|
||||
{
|
||||
return current_tx_nb;
|
||||
}
|
||||
|
||||
void sched_grant::set_current_tx_nb(uint32_t current_tx_nb_)
|
||||
{
|
||||
current_tx_nb = current_tx_nb_;
|
||||
}
|
||||
|
||||
|
||||
void sched_grant::set_rv(uint32_t rv) {
|
||||
if (dir == UPLINK) {
|
||||
ul_grant.rv_idx = rv;
|
||||
} else {
|
||||
dl_grant.rv_idx = rv;
|
||||
}
|
||||
}
|
||||
|
||||
bool sched_grant::get_ndi() {
|
||||
if (dir == UPLINK) {
|
||||
return ul_grant.ndi;
|
||||
} else {
|
||||
return dl_grant.ndi;
|
||||
}
|
||||
}
|
||||
|
||||
void sched_grant::set_ndi(bool value) {
|
||||
if (dir == UPLINK) {
|
||||
ul_grant.ndi = value;
|
||||
} else {
|
||||
dl_grant.ndi = value;
|
||||
}
|
||||
}
|
||||
|
||||
bool sched_grant::get_cqi_request() {
|
||||
if (dir == UPLINK) {
|
||||
return ul_grant.ndi;
|
||||
} else {
|
||||
return dl_grant.ndi;
|
||||
}
|
||||
}
|
||||
|
||||
int sched_grant::get_harq_process() {
|
||||
if (dir == UPLINK) {
|
||||
return -1;
|
||||
} else {
|
||||
return dl_grant.harq_process;
|
||||
}
|
||||
}
|
||||
|
||||
bool sched_grant::is_uplink() {
|
||||
return dir == UPLINK;
|
||||
}
|
||||
|
||||
bool sched_grant::is_downlink() {
|
||||
return dir == DOWNLINK;
|
||||
}
|
||||
void* sched_grant::get_grant_ptr() {
|
||||
if (is_uplink()) {
|
||||
return (void*) &ul_grant;
|
||||
} else {
|
||||
return (void*) &dl_grant;
|
||||
}
|
||||
}
|
||||
} // namespace ue
|
||||
} // namespace srslte
|
||||
|
|
@ -63,12 +63,12 @@ void ul_buffer::free_cell() {
|
|||
}
|
||||
}
|
||||
|
||||
bool ul_buffer::generate_ack(bool ack, sched_grant last_dl_grant)
|
||||
bool ul_buffer::generate_ack(bool ack, dl_sched_grant *last_dl_grant)
|
||||
{
|
||||
uci_data.uci_ack_len = 1;
|
||||
uci_data.uci_ack = ack?1:0;
|
||||
uci_pending = true;
|
||||
last_n_cce = last_dl_grant.get_ncce();
|
||||
last_n_cce = last_dl_grant->get_ncce();
|
||||
}
|
||||
|
||||
bool ul_buffer::generate_ack(bool ack[2])
|
||||
|
@ -89,11 +89,11 @@ bool ul_buffer::uci_ready() {
|
|||
}
|
||||
|
||||
bool ul_buffer::generate_data() {
|
||||
sched_grant dummy(sched_grant::DOWNLINK, 0);
|
||||
return generate_data(dummy, NULL);
|
||||
ul_sched_grant dummy(0);
|
||||
return generate_data(&dummy, NULL);
|
||||
}
|
||||
|
||||
bool ul_buffer::generate_data(sched_grant pusch_grant,
|
||||
bool ul_buffer::generate_data(ul_sched_grant *grant,
|
||||
uint8_t *payload)
|
||||
{
|
||||
if (is_ready()) {
|
||||
|
@ -115,7 +115,7 @@ bool ul_buffer::generate_data(sched_grant pusch_grant,
|
|||
pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTRA_SF :
|
||||
pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTER_SF;
|
||||
pusch_hopping.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET);
|
||||
pusch_hopping.current_tx_nb = pusch_grant.get_current_tx_nb();
|
||||
pusch_hopping.current_tx_nb = grant->get_current_tx_nb();
|
||||
|
||||
srslte_pucch_cfg_t pucch_cfg;
|
||||
bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t));
|
||||
|
@ -145,10 +145,12 @@ bool ul_buffer::generate_data(sched_grant pusch_grant,
|
|||
int n = 0;
|
||||
// Transmit on PUSCH if UL grant available, otherwise in PUCCH
|
||||
if (payload) {
|
||||
n = srslte_ue_ul_pusch_uci_encode_rnti(&ue_ul, (srslte_ra_pusch_t*) pusch_grant.get_grant_ptr(),
|
||||
payload, uci_data,
|
||||
tti%10, pusch_grant.get_rnti(),
|
||||
signal_buffer);
|
||||
|
||||
grant->to_pusch_cfg(tti%10, cell.cp, &pusch_cfg);
|
||||
n = srslte_ue_ul_pusch_encode_cfg(&ue_ul, &pusch_cfg,
|
||||
payload, uci_data,
|
||||
grant->get_rnti(),
|
||||
signal_buffer);
|
||||
} else {
|
||||
n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti&10, signal_buffer);
|
||||
}
|
||||
|
|
|
@ -214,8 +214,9 @@ void config_phy() {
|
|||
phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_HOPPING_EN, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PUSCH_RS_SEQUENCE_HOPPING_EN, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET, 0);
|
||||
|
||||
|
||||
phy.set_param(srslte::ue::phy_params::PUCCH_BETA, 10);
|
||||
phy.set_param(srslte::ue::phy_params::PUCCH_DELTA_SHIFT, 1);
|
||||
phy.set_param(srslte::ue::phy_params::PUCCH_CYCLIC_SHIFT, 0);
|
||||
|
@ -253,7 +254,7 @@ void run_tti(uint32_t tti) {
|
|||
}
|
||||
}
|
||||
if (state == RAR) {
|
||||
srslte::ue::sched_grant rar_grant(srslte::ue::sched_grant::DOWNLINK, 2);
|
||||
srslte::ue::dl_sched_grant rar_grant(2);
|
||||
int ra_tti = phy.get_prach_transmitted_tti();
|
||||
if (ra_tti > 0) {
|
||||
INFO("PRACH was transmitted at %d\n", ra_tti);
|
||||
|
@ -265,7 +266,7 @@ void run_tti(uint32_t tti) {
|
|||
if (dl_buffer->get_dl_grant(srslte::ue::dl_buffer::PDCCH_DL_SEARCH_RARNTI, &rar_grant))
|
||||
{
|
||||
// Decode packet
|
||||
if (dl_buffer->decode_data(rar_grant, payload)) {
|
||||
if (dl_buffer->decode_data(&rar_grant, payload)) {
|
||||
rar_unpack(payload, &rar_msg);
|
||||
if (!prog_args.continous) {
|
||||
printf("Received RAR for preamble %d\n", rar_msg.RAPID);
|
||||
|
@ -283,8 +284,12 @@ void run_tti(uint32_t tti) {
|
|||
phy.set_timeadv_rar(rar_msg.timing_adv_cmd);
|
||||
|
||||
// Generate Msg3 grant
|
||||
srslte::ue::sched_grant connreq_grant(srslte::ue::sched_grant::UPLINK, rar_msg.temp_c_rnti);
|
||||
phy.rar_ul_grant(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, &connreq_grant);
|
||||
srslte::ue::ul_sched_grant connreq_grant(rar_msg.temp_c_rnti);
|
||||
srslte_dci_rar_grant_t rar_grant;
|
||||
rar_grant.rba = rar_msg.rba;
|
||||
rar_grant.trunc_mcs = rar_msg.mcs;
|
||||
rar_grant.hopping_flag = rar_msg.hopping_flag;
|
||||
phy.rar_ul_grant(&rar_grant, &connreq_grant);
|
||||
|
||||
// Pack Msg3 bits
|
||||
srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload, connreq_grant.get_tbs());
|
||||
|
@ -296,7 +301,7 @@ void run_tti(uint32_t tti) {
|
|||
if (ul_buffer) {
|
||||
connreq_grant.set_rv(0);
|
||||
INFO("Generating PUSCH for TTI: %d\n", ul_buffer->tti);
|
||||
//ul_buffer->generate_pusch(connreq_grant, payload);
|
||||
ul_buffer->generate_data(&connreq_grant, payload);
|
||||
|
||||
// Save transmission time
|
||||
conreq_tti = ul_buffer->tti;
|
||||
|
@ -318,11 +323,15 @@ void run_tti(uint32_t tti) {
|
|||
uint32_t interval_conreq = interval(tti, conreq_tti);
|
||||
if (interval_conreq == 4) {
|
||||
|
||||
srslte::ue::sched_grant connreq_grant(srslte::ue::sched_grant::UPLINK, rar_msg.temp_c_rnti);
|
||||
phy.rar_ul_grant(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, &connreq_grant);
|
||||
srslte::ue::ul_sched_grant connreq_grant(rar_msg.temp_c_rnti);
|
||||
srslte_dci_rar_grant_t rar_grant;
|
||||
rar_grant.rba = rar_msg.rba;
|
||||
rar_grant.trunc_mcs = rar_msg.mcs;
|
||||
rar_grant.hopping_flag = rar_msg.hopping_flag;
|
||||
phy.rar_ul_grant(&rar_grant, &connreq_grant);
|
||||
|
||||
// Decode PHICH from Connection Request
|
||||
if (!dl_buffer->decode_ack(connreq_grant)) {
|
||||
if (!dl_buffer->decode_ack(&connreq_grant)) {
|
||||
|
||||
// Pack Msg3 bits
|
||||
srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload, connreq_grant.get_tbs());
|
||||
|
@ -339,7 +348,7 @@ void run_tti(uint32_t tti) {
|
|||
connreq_grant.set_current_tx_nb(nof_rtx_connsetup);
|
||||
connreq_grant.set_rv(rv_value[nof_rtx_connsetup%4]);
|
||||
INFO("Generating PUSCH for TTI: %d\n", ul_buffer->tti);
|
||||
ul_buffer->generate_data(connreq_grant, payload);
|
||||
ul_buffer->generate_data(&connreq_grant, payload);
|
||||
|
||||
// Save transmission time
|
||||
conreq_tti = ul_buffer->tti;
|
||||
|
@ -354,13 +363,13 @@ void run_tti(uint32_t tti) {
|
|||
}
|
||||
}
|
||||
if (state == CONNSETUP) {
|
||||
srslte::ue::sched_grant conn_setup_grant(srslte::ue::sched_grant::DOWNLINK, rar_msg.temp_c_rnti);
|
||||
srslte::ue::dl_sched_grant conn_setup_grant(rar_msg.temp_c_rnti);
|
||||
bool connsetup_recv = false;
|
||||
// Get DL grant for tmp_rnti
|
||||
if (dl_buffer->get_dl_grant(srslte::ue::dl_buffer::PDCCH_DL_SEARCH_TEMPORAL, &conn_setup_grant))
|
||||
{
|
||||
// Decode packet
|
||||
if (dl_buffer->decode_data(conn_setup_grant, payload)) {
|
||||
if (dl_buffer->decode_data(&conn_setup_grant, payload)) {
|
||||
nof_rx_connsetup++;
|
||||
state = RA;
|
||||
nof_rtx_connsetup=0;
|
||||
|
@ -375,7 +384,7 @@ void run_tti(uint32_t tti) {
|
|||
// send ACK
|
||||
INFO("Sending ack %d on TTI: %d\n", connsetup_recv, tti+4);
|
||||
srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+4);
|
||||
ul_buffer->generate_ack(connsetup_recv, conn_setup_grant);
|
||||
ul_buffer->generate_ack(connsetup_recv, &conn_setup_grant);
|
||||
if (!prog_args.continous) {
|
||||
while(ul_buffer->uci_ready()) {
|
||||
sleep(1);
|
||||
|
|
|
@ -92,7 +92,7 @@ uint8_t payload[1024];
|
|||
|
||||
// This is the MAC implementation
|
||||
void run_tti(uint32_t tti) {
|
||||
srslte::ue::sched_grant grant = srslte::ue::sched_grant(srslte::ue::sched_grant::DOWNLINK, SRSLTE_SIRNTI);
|
||||
srslte::ue::dl_sched_grant grant(SRSLTE_SIRNTI);
|
||||
INFO("MAC running tti: %d\n", tti);
|
||||
|
||||
// SIB1 is scheduled in subframe #5 of even frames
|
||||
|
@ -106,9 +106,9 @@ void run_tti(uint32_t tti) {
|
|||
total_dci++;
|
||||
// MAC sets RV
|
||||
grant.set_rv(((uint32_t) ceilf((float)3*((phy.tti_to_SFN(tti)/2)%4)/2))%4);
|
||||
|
||||
|
||||
// Decode packet
|
||||
if (!buffer->decode_data(grant, payload)) {
|
||||
if (!buffer->decode_data(&grant, payload)) {
|
||||
total_errors++;
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,12 @@ int main(int argc, char *argv[])
|
|||
// Give it time to create thread
|
||||
sleep(1);
|
||||
|
||||
// Set default parameters
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_CONFIG_INDEX, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 1);
|
||||
|
||||
// Set RX freq and gain
|
||||
phy.get_radio()->set_rx_freq(prog_args.uhd_freq);
|
||||
phy.get_radio()->set_rx_gain(prog_args.uhd_gain);
|
||||
|
|
|
@ -209,12 +209,12 @@ int main(int argc, char **argv) {
|
|||
srslte_modem_table_lte(&modulator, modulation, false);
|
||||
|
||||
srslte_tcod_t turbocoder;
|
||||
srslte_tcod_init(&turbocoder, MAX_LONG_CB);
|
||||
srslte_tcod_init(&turbocoder, SRSLTE_TCOD_MAX_LEN_CB);
|
||||
|
||||
srslte_dft_precoding_t dft_precod;
|
||||
srslte_dft_precoding_init(&dft_precod, 12);
|
||||
|
||||
nbits = srslte_find_cb_index(sf_n_samples/8/srslte_mod_bits_x_symbol(modulation)/3 - 12);
|
||||
nbits = srslte_cbsegm_cbindex(sf_n_samples/8/srslte_mod_bits_x_symbol(modulation)/3 - 12);
|
||||
uint32_t ncoded_bits = sf_n_samples/8/srslte_mod_bits_x_symbol(modulation);
|
||||
|
||||
uint8_t *data = malloc(sizeof(uint8_t)*nbits);
|
||||
|
|
|
@ -368,8 +368,8 @@ int main(int argc, char **argv) {
|
|||
float rsrp=0.0, rsrq=0.0, snr=0.0;
|
||||
bool decode_pdsch;
|
||||
int pdcch_tx=0;
|
||||
srslte_ra_pdsch_t old_ra_dl;
|
||||
bzero(&old_ra_dl, sizeof(srslte_ra_pdsch_t));
|
||||
srslte_ra_dl_dci_t old_ra_dl;
|
||||
bzero(&old_ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
|
||||
ue_sync.correct_cfo = prog_args.enable_cfo;
|
||||
|
||||
|
@ -418,8 +418,8 @@ int main(int argc, char **argv) {
|
|||
n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data_packed, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI,
|
||||
((int) ceilf((float)3*(((sfn)/2)%4)/2))%4);
|
||||
}
|
||||
if (memcmp(&ue_dl.ra_dl, &old_ra_dl, sizeof(srslte_ra_pdsch_t))) {
|
||||
memcpy(&old_ra_dl, &ue_dl.ra_dl, sizeof(srslte_ra_pdsch_t));
|
||||
if (memcmp(&ue_dl.ra_dl, &old_ra_dl, sizeof(srslte_ra_dl_dci_t))) {
|
||||
memcpy(&old_ra_dl, &ue_dl.ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
fflush(stdout);printf("\nCFI:\t%d\n", ue_dl.cfi);
|
||||
printf("Format: %s\n", srslte_dci_format_string(ue_dl.dci_format));
|
||||
srslte_ra_pdsch_fprint(stdout, &old_ra_dl, cell.nof_prb);
|
||||
|
|
Loading…
Reference in New Issue