adding adaptations to the phy layer for mbms

master
yagoda 7 years ago
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);
memcpy(data[0], &data2[wpm], nbytes / (size_t) 2); if(mbsfn_area_id > -1){
memcpy(data[1], &data2[wpm], nbytes / (size_t) 2); memcpy(data_mbms, &data2[wpm], nbytes);
}
else{
memcpy(data[0], &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);
@ -830,13 +842,13 @@ int main(int argc, char **argv) {
srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_symbols[0], cell.nof_prb, srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_symbols[0], cell.nof_prb,
SRSLTE_CP_NORM); SRSLTE_CP_NORM);
} }
/* Copy zeros, SSS, PSS into the rest of antenna ports */ /* Copy zeros, SSS, PSS into the rest of antenna ports */
for (i = 1; i < cell.nof_ports; i++) { for (i = 1; i < cell.nof_ports; i++) {
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) {
} }
} }
} }
net_packet_ready = false; if(mbsfn_area_id < 0){
sem_post(&net_sem); net_packet_ready = false;
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,13 +1001,14 @@ 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]);
} }
}else{ }else{
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) {

@ -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];
@ -963,6 +965,15 @@ void *plot_thread_run(void *arg) {
plot_scatter_setYAxisScale(&pscatequal, -4, 4); plot_scatter_setYAxisScale(&pscatequal, -4, 4);
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);
@ -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_pdsch_cfg_t pdsch_cfg; srslte_refsignal_t mbsfnr_signal;
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,11 +673,10 @@ 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);
return 0; return 0;

@ -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) {

@ -69,6 +69,13 @@ 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_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");
@ -82,7 +89,15 @@ 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");
goto clean_exit; goto clean_exit;
@ -97,7 +112,11 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], u
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret); fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
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;
@ -181,11 +210,21 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell)
fprintf(stderr, "Error creating PDSCH object\n"); fprintf(stderr, "Error creating PDSCH object\n");
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,12 +264,29 @@ 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.
*/ */
int srslte_pmch_set_area_id(srslte_pmch_t *q, uint16_t area_id) { int srslte_pmch_set_area_id(srslte_pmch_t *q, uint16_t area_id) {
uint32_t i; uint32_t i;
if (!q->seqs[area_id]) { if (!q->seqs[area_id]) {
q->seqs[area_id] = calloc(1, sizeof(srslte_pmch_seq_t)); q->seqs[area_id] = calloc(1, sizeof(srslte_pmch_seq_t));
if (q->seqs[area_id]) { if (q->seqs[area_id]) {

@ -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;
}
if (srslte_pmch_set_cell(&q->pmch, q->cell)) {
fprintf(stderr, "Error resizing PMCH object\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
q->current_rnti = 0; q->current_rnti = 0;
} }
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;

Loading…
Cancel
Save