mirror of https://github.com/pvnis/srsRAN_4G.git
refactor Sidelink PSBCH and DMRS code
parent
e5609e299d
commit
7de51c8236
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2013-2019 Software Radio Systems Limited
|
||||
*
|
||||
* This file is part of srsLTE.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSLTE_MIB_SL_H
|
||||
#define SRSLTE_MIB_SL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
|
||||
/**
|
||||
* Master information block - Sidelink (MIB-SL and MIB-SL-V2X).
|
||||
*
|
||||
* \brief MIB-SL packing/unpacking functions to convert between bit streams
|
||||
*
|
||||
* Reference: 3GPP TS 36.331 version 15.6.0 Release 15 Sec. 6.5
|
||||
*/
|
||||
typedef struct SRSLTE_API {
|
||||
|
||||
uint32_t mib_sl_len;
|
||||
|
||||
// sl-Bandwidth-r12 enum {6, 15, 25, 50, 75, 100} (3 bits)
|
||||
uint32_t sl_bandwidth_r12;
|
||||
|
||||
// tdd-ConfigSL-r12 (3 bits)
|
||||
uint32_t tdd_config_sl_r12;
|
||||
|
||||
// directFrameNumber-r12 (10 bits)
|
||||
uint32_t direct_frame_number_r12;
|
||||
|
||||
// directSubframeNumber-r12 (4 bits)
|
||||
uint32_t direct_subframe_number_r12;
|
||||
|
||||
// inCoverage-r12 (1 bit)
|
||||
bool in_coverage_r12;
|
||||
|
||||
// reserved-r12
|
||||
// TM2: (19 bits)
|
||||
// TM4: (27 bits)
|
||||
|
||||
} srslte_mib_sl_t;
|
||||
|
||||
SRSLTE_API int srslte_mib_sl_init(srslte_mib_sl_t* q, srslte_sl_tm_t tm);
|
||||
|
||||
SRSLTE_API int srslte_mib_sl_set(srslte_mib_sl_t* q,
|
||||
uint32_t nof_prb,
|
||||
uint32_t tdd_config,
|
||||
uint32_t direct_frame_number,
|
||||
uint32_t direct_subframe_number,
|
||||
bool in_coverage);
|
||||
|
||||
SRSLTE_API void srslte_mib_sl_pack(srslte_mib_sl_t* q, uint8_t* msg);
|
||||
|
||||
SRSLTE_API void srslte_mib_sl_unpack(srslte_mib_sl_t* q, uint8_t* msg);
|
||||
|
||||
SRSLTE_API void srslte_mib_sl_free(srslte_mib_sl_t* q);
|
||||
|
||||
SRSLTE_API void srslte_mib_sl_printf(FILE* f, srslte_mib_sl_t* q);
|
||||
|
||||
#endif // SRSLTE_MIB_SL_H
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2013-2019 Software Radio Systems Limited
|
||||
*
|
||||
* This file is part of srsLTE.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include "srslte/phy/phch/mib_sl.h"
|
||||
#include "srslte/phy/utils/bit.h"
|
||||
//#include "srslte/phy/common/phy_sl_common.h"
|
||||
|
||||
int srslte_mib_sl_init(srslte_mib_sl_t* q, srslte_sl_tm_t tm)
|
||||
{
|
||||
if (tm == SRSLTE_SIDELINK_TM1 || tm == SRSLTE_SIDELINK_TM2) {
|
||||
q->mib_sl_len = SRSLTE_MIB_SL_LEN;
|
||||
} else if (tm == SRSLTE_SIDELINK_TM3 || tm == SRSLTE_SIDELINK_TM4) {
|
||||
q->mib_sl_len = SRSLTE_MIB_SL_V2X_LEN;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
q->sl_bandwidth_r12 = 0;
|
||||
q->direct_frame_number_r12 = 0;
|
||||
q->direct_subframe_number_r12 = 0;
|
||||
q->in_coverage_r12 = false;
|
||||
q->tdd_config_sl_r12 = 0;
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_mib_sl_set(srslte_mib_sl_t* q,
|
||||
uint32_t nof_prb,
|
||||
uint32_t tdd_config,
|
||||
uint32_t direct_frame_number,
|
||||
uint32_t direct_subframe_number,
|
||||
bool in_coverage)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL) {
|
||||
switch (nof_prb) {
|
||||
case 6:
|
||||
q->sl_bandwidth_r12 = 0;
|
||||
break;
|
||||
case 15:
|
||||
q->sl_bandwidth_r12 = 1;
|
||||
break;
|
||||
case 25:
|
||||
q->sl_bandwidth_r12 = 2;
|
||||
break;
|
||||
case 50:
|
||||
q->sl_bandwidth_r12 = 3;
|
||||
break;
|
||||
case 75:
|
||||
q->sl_bandwidth_r12 = 4;
|
||||
break;
|
||||
case 100:
|
||||
q->sl_bandwidth_r12 = 5;
|
||||
break;
|
||||
default:
|
||||
printf("Invalid bandwidth\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
q->tdd_config_sl_r12 = tdd_config;
|
||||
q->direct_frame_number_r12 = direct_frame_number;
|
||||
q->direct_subframe_number_r12 = direct_subframe_number;
|
||||
q->in_coverage_r12 = in_coverage;
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_mib_sl_pack(srslte_mib_sl_t* q, uint8_t* msg)
|
||||
{
|
||||
bzero(msg, sizeof(uint8_t) * SRSLTE_MIB_SL_MAX_LEN);
|
||||
srslte_bit_unpack(q->sl_bandwidth_r12, &msg, 3);
|
||||
srslte_bit_unpack(q->tdd_config_sl_r12, &msg, 3);
|
||||
srslte_bit_unpack(q->direct_frame_number_r12, &msg, 10);
|
||||
srslte_bit_unpack(q->direct_subframe_number_r12, &msg, 4);
|
||||
srslte_bit_unpack((uint32_t)q->in_coverage_r12, &msg, 1);
|
||||
}
|
||||
|
||||
void srslte_mib_sl_unpack(srslte_mib_sl_t* q, uint8_t* msg)
|
||||
{
|
||||
q->sl_bandwidth_r12 = srslte_bit_pack(&msg, 3);
|
||||
q->tdd_config_sl_r12 = srslte_bit_pack(&msg, 3);
|
||||
q->direct_frame_number_r12 = srslte_bit_pack(&msg, 10);
|
||||
q->direct_subframe_number_r12 = srslte_bit_pack(&msg, 4);
|
||||
q->in_coverage_r12 = (bool)srslte_bit_pack(&msg, 1);
|
||||
}
|
||||
|
||||
void srslte_mib_sl_printf(FILE* f, srslte_mib_sl_t* q)
|
||||
{
|
||||
fprintf(f, " - Bandwidth: %i\n", q->sl_bandwidth_r12);
|
||||
fprintf(f, " - Direct Frame Number: %i\n", q->direct_frame_number_r12);
|
||||
fprintf(f, " - Direct Subframe Number: %i\n", q->direct_subframe_number_r12);
|
||||
fprintf(f, " - TDD config: %i\n", q->tdd_config_sl_r12);
|
||||
fprintf(f, " - In coverage: %s\n", q->in_coverage_r12 ? "yes" : "no");
|
||||
}
|
||||
|
||||
void srslte_mib_sl_free(srslte_mib_sl_t* q)
|
||||
{
|
||||
if (q != NULL) {
|
||||
bzero(q, sizeof(srslte_mib_sl_t));
|
||||
}
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright 2013-2019 Software Radio Systems Limited
|
||||
*
|
||||
* This file is part of srsLTE.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <srslte/phy/ch_estimation/chest_sl.h>
|
||||
#include <srslte/phy/dft/ofdm.h>
|
||||
#include <srslte/phy/io/filesource.h>
|
||||
#include <srslte/phy/phch/mib_sl.h>
|
||||
#include <srslte/phy/phch/psbch.h>
|
||||
#include <srslte/phy/sync/cfo.h>
|
||||
#include <srslte/phy/utils/debug.h>
|
||||
#include <srslte/phy/utils/vector.h>
|
||||
|
||||
char* input_file_name;
|
||||
int32_t N_sl_id = 168;
|
||||
uint32_t offset = 0;
|
||||
float frequency_offset = 0.0;
|
||||
float snr = 100.0;
|
||||
srslte_cp_t cp = SRSLTE_CP_NORM;
|
||||
uint32_t nof_prb = 6;
|
||||
bool use_standard_lte_rates = false;
|
||||
bool do_equalization = true;
|
||||
srslte_sl_tm_t tm = SRSLTE_SIDELINK_TM2;
|
||||
|
||||
srslte_filesource_t fsrc;
|
||||
|
||||
void usage(char* prog)
|
||||
{
|
||||
printf("Usage: %s [cdeipt]\n", prog);
|
||||
printf("\t-i input_file_name\n");
|
||||
printf("\t-p nof_prb [Default %d]\n", nof_prb);
|
||||
printf("\t-e extended CP [Default normal]\n");
|
||||
printf("\t-d use_standard_lte_rates [Default %i]\n", use_standard_lte_rates);
|
||||
printf("\t-s skip equalization [Default no]\n");
|
||||
printf("\t-c N_sl_id [Default %d]\n", N_sl_id);
|
||||
printf("\t-t Sidelink transmission mode {1,2,3,4} [Default %d]\n", (tm + 1));
|
||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char** argv)
|
||||
{
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "cdeisptv")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
N_sl_id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'd':
|
||||
use_standard_lte_rates = true;
|
||||
break;
|
||||
case 's':
|
||||
do_equalization = false;
|
||||
break;
|
||||
case 'e':
|
||||
cp = SRSLTE_CP_EXT;
|
||||
break;
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
break;
|
||||
case 'p':
|
||||
nof_prb = atoi(argv[optind]);
|
||||
break;
|
||||
case 't':
|
||||
switch (atoi(argv[optind])) {
|
||||
case 1:
|
||||
tm = SRSLTE_SIDELINK_TM1;
|
||||
break;
|
||||
case 2:
|
||||
tm = SRSLTE_SIDELINK_TM2;
|
||||
break;
|
||||
case 3:
|
||||
tm = SRSLTE_SIDELINK_TM3;
|
||||
break;
|
||||
case 4:
|
||||
tm = SRSLTE_SIDELINK_TM4;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = SRSLTE_ERROR;
|
||||
|
||||
parse_args(argc, argv);
|
||||
srslte_use_standard_symbol_size(use_standard_lte_rates);
|
||||
|
||||
int32_t symbol_sz = srslte_symbol_sz(nof_prb);
|
||||
printf("Symbol SZ: %i\n", symbol_sz);
|
||||
|
||||
uint32_t sf_n_samples = srslte_symbol_sz(nof_prb) * 15;
|
||||
printf("sf_n_samples: %i\n", sf_n_samples);
|
||||
|
||||
uint32_t sf_n_re = SRSLTE_CP_NSYMB(cp) * SRSLTE_NRE * 2 * nof_prb;
|
||||
cf_t* sf_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_re);
|
||||
cf_t* equalized_sf_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_re);
|
||||
|
||||
cf_t* input_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_samples);
|
||||
cf_t* output_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_samples);
|
||||
|
||||
// TX
|
||||
srslte_ofdm_t ifft;
|
||||
if (srslte_ofdm_tx_init(&ifft, cp, sf_buffer, output_buffer, nof_prb)) {
|
||||
ERROR("Error creating IFFT object\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
srslte_ofdm_set_normalize(&ifft, true);
|
||||
srslte_ofdm_set_freq_shift(&ifft, 0.5);
|
||||
|
||||
// RX
|
||||
srslte_ofdm_t fft;
|
||||
if (srslte_ofdm_rx_init(&fft, cp, input_buffer, sf_buffer, nof_prb)) {
|
||||
fprintf(stderr, "Error creating FFT object\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
srslte_ofdm_set_normalize(&fft, true);
|
||||
srslte_ofdm_set_freq_shift(&fft, -0.5);
|
||||
|
||||
// PSBCH
|
||||
srslte_psbch_t psbch;
|
||||
srslte_psbch_init(&psbch, nof_prb, N_sl_id, tm, SRSLTE_CP_NORM);
|
||||
|
||||
// PSCBH DMRS
|
||||
srslte_chest_sl_t psbch_chest;
|
||||
srslte_chest_sl_init_psbch_dmrs(&psbch_chest);
|
||||
|
||||
// Read subframe from third party implementations
|
||||
if (!input_file_name || srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) {
|
||||
printf("Error opening file %s\n", input_file_name);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
srslte_filesource_read(&fsrc, input_buffer, sf_n_samples);
|
||||
// srslte_vec_sc_prod_cfc(input_buffer, sqrtf(symbol_sz), input_buffer, sf_n_samples);
|
||||
|
||||
// Run FFT
|
||||
srslte_ofdm_rx_sf(&fft);
|
||||
|
||||
// Equalize
|
||||
if (do_equalization) {
|
||||
srslte_chest_sl_gen_psbch_dmrs(&psbch_chest, tm, N_sl_id);
|
||||
srslte_chest_sl_psbch_ls_estimate_equalize(&psbch_chest, sf_buffer, equalized_sf_buffer, nof_prb, tm, cp);
|
||||
} else {
|
||||
// just copy symbols
|
||||
memcpy(equalized_sf_buffer, sf_buffer, sizeof(cf_t) * sf_n_re);
|
||||
}
|
||||
|
||||
// prepare Rx buffer
|
||||
uint8_t mib_sl_rx[SRSLTE_MIB_SL_MAX_LEN] = {};
|
||||
|
||||
// Decode PSBCH
|
||||
if (srslte_psbch_decode(&psbch, equalized_sf_buffer, mib_sl_rx, sizeof(mib_sl_rx)) == SRSLTE_SUCCESS) {
|
||||
printf("Rx payload: ");
|
||||
srslte_vec_fprint_hex(stdout, mib_sl_rx, sizeof(mib_sl_rx));
|
||||
|
||||
// Unpack and print MIB-SL
|
||||
srslte_mib_sl_t mib_sl;
|
||||
srslte_mib_sl_init(&mib_sl, tm);
|
||||
srslte_mib_sl_unpack(&mib_sl, mib_sl_rx);
|
||||
srslte_mib_sl_printf(stdout, &mib_sl);
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
if (SRSLTE_VERBOSE_ISDEBUG()) {
|
||||
char* filename = (do_equalization) ? "psbch_rx_syms_eq_on.bin" : "psbch_rx_syms_eq_off.bin";
|
||||
printf("Saving PSBCH symbols (%d) to %s\n", psbch.E / psbch.Qm, filename);
|
||||
srslte_vec_save_file(filename, psbch.mod_symbols, psbch.E / psbch.Qm * sizeof(cf_t));
|
||||
}
|
||||
|
||||
srslte_ofdm_tx_free(&ifft);
|
||||
srslte_ofdm_rx_free(&fft);
|
||||
|
||||
srslte_filesource_free(&fsrc);
|
||||
|
||||
srslte_chest_sl_free(&psbch_chest);
|
||||
srslte_psbch_free(&psbch);
|
||||
|
||||
free(sf_buffer);
|
||||
free(equalized_sf_buffer);
|
||||
free(input_buffer);
|
||||
free(output_buffer);
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue