mirror of https://github.com/PentHertz/srsLTE.git
adding adaptations to the phy layer for mbms
This commit is contained in:
parent
cc866b6de1
commit
9d7d6c9415
|
@ -123,7 +123,7 @@ int prbset_orig = 0;
|
||||||
|
|
||||||
|
|
||||||
#define DATA_BUFF_SZ 1024*1024
|
#define DATA_BUFF_SZ 1024*1024
|
||||||
uint8_t *data[2], data2[DATA_BUFF_SZ];
|
uint8_t *data_mbms, *data[2], data2[DATA_BUFF_SZ];
|
||||||
uint8_t data_tmp[DATA_BUFF_SZ];
|
uint8_t data_tmp[DATA_BUFF_SZ];
|
||||||
|
|
||||||
void usage(char *prog) {
|
void usage(char *prog) {
|
||||||
|
@ -145,7 +145,7 @@ void usage(char *prog) {
|
||||||
printf("\t-x Transmission mode[single|diversity|cdd|multiplex] [Default %s]\n", mimo_type_str);
|
printf("\t-x Transmission mode[single|diversity|cdd|multiplex] [Default %s]\n", mimo_type_str);
|
||||||
printf("\t-b Precoding Matrix Index (multiplex mode only)* [Default %d]\n", multiplex_pmi);
|
printf("\t-b Precoding Matrix Index (multiplex mode only)* [Default %d]\n", multiplex_pmi);
|
||||||
printf("\t-w Number of codewords/layers (multiplex mode only)* [Default %d]\n", multiplex_nof_layers);
|
printf("\t-w Number of codewords/layers (multiplex mode only)* [Default %d]\n", multiplex_nof_layers);
|
||||||
printf("\t-u listen TCP port for input data (-1 is random) [Default %d]\n", net_port);
|
printf("\t-u listen TCP/UDP port for input data (if mbsfn is active then the stream is over mbsfn only) (-1 is random) [Default %d]\n", net_port);
|
||||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||||
printf("\t-s output file SNR [Default %f]\n", output_file_snr);
|
printf("\t-s output file SNR [Default %f]\n", output_file_snr);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -256,6 +256,7 @@ void base_init() {
|
||||||
}
|
}
|
||||||
bzero(data[i], sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
bzero(data[i], sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
data_mbms = srslte_vec_malloc(sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
||||||
|
|
||||||
/* init memory */
|
/* init memory */
|
||||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||||
|
@ -659,15 +660,21 @@ void *net_thread_fnc(void *arg) {
|
||||||
n = srslte_netsource_read(&net_source, &data2[rpm], DATA_BUFF_SZ-rpm);
|
n = srslte_netsource_read(&net_source, &data2[rpm], DATA_BUFF_SZ-rpm);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
// FIXME: I assume that both transport blocks have same size in case of 2 tb are active
|
// FIXME: I assume that both transport blocks have same size in case of 2 tb are active
|
||||||
int nbytes = 1 + (pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs - 1) / 8;
|
|
||||||
|
int nbytes = 1 + (((mbsfn_area_id > -1)?(pmch_cfg.grant.mcs[0].tbs):(pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs)) - 1) / 8;
|
||||||
rpm += n;
|
rpm += n;
|
||||||
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
|
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
|
||||||
wpm = 0;
|
wpm = 0;
|
||||||
while (rpm >= nbytes) {
|
while (rpm >= nbytes) {
|
||||||
// wait for packet to be transmitted
|
// wait for packet to be transmitted
|
||||||
sem_wait(&net_sem);
|
sem_wait(&net_sem);
|
||||||
|
if(mbsfn_area_id > -1){
|
||||||
|
memcpy(data_mbms, &data2[wpm], nbytes);
|
||||||
|
}
|
||||||
|
else{
|
||||||
memcpy(data[0], &data2[wpm], nbytes / (size_t) 2);
|
memcpy(data[0], &data2[wpm], nbytes / (size_t) 2);
|
||||||
memcpy(data[1], &data2[wpm], nbytes / (size_t) 2);
|
memcpy(data[1], &data2[wpm], nbytes / (size_t) 2);
|
||||||
|
}
|
||||||
INFO("Sent %d/%d bytes ready\n", nbytes, rpm);
|
INFO("Sent %d/%d bytes ready\n", nbytes, rpm);
|
||||||
rpm -= nbytes;
|
rpm -= nbytes;
|
||||||
wpm += nbytes;
|
wpm += nbytes;
|
||||||
|
@ -739,10 +746,15 @@ int main(int argc, char **argv) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if(mbsfn_area_id > -1) {
|
if(mbsfn_area_id > -1) {
|
||||||
if(srslte_refsignal_mbsfn_init(&mbsfn_refs, cell, mbsfn_area_id)) {
|
if(srslte_refsignal_mbsfn_init(&mbsfn_refs, cell.nof_prb)) {
|
||||||
fprintf(stderr, "Error initializing equalizer\n");
|
fprintf(stderr, "Error initializing equalizer\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
if (srslte_refsignal_mbsfn_set_cell(&mbsfn_refs, cell, mbsfn_area_id)) {
|
||||||
|
fprintf(stderr, "Error initializing MBSFNR signal\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(srslte_refsignal_cs_set_cell(&csr_refs, cell)){
|
if(srslte_refsignal_cs_set_cell(&csr_refs, cell)){
|
||||||
|
@ -801,7 +813,7 @@ int main(int argc, char **argv) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pmch_cfg.grant.mcs[0].tbs = 1096;
|
||||||
/* Initiate valid DCI locations */
|
/* Initiate valid DCI locations */
|
||||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||||
srslte_pdcch_ue_locations(&pdcch, locations[i], 30, i, cfi, UE_CRNTI);
|
srslte_pdcch_ue_locations(&pdcch, locations[i], 30, i, cfi, UE_CRNTI);
|
||||||
|
@ -836,7 +848,7 @@ int main(int argc, char **argv) {
|
||||||
memcpy(sf_symbols[i], sf_symbols[0], sizeof(cf_t) * sf_n_re);
|
memcpy(sf_symbols[i], sf_symbols[0], sizeof(cf_t) * sf_n_re);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sf_idx == 1 && mbsfn_area_id > -1){
|
if(sf_idx == 2 && mbsfn_area_id > -1){
|
||||||
srslte_refsignal_mbsfn_put_sf(cell, 0,csr_refs.pilots[0][sf_idx], mbsfn_refs.pilots[0][sf_idx], sf_symbols[0]);
|
srslte_refsignal_mbsfn_put_sf(cell, 0,csr_refs.pilots[0][sf_idx], mbsfn_refs.pilots[0][sf_idx], sf_symbols[0]);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < cell.nof_ports; i++) {
|
for (i = 0; i < cell.nof_ports; i++) {
|
||||||
|
@ -932,41 +944,46 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(mbsfn_area_id < 0){
|
||||||
net_packet_ready = false;
|
net_packet_ready = false;
|
||||||
sem_post(&net_sem);
|
sem_post(&net_sem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}else{ // We're sending MCH on subframe 1 - PDCCH + PMCH
|
}else{ // We're sending MCH on subframe 1 - PDCCH + PMCH
|
||||||
|
|
||||||
/* Encode PDCCH */
|
/* Encode PDCCH */
|
||||||
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
//INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||||
srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
//srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
||||||
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], M_CRNTI, sf_symbols, sf_idx, cfi)) {
|
//if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], M_CRNTI, sf_symbols, sf_idx, cfi)) {
|
||||||
fprintf(stderr, "Error encoding DCI message\n");
|
// fprintf(stderr, "Error encoding DCI message\n");
|
||||||
exit(-1);
|
// exit(-1);
|
||||||
}
|
// }
|
||||||
/* Configure pmch_cfg parameters */
|
/* Configure pmch_cfg parameters */
|
||||||
srslte_ra_dl_grant_t grant;
|
srslte_ra_dl_grant_t grant;
|
||||||
grant.tb_en[0] = true;
|
grant.tb_en[0] = true;
|
||||||
grant.tb_en[1] = false;
|
grant.tb_en[1] = false;
|
||||||
grant.mcs[0].idx = 2;
|
|
||||||
grant.mcs[0].mod = SRSLTE_MOD_QPSK;
|
grant.mcs[0].idx = 13;
|
||||||
grant.nof_prb = cell.nof_prb;
|
grant.nof_prb = cell.nof_prb;
|
||||||
grant.sf_type = SRSLTE_SF_MBSFN;
|
grant.sf_type = SRSLTE_SF_MBSFN;
|
||||||
grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod);
|
|
||||||
srslte_dl_fill_ra_mcs(&grant.mcs[0], cell.nof_prb);
|
srslte_dl_fill_ra_mcs(&grant.mcs[0], cell.nof_prb);
|
||||||
|
grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod);
|
||||||
for(int i = 0; i < 2; i++){
|
for(int i = 0; i < 2; i++){
|
||||||
for(int j = 0; j < grant.nof_prb; j++){
|
for(int j = 0; j < grant.nof_prb; j++){
|
||||||
grant.prb_idx[i][j] = true;
|
grant.prb_idx[i][j] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(int i = 0; i < grant.mcs[0].tbs/8;i++)
|
||||||
|
{
|
||||||
|
data_mbms[i] = i%255;
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, sf_idx)) {
|
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, sf_idx)) {
|
||||||
fprintf(stderr, "Error configuring PMCH\n");
|
fprintf(stderr, "Error configuring PMCH\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
/* Encode PMCH */
|
/* Encode PMCH */
|
||||||
if (srslte_pmch_encode(&pmch, &pmch_cfg, softbuffers[0], data[0], mbsfn_area_id, sf_symbols)) {
|
if (srslte_pmch_encode(&pmch, &pmch_cfg, softbuffers[0], data_mbms, mbsfn_area_id, sf_symbols)) {
|
||||||
fprintf(stderr, "Error encoding PDSCH\n");
|
fprintf(stderr, "Error encoding PDSCH\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -984,7 +1001,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transform to OFDM symbols */
|
/* Transform to OFDM symbols */
|
||||||
if(sf_idx != 1 || mbsfn_area_id < 0){
|
if(sf_idx != 2 || mbsfn_area_id < 0){
|
||||||
for (i = 0; i < cell.nof_ports; i++) {
|
for (i = 0; i < cell.nof_ports; i++) {
|
||||||
srslte_ofdm_tx_sf(&ifft[i]);
|
srslte_ofdm_tx_sf(&ifft[i]);
|
||||||
}
|
}
|
||||||
|
@ -992,6 +1009,7 @@ int main(int argc, char **argv) {
|
||||||
srslte_ofdm_tx_sf(&ifft_mbsfn);
|
srslte_ofdm_tx_sf(&ifft_mbsfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* send to file or usrp */
|
/* send to file or usrp */
|
||||||
if (output_file_name) {
|
if (output_file_name) {
|
||||||
if (!null_file_sink) {
|
if (!null_file_sink) {
|
||||||
|
|
|
@ -864,6 +864,8 @@ int main(int argc, char **argv) {
|
||||||
PRINT_LINE_ADVANCE_CURSOR();
|
PRINT_LINE_ADVANCE_CURSOR();
|
||||||
ue_dl.pdsch_pkt_errors = 0;
|
ue_dl.pdsch_pkt_errors = 0;
|
||||||
ue_dl.pdsch_pkts_total = 0;
|
ue_dl.pdsch_pkts_total = 0;
|
||||||
|
ue_dl.pmch_pkt_errors = 0;
|
||||||
|
ue_dl.pmch_pkts_total = 0;
|
||||||
/*
|
/*
|
||||||
ue_dl.pkt_errors = 0;
|
ue_dl.pkt_errors = 0;
|
||||||
ue_dl.pkts_total = 0;
|
ue_dl.pkts_total = 0;
|
||||||
|
@ -944,7 +946,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
|
||||||
plot_real_t p_sync, pce;
|
plot_real_t p_sync, pce;
|
||||||
plot_scatter_t pscatequal, pscatequal_pdcch;
|
plot_scatter_t pscatequal, pscatequal_pdcch, pscatequal_pmch;
|
||||||
|
|
||||||
float tmp_plot[110*15*2048];
|
float tmp_plot[110*15*2048];
|
||||||
float tmp_plot2[110*15*2048];
|
float tmp_plot2[110*15*2048];
|
||||||
|
@ -964,6 +966,15 @@ void *plot_thread_run(void *arg) {
|
||||||
|
|
||||||
plot_scatter_addToWindowGrid(&pscatequal, (char*)"pdsch_ue", 0, 0);
|
plot_scatter_addToWindowGrid(&pscatequal, (char*)"pdsch_ue", 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
plot_scatter_init(&pscatequal_pmch);
|
||||||
|
plot_scatter_setTitle(&pscatequal_pmch, "PMCH - Equalized Symbols");
|
||||||
|
plot_scatter_setXAxisScale(&pscatequal_pmch, -4, 4);
|
||||||
|
plot_scatter_setYAxisScale(&pscatequal_pmch, -4, 4);
|
||||||
|
|
||||||
|
plot_scatter_addToWindowGrid(&pscatequal_pmch, (char*)"pdsch_ue", 0, 1);
|
||||||
|
|
||||||
if (!prog_args.disable_plots_except_constellation) {
|
if (!prog_args.disable_plots_except_constellation) {
|
||||||
plot_real_init(&pce);
|
plot_real_init(&pce);
|
||||||
plot_real_setTitle(&pce, "Channel Response - Magnitude");
|
plot_real_setTitle(&pce, "Channel Response - Magnitude");
|
||||||
|
@ -979,7 +990,7 @@ void *plot_thread_run(void *arg) {
|
||||||
plot_scatter_setXAxisScale(&pscatequal_pdcch, -4, 4);
|
plot_scatter_setXAxisScale(&pscatequal_pdcch, -4, 4);
|
||||||
plot_scatter_setYAxisScale(&pscatequal_pdcch, -4, 4);
|
plot_scatter_setYAxisScale(&pscatequal_pdcch, -4, 4);
|
||||||
|
|
||||||
plot_real_addToWindowGrid(&pce, (char*)"pdsch_ue", 0, 1);
|
plot_real_addToWindowGrid(&pce, (char*)"pdsch_ue", 0, 2);
|
||||||
plot_real_addToWindowGrid(&pscatequal_pdcch, (char*)"pdsch_ue", 1, 0);
|
plot_real_addToWindowGrid(&pscatequal_pdcch, (char*)"pdsch_ue", 1, 0);
|
||||||
plot_real_addToWindowGrid(&p_sync, (char*)"pdsch_ue", 1, 1);
|
plot_real_addToWindowGrid(&p_sync, (char*)"pdsch_ue", 1, 1);
|
||||||
}
|
}
|
||||||
|
@ -988,6 +999,7 @@ void *plot_thread_run(void *arg) {
|
||||||
sem_wait(&plot_sem);
|
sem_wait(&plot_sem);
|
||||||
|
|
||||||
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits[0].nof_re;
|
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits[0].nof_re;
|
||||||
|
uint32_t nof_symbols_pmch = ue_dl.pmch_cfg.nbits[0].nof_re;
|
||||||
if (!prog_args.disable_plots_except_constellation) {
|
if (!prog_args.disable_plots_except_constellation) {
|
||||||
for (i = 0; i < nof_re; i++) {
|
for (i = 0; i < nof_re; i++) {
|
||||||
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));
|
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));
|
||||||
|
@ -1031,6 +1043,7 @@ void *plot_thread_run(void *arg) {
|
||||||
|
|
||||||
plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.d[0], nof_symbols);
|
plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.d[0], nof_symbols);
|
||||||
|
|
||||||
|
plot_scatter_setNewData(&pscatequal_pmch, ue_dl.pmch.d, nof_symbols_pmch);
|
||||||
if (plot_sf_idx == 1) {
|
if (plot_sf_idx == 1) {
|
||||||
if (prog_args.net_port_signal > 0) {
|
if (prog_args.net_port_signal > 0) {
|
||||||
srslte_netsink_write(&net_sink_signal, &sf_buffer[srslte_ue_sync_sf_len(&ue_sync)/7],
|
srslte_netsink_write(&net_sink_signal, &sf_buffer[srslte_ue_sync_sf_len(&ue_sync)/7],
|
||||||
|
|
|
@ -93,8 +93,10 @@ SRSLTE_API uint32_t srslte_refsignal_cs_v(uint32_t port_id,
|
||||||
|
|
||||||
SRSLTE_API uint32_t srslte_refsignal_cs_nof_symbols(uint32_t port_id);
|
SRSLTE_API uint32_t srslte_refsignal_cs_nof_symbols(uint32_t port_id);
|
||||||
|
|
||||||
SRSLTE_API int srslte_refsignal_mbsfn_init(srslte_refsignal_t *q, srslte_cell_t cell,
|
SRSLTE_API int srslte_refsignal_mbsfn_init(srslte_refsignal_t *q, uint32_t max_prb);
|
||||||
uint16_t mbsfn_area_id);
|
|
||||||
|
SRSLTE_API int srslte_refsignal_mbsfn_set_cell(srslte_refsignal_t * q,
|
||||||
|
srslte_cell_t cell, uint16_t mbsfn_area_id);
|
||||||
|
|
||||||
SRSLTE_API int srslte_refsignal_mbsfn_get_sf(srslte_cell_t cell,
|
SRSLTE_API int srslte_refsignal_mbsfn_get_sf(srslte_cell_t cell,
|
||||||
uint32_t port_id,
|
uint32_t port_id,
|
||||||
|
|
|
@ -92,7 +92,7 @@ SRSLTE_API int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q,
|
||||||
srslte_cp_t cp_type,
|
srslte_cp_t cp_type,
|
||||||
cf_t *in_buffer,
|
cf_t *in_buffer,
|
||||||
cf_t *out_buffer,
|
cf_t *out_buffer,
|
||||||
uint32_t nof_prb);
|
uint32_t max_prb);
|
||||||
|
|
||||||
SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q,
|
SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q,
|
||||||
srslte_cp_t cp_type,
|
srslte_cp_t cp_type,
|
||||||
|
|
|
@ -69,15 +69,20 @@ typedef struct SRSLTE_API {
|
||||||
cf_t *slot1_symbols[SRSLTE_MAX_PORTS];
|
cf_t *slot1_symbols[SRSLTE_MAX_PORTS];
|
||||||
|
|
||||||
srslte_ofdm_t ifft[SRSLTE_MAX_PORTS];
|
srslte_ofdm_t ifft[SRSLTE_MAX_PORTS];
|
||||||
|
|
||||||
|
srslte_ofdm_t ifft_mbsfn;
|
||||||
srslte_pbch_t pbch;
|
srslte_pbch_t pbch;
|
||||||
srslte_pcfich_t pcfich;
|
srslte_pcfich_t pcfich;
|
||||||
srslte_regs_t regs;
|
srslte_regs_t regs;
|
||||||
srslte_pdcch_t pdcch;
|
srslte_pdcch_t pdcch;
|
||||||
srslte_pdsch_t pdsch;
|
srslte_pdsch_t pdsch;
|
||||||
|
srslte_pmch_t pmch;
|
||||||
srslte_phich_t phich;
|
srslte_phich_t phich;
|
||||||
|
|
||||||
srslte_refsignal_t csr_signal;
|
srslte_refsignal_t csr_signal;
|
||||||
|
srslte_refsignal_t mbsfnr_signal;
|
||||||
srslte_pdsch_cfg_t pdsch_cfg;
|
srslte_pdsch_cfg_t pdsch_cfg;
|
||||||
|
srslte_pdsch_cfg_t pmch_cfg;
|
||||||
srslte_ra_dl_dci_t dl_dci;
|
srslte_ra_dl_dci_t dl_dci;
|
||||||
|
|
||||||
srslte_dci_format_t dci_format;
|
srslte_dci_format_t dci_format;
|
||||||
|
@ -134,6 +139,8 @@ SRSLTE_API void srslte_enb_dl_prepare_power_allocation(srslte_enb_dl_t *q);
|
||||||
SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q,
|
SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q,
|
||||||
float amp);
|
float amp);
|
||||||
|
|
||||||
|
SRSLTE_API void srslte_enb_dl_set_non_mbsfn_region(srslte_enb_dl_t *q, uint8_t non_mbsfn_region);
|
||||||
|
|
||||||
SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q);
|
SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q);
|
||||||
|
|
||||||
SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q,
|
SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q,
|
||||||
|
@ -157,8 +164,13 @@ SRSLTE_API void srslte_enb_dl_put_phich(srslte_enb_dl_t *q,
|
||||||
SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q,
|
SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q,
|
||||||
uint32_t tti);
|
uint32_t tti);
|
||||||
|
|
||||||
|
SRSLTE_API void srslte_enb_dl_put_mbsfn_base(srslte_enb_dl_t *q,
|
||||||
|
uint32_t tti);
|
||||||
|
|
||||||
SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q);
|
SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q);
|
||||||
|
|
||||||
|
SRSLTE_API void srslte_enb_dl_gen_signal_mbsfn(srslte_enb_dl_t *q);
|
||||||
|
|
||||||
SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q,
|
SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q,
|
||||||
uint16_t rnti);
|
uint16_t rnti);
|
||||||
|
|
||||||
|
@ -174,6 +186,12 @@ SRSLTE_API int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q,
|
||||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||||
srslte_mimo_type_t mimo_type);
|
srslte_mimo_type_t mimo_type);
|
||||||
|
|
||||||
|
SRSLTE_API int srslte_enb_dl_put_pmch(srslte_enb_dl_t *q,
|
||||||
|
srslte_ra_dl_grant_t *grant,
|
||||||
|
srslte_softbuffer_tx_t *softbuffer,
|
||||||
|
uint32_t sf_idx,
|
||||||
|
uint8_t *data_mbms);
|
||||||
|
|
||||||
SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q,
|
SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q,
|
||||||
srslte_ra_dl_dci_t *grant,
|
srslte_ra_dl_dci_t *grant,
|
||||||
srslte_dci_format_t format,
|
srslte_dci_format_t format,
|
||||||
|
|
|
@ -94,7 +94,7 @@ SRSLTE_API int srslte_pmch_init_multi(srslte_pmch_t *q,
|
||||||
|
|
||||||
SRSLTE_API void srslte_pmch_free(srslte_pmch_t *q);
|
SRSLTE_API void srslte_pmch_free(srslte_pmch_t *q);
|
||||||
|
|
||||||
|
SRSLTE_API int srslte_pmch_set_cell(srslte_pmch_t *q, srslte_cell_t cell);
|
||||||
|
|
||||||
SRSLTE_API int srslte_pmch_set_area_id(srslte_pmch_t *q, uint16_t area_id);
|
SRSLTE_API int srslte_pmch_set_area_id(srslte_pmch_t *q, uint16_t area_id);
|
||||||
|
|
||||||
|
|
|
@ -212,9 +212,12 @@ int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q, uint16_t mbsfn_area_
|
||||||
if (mbsfn_area_id < SRSLTE_MAX_MBSFN_AREA_IDS) {
|
if (mbsfn_area_id < SRSLTE_MAX_MBSFN_AREA_IDS) {
|
||||||
if(!q->mbsfn_refs[mbsfn_area_id]) {
|
if(!q->mbsfn_refs[mbsfn_area_id]) {
|
||||||
q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t));
|
q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t));
|
||||||
|
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell.nof_prb)) {
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(q->mbsfn_refs[mbsfn_area_id]) {
|
if(q->mbsfn_refs[mbsfn_area_id]) {
|
||||||
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
|
if(srslte_refsignal_mbsfn_set_cell(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,11 +270,11 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslt
|
||||||
const float weight = 1.0f;
|
const float weight = 1.0f;
|
||||||
float sum_power = 0.0f;
|
float sum_power = 0.0f;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
uint32_t npilots = (ch_mode == SRSLTE_SF_MBSFN)?SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id):SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
||||||
uint32_t nsymbols =
|
uint32_t nsymbols =
|
||||||
(ch_mode == SRSLTE_SF_MBSFN) ? srslte_refsignal_mbsfn_nof_symbols() : srslte_refsignal_cs_nof_symbols(port_id);
|
(ch_mode == SRSLTE_SF_MBSFN) ? srslte_refsignal_mbsfn_nof_symbols() : srslte_refsignal_cs_nof_symbols(port_id);
|
||||||
uint32_t nref = npilots / nsymbols;
|
uint32_t nref = npilots / nsymbols;
|
||||||
uint32_t fidx = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
uint32_t fidx = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_fidx(1):srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
||||||
|
|
||||||
cf_t *input2d[nsymbols + 2];
|
cf_t *input2d[nsymbols + 2];
|
||||||
cf_t *tmp_noise = q->tmp_noise;
|
cf_t *tmp_noise = q->tmp_noise;
|
||||||
|
@ -497,8 +500,10 @@ void srslte_chest_dl_set_smooth_filter_auto(srslte_chest_dl_t *q, bool enable) {
|
||||||
uint32_t srslte_chest_dl_interleave_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *tmp, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
uint32_t srslte_chest_dl_interleave_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *tmp, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
||||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
||||||
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
||||||
|
uint32_t fidx = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_fidx(1):srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
||||||
|
|
||||||
if (srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0) < 3) {
|
|
||||||
|
if (fidx < 3) {
|
||||||
srslte_vec_interleave(input, &input[nref], tmp, nref);
|
srslte_vec_interleave(input, &input[nref], tmp, nref);
|
||||||
for (int l = 2; l < nsymbols - 1; l += 2) {
|
for (int l = 2; l < nsymbols - 1; l += 2) {
|
||||||
srslte_vec_interleave_add(&input[l * nref], &input[(l + 1) * nref], tmp, nref);
|
srslte_vec_interleave_add(&input[l * nref], &input[(l + 1) * nref], tmp, nref);
|
||||||
|
@ -519,6 +524,7 @@ uint32_t srslte_chest_dl_interleave_pilots(srslte_chest_dl_t *q, cf_t *input, cf
|
||||||
static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
||||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
||||||
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
||||||
|
uint32_t fidx = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_fidx(1):srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
||||||
|
|
||||||
// Average in the time domain if enabled
|
// Average in the time domain if enabled
|
||||||
if (q->average_subframe) {
|
if (q->average_subframe) {
|
||||||
|
@ -549,9 +555,16 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t skip = (ch_mode == SRSLTE_SF_MBSFN)?2*q->cell.nof_prb:0;
|
||||||
|
|
||||||
|
if(ch_mode == SRSLTE_SF_MBSFN){
|
||||||
|
memcpy(&output[0],&input[0],skip*sizeof(cf_t));
|
||||||
|
}
|
||||||
|
|
||||||
// Average in the frequency domain
|
// Average in the frequency domain
|
||||||
for (int l=0;l<nsymbols;l++) {
|
for (int l=0;l<nsymbols;l++) {
|
||||||
srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len);
|
srslte_conv_same_cf(&input[l*nref + skip], q->smooth_filter, &output[l*nref + skip], nref, q->smooth_filter_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,9 +673,8 @@ int srslte_chest_dl_estimate_port_mbsfn(srslte_chest_dl_t *q, cf_t *input, cf_t
|
||||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx],
|
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx],
|
||||||
q->pilot_estimates, (2*q->cell.nof_prb));
|
q->pilot_estimates, (2*q->cell.nof_prb));
|
||||||
|
|
||||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal+(2*q->cell.nof_prb), q->mbsfn_refs[mbsfn_area_id]->pilots[port_id/2][sf_idx],
|
srslte_vec_prod_conj_ccc(&q->pilot_recv_signal[(2*q->cell.nof_prb)], q->mbsfn_refs[mbsfn_area_id]->pilots[port_id/2][sf_idx],
|
||||||
q->pilot_estimates+(2*q->cell.nof_prb), SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id)-(2*q->cell.nof_prb));
|
&q->pilot_estimates[(2*q->cell.nof_prb)], SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id)-(2*q->cell.nof_prb));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_MBSFN);
|
chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_MBSFN);
|
||||||
|
|
|
@ -176,22 +176,21 @@ free_and_exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, srslte_cell_t cell, uint16_t mbsfn_area_id)
|
int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, uint32_t max_prb)
|
||||||
{
|
{
|
||||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
uint32_t i, p;
|
uint32_t i, p;
|
||||||
if (q != NULL &&
|
if (q != NULL)
|
||||||
srslte_cell_isvalid(&cell))
|
|
||||||
{
|
{
|
||||||
ret = SRSLTE_ERROR;
|
ret = SRSLTE_ERROR;
|
||||||
bzero(q, sizeof(srslte_refsignal_t));
|
bzero(q, sizeof(srslte_refsignal_t));
|
||||||
q->cell = cell;
|
|
||||||
q->type = SRSLTE_SF_MBSFN;
|
q->type = SRSLTE_SF_MBSFN;
|
||||||
q->mbsfn_area_id = mbsfn_area_id;
|
|
||||||
|
|
||||||
for (p=0;p<2;p++) {
|
for (p=0;p<2;p++) {
|
||||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||||
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * q->cell.nof_prb * 18);
|
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * max_prb * 18);
|
||||||
if (!q->pilots[p][i]) {
|
if (!q->pilots[p][i]) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
goto free_and_exit;
|
goto free_and_exit;
|
||||||
|
@ -199,9 +198,7 @@ int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, srslte_cell_t cell, uint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(srslte_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) {
|
|
||||||
goto free_and_exit;
|
|
||||||
}
|
|
||||||
ret = SRSLTE_SUCCESS;
|
ret = SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +209,24 @@ free_and_exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srslte_refsignal_mbsfn_set_cell(srslte_refsignal_t * q, srslte_cell_t cell, uint16_t mbsfn_area_id){
|
||||||
|
|
||||||
|
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
q->cell = cell;
|
||||||
|
|
||||||
|
q->mbsfn_area_id = mbsfn_area_id;
|
||||||
|
if(srslte_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) {
|
||||||
|
goto free_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SRSLTE_SUCCESS;
|
||||||
|
|
||||||
|
free_and_exit:
|
||||||
|
if (ret == SRSLTE_ERROR) {
|
||||||
|
srslte_refsignal_free(q);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Allocates memory for the 20 slots in a subframe
|
/** Allocates memory for the 20 slots in a subframe
|
||||||
|
|
|
@ -149,6 +149,7 @@ int srslte_ofdm_replan_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof
|
||||||
|
|
||||||
q->symbol_sz = (uint32_t) symbol_sz;
|
q->symbol_sz = (uint32_t) symbol_sz;
|
||||||
q->nof_symbols = SRSLTE_CP_NSYMB(cp);
|
q->nof_symbols = SRSLTE_CP_NSYMB(cp);
|
||||||
|
q->nof_symbols_mbsfn = SRSLTE_CP_NSYMB(SRSLTE_CP_EXT);
|
||||||
q->cp = cp;
|
q->cp = cp;
|
||||||
q->nof_re = (uint32_t) nof_prb * SRSLTE_NRE;
|
q->nof_re = (uint32_t) nof_prb * SRSLTE_NRE;
|
||||||
q->nof_guards = ((symbol_sz - q->nof_re) / 2);
|
q->nof_guards = ((symbol_sz - q->nof_re) / 2);
|
||||||
|
@ -246,14 +247,15 @@ int srslte_ofdm_rx_init(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t
|
||||||
return srslte_ofdm_init_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_FORWARD);
|
return srslte_ofdm_init_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_FORWARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t nof_prb)
|
int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, cf_t *out_buffer, uint32_t max_prb)
|
||||||
{
|
{
|
||||||
int symbol_sz = srslte_symbol_sz(nof_prb);
|
int symbol_sz = srslte_symbol_sz(max_prb);
|
||||||
if (symbol_sz < 0) {
|
if (symbol_sz < 0) {
|
||||||
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
|
fprintf(stderr, "Error: Invalid nof_prb=%d\n", max_prb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_FORWARD, SRSLTE_SF_MBSFN);
|
q->max_prb = max_prb;
|
||||||
|
return srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, max_prb, SRSLTE_DFT_FORWARD, SRSLTE_SF_MBSFN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -292,7 +294,7 @@ int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer,
|
||||||
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
|
fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
q->max_prb = nof_prb;
|
||||||
ret = srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_BACKWARD, SRSLTE_SF_MBSFN);
|
ret = srslte_ofdm_init_mbsfn_(q, cp, in_buffer, out_buffer, symbol_sz, nof_prb, SRSLTE_DFT_BACKWARD, SRSLTE_SF_MBSFN);
|
||||||
|
|
||||||
if (ret == SRSLTE_SUCCESS) {
|
if (ret == SRSLTE_SUCCESS) {
|
||||||
|
|
|
@ -70,6 +70,13 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (srslte_ofdm_tx_init_mbsfn(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->sf_symbols[0], out_buffer[0], max_prb)) {
|
||||||
|
fprintf(stderr, "Error initiating FFT \n");
|
||||||
|
goto clean_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (srslte_pbch_init(&q->pbch)) {
|
if (srslte_pbch_init(&q->pbch)) {
|
||||||
fprintf(stderr, "Error creating PBCH object\n");
|
fprintf(stderr, "Error creating PBCH object\n");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
|
@ -82,6 +89,14 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
|
||||||
fprintf(stderr, "Error creating PHICH object\n");
|
fprintf(stderr, "Error creating PHICH object\n");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
int mbsfn_area_id = 1;
|
||||||
|
|
||||||
|
|
||||||
|
if (srslte_pmch_init(&q->pmch, max_prb)) {
|
||||||
|
fprintf(stderr, "Error creating PMCH object\n");
|
||||||
|
}
|
||||||
|
srslte_pmch_set_area_id(&q->pmch, mbsfn_area_id);
|
||||||
|
|
||||||
|
|
||||||
if (srslte_pdcch_init_enb(&q->pdcch, max_prb)) {
|
if (srslte_pdcch_init_enb(&q->pdcch, max_prb)) {
|
||||||
fprintf(stderr, "Error creating PDCCH object\n");
|
fprintf(stderr, "Error creating PDCCH object\n");
|
||||||
|
@ -98,6 +113,10 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_refsignal_mbsfn_init(&q->mbsfnr_signal, max_prb)) {
|
||||||
|
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||||
|
goto clean_exit;
|
||||||
|
}
|
||||||
ret = SRSLTE_SUCCESS;
|
ret = SRSLTE_SUCCESS;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,15 +136,16 @@ void srslte_enb_dl_free(srslte_enb_dl_t *q)
|
||||||
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||||
srslte_ofdm_tx_free(&q->ifft[i]);
|
srslte_ofdm_tx_free(&q->ifft[i]);
|
||||||
}
|
}
|
||||||
|
srslte_ofdm_tx_free(&q->ifft_mbsfn);
|
||||||
srslte_regs_free(&q->regs);
|
srslte_regs_free(&q->regs);
|
||||||
srslte_pbch_free(&q->pbch);
|
srslte_pbch_free(&q->pbch);
|
||||||
srslte_pcfich_free(&q->pcfich);
|
srslte_pcfich_free(&q->pcfich);
|
||||||
srslte_phich_free(&q->phich);
|
srslte_phich_free(&q->phich);
|
||||||
srslte_pdcch_free(&q->pdcch);
|
srslte_pdcch_free(&q->pdcch);
|
||||||
srslte_pdsch_free(&q->pdsch);
|
srslte_pdsch_free(&q->pdsch);
|
||||||
|
srslte_pmch_free(&q->pmch);
|
||||||
srslte_refsignal_free(&q->csr_signal);
|
srslte_refsignal_free(&q->csr_signal);
|
||||||
|
srslte_refsignal_free(&q->mbsfnr_signal);
|
||||||
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
|
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
|
||||||
if (q->sf_symbols[i]) {
|
if (q->sf_symbols[i]) {
|
||||||
free(q->sf_symbols[i]);
|
free(q->sf_symbols[i]);
|
||||||
|
@ -159,6 +179,15 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_ofdm_tx_set_prb(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) {
|
||||||
|
fprintf(stderr, "Error re-planning ifft_mbsfn\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
srslte_ofdm_set_non_mbsfn_region(&q->ifft_mbsfn, 2);
|
||||||
|
//srslte_ofdm_set_normalize(&q->ifft_mbsfn, true);
|
||||||
|
|
||||||
if (srslte_pbch_set_cell(&q->pbch, q->cell)) {
|
if (srslte_pbch_set_cell(&q->pbch, q->cell)) {
|
||||||
fprintf(stderr, "Error creating PBCH object\n");
|
fprintf(stderr, "Error creating PBCH object\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
@ -182,10 +211,20 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_pmch_set_cell(&q->pmch, q->cell)) {
|
||||||
|
fprintf(stderr, "Error creating PMCH object\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_refsignal_cs_set_cell(&q->csr_signal, q->cell)) {
|
if (srslte_refsignal_cs_set_cell(&q->csr_signal, q->cell)) {
|
||||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
int mbsfn_area_id = 1;
|
||||||
|
if (srslte_refsignal_mbsfn_set_cell(&q->mbsfnr_signal, q->cell, mbsfn_area_id)) {
|
||||||
|
fprintf(stderr, "Error initializing MBSFNR signal (%d)\n",ret);
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
/* Generate PSS/SSS signals */
|
/* Generate PSS/SSS signals */
|
||||||
srslte_pss_generate(q->pss_signal, cell.id%3);
|
srslte_pss_generate(q->pss_signal, cell.id%3);
|
||||||
srslte_sss_generate(q->sss_signal0, q->sss_signal5, cell.id);
|
srslte_sss_generate(q->sss_signal0, q->sss_signal5, cell.id);
|
||||||
|
@ -201,6 +240,11 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void srslte_enb_dl_set_non_mbsfn_region(srslte_enb_dl_t *q, uint8_t non_mbsfn_region)
|
||||||
|
{
|
||||||
|
srslte_ofdm_set_non_mbsfn_region(&q->ifft_mbsfn, non_mbsfn_region);
|
||||||
|
}
|
||||||
|
|
||||||
void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, float amp)
|
void srslte_enb_dl_set_amp(srslte_enb_dl_t *q, float amp)
|
||||||
{
|
{
|
||||||
q->tx_amp = amp;
|
q->tx_amp = amp;
|
||||||
|
@ -334,17 +378,30 @@ void srslte_enb_dl_put_base(srslte_enb_dl_t *q, uint32_t tti)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void srslte_enb_dl_put_mbsfn_base(srslte_enb_dl_t *q, uint32_t tti)
|
||||||
|
{
|
||||||
|
uint32_t sf_idx1 = tti%10;
|
||||||
|
srslte_enb_dl_put_pcfich(q, sf_idx1);
|
||||||
|
srslte_refsignal_mbsfn_put_sf(q->cell, 0,q->csr_signal.pilots[0][sf_idx1], q->mbsfnr_signal.pilots[0][sf_idx1], q->sf_symbols[0]);
|
||||||
|
}
|
||||||
|
|
||||||
void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q)
|
void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q)
|
||||||
{
|
{
|
||||||
// TODO: PAPR control
|
// TODO: PAPR control
|
||||||
float norm_factor = (float) sqrt(q->cell.nof_prb)/15/sqrt(q->ifft[0].symbol_sz);
|
float norm_factor = (float) sqrt(q->cell.nof_prb)/15/sqrt(q->ifft[0].symbol_sz);
|
||||||
|
|
||||||
for (int i = 0; i < q->cell.nof_ports; i++) {
|
for (int i = 0; i < q->cell.nof_ports; i++) {
|
||||||
srslte_ofdm_tx_sf(&q->ifft[i]);
|
srslte_ofdm_tx_sf(&q->ifft[i]);
|
||||||
srslte_vec_sc_prod_cfc(q->ifft[i].out_buffer, q->tx_amp*norm_factor, q->ifft[i].out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
srslte_vec_sc_prod_cfc(q->ifft[i].out_buffer, norm_factor, q->ifft[i].out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void srslte_enb_dl_gen_signal_mbsfn(srslte_enb_dl_t *q)
|
||||||
|
{
|
||||||
|
float norm_factor = (float) sqrt(q->cell.nof_prb)/15/sqrt(q->ifft_mbsfn.symbol_sz);
|
||||||
|
srslte_ofdm_tx_sf(&q->ifft_mbsfn);
|
||||||
|
srslte_vec_sc_prod_cfc(q->ifft_mbsfn.out_buffer, norm_factor, q->ifft_mbsfn.out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||||
|
}
|
||||||
|
|
||||||
int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti)
|
int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q, uint16_t rnti)
|
||||||
{
|
{
|
||||||
return srslte_pdsch_set_rnti(&q->pdsch, rnti);
|
return srslte_pdsch_set_rnti(&q->pdsch, rnti);
|
||||||
|
@ -438,7 +495,23 @@ int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srs
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srslte_enb_dl_put_pmch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer, uint32_t sf_idx, uint8_t *data_mbms)
|
||||||
|
{
|
||||||
|
/* Encode PMCH */
|
||||||
|
|
||||||
|
int mbsfn_area_id = 1;
|
||||||
|
if (srslte_pmch_cfg(&q->pmch_cfg, q->cell, grant, q->cfi, sf_idx)) {
|
||||||
|
fprintf(stderr, "Error configuring PMCH\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
/* Encode PMCH */
|
||||||
|
if (srslte_pmch_encode(&q->pmch, &q->pmch_cfg, softbuffer, data_mbms, mbsfn_area_id, q->sf_symbols)) {
|
||||||
|
fprintf(stderr, "Error encoding PDSCH\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void srslte_enb_dl_save_signal(srslte_enb_dl_t *q, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, uint32_t tti, uint32_t rv_idx, uint16_t rnti, uint32_t cfi)
|
void srslte_enb_dl_save_signal(srslte_enb_dl_t *q, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, uint32_t tti, uint32_t rv_idx, uint16_t rnti, uint32_t cfi)
|
||||||
{
|
{
|
||||||
|
|
|
@ -264,6 +264,23 @@ void srslte_pmch_free(srslte_pmch_t *q) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srslte_pmch_set_cell(srslte_pmch_t *q, srslte_cell_t cell)
|
||||||
|
{
|
||||||
|
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
|
||||||
|
if (q != NULL &&
|
||||||
|
srslte_cell_isvalid(&cell))
|
||||||
|
{
|
||||||
|
memcpy(&q->cell, &cell, sizeof(srslte_cell_t));
|
||||||
|
q->max_re = q->cell.nof_prb * MAX_PMCH_RE;
|
||||||
|
|
||||||
|
INFO("PMCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d\n", q->cell.nof_ports,
|
||||||
|
q->cell.id, q->cell.nof_prb, q->max_re);
|
||||||
|
|
||||||
|
ret = SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Precalculate the scramble sequences for a given MBSFN area ID. This function takes a while
|
/* Precalculate the scramble sequences for a given MBSFN area ID. This function takes a while
|
||||||
* to execute.
|
* to execute.
|
||||||
|
|
|
@ -199,8 +199,10 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell)
|
||||||
if (q != NULL &&
|
if (q != NULL &&
|
||||||
srslte_cell_isvalid(&cell))
|
srslte_cell_isvalid(&cell))
|
||||||
{
|
{
|
||||||
q->pkt_errors = 0;
|
q->pdsch_pkt_errors = 0;
|
||||||
q->pkts_total = 0;
|
q->pdsch_pkts_total = 0;
|
||||||
|
q->pmch_pkt_errors = 0;
|
||||||
|
q->pmch_pkts_total = 0;
|
||||||
q->pending_ul_dci_rnti = 0;
|
q->pending_ul_dci_rnti = 0;
|
||||||
|
|
||||||
if (q->cell.id != cell.id || q->cell.nof_prb == 0) {
|
if (q->cell.id != cell.id || q->cell.nof_prb == 0) {
|
||||||
|
@ -218,6 +220,12 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell)
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_ofdm_rx_set_prb(&q->fft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) {
|
||||||
|
fprintf(stderr, "Error resizing MBSFN FFT\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_chest_dl_set_cell(&q->chest, q->cell)) {
|
if (srslte_chest_dl_set_cell(&q->chest, q->cell)) {
|
||||||
fprintf(stderr, "Error resizing channel estimator\n");
|
fprintf(stderr, "Error resizing channel estimator\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
@ -237,9 +245,15 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) {
|
if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) {
|
||||||
fprintf(stderr, "Error creating PDSCH object\n");
|
fprintf(stderr, "Error resizing PDSCH object\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_pmch_set_cell(&q->pmch, q->cell)) {
|
||||||
|
fprintf(stderr, "Error resizing PMCH object\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
q->current_rnti = 0;
|
q->current_rnti = 0;
|
||||||
}
|
}
|
||||||
ret = SRSLTE_SUCCESS;
|
ret = SRSLTE_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue