1.程序使用
-g:设置接收端信息增益值;
-o:offset frequency correction (in Hz) for input file,输入文件的频率偏移校准
频率偏移:调频信号偏离载波频率的幅度。为了兼顾接收机的分辨度和节约频谱资源,往往 需要选取一个调制指数来确定原始信号和频率偏移之间的关系。
-O:offset samples for input file,输入文件的采样率偏移
-p:nof_prb for input file,number of PRBs(Physical Resource Block,物理资源块)
-P:nof_ports for input file,可能是设置物理层相关信息,默认是0
-r:RNTI in Hex,UE的标识
-l:n_id_ncell,发射段id
-R:Is R14 cell,bool类型
2.部分变量
srsran_nbiot_ue_dl_t定义
typedef struct SRSRAN_API {
srsran_npdcch_t npdcch;//承载MIB
srsran_npdsch_t npdsch;//承载SIB
srsran_ofdm_t fft;
srsran_chest_dl_nbiot_t chest;
srsran_cfo_t sfo_correct;
srsran_softbuffer_rx_t softbuffer;
srsran_nbiot_cell_t cell;
srsran_mib_nb_t mib;
bool mib_set;
int nof_re; // Number of RE per subframe
cf_t* sf_symbols; // this buffer holds the symbols of the current subframe
cf_t* sf_buffer; // this buffer holds multiple subframes
cf_t* ce[SRSRAN_MAX_PORTS];
cf_t* ce_buffer[SRSRAN_MAX_PORTS];
float* llr; // Buffer to hold soft-bits for later combining repetitions
uint32_t pkt_errors;
uint32_t pkts_total;
uint32_t pkts_ok;
uint32_t nof_detected;
uint32_t bits_total;
// DL configuration for "normal" transmissions
bool has_dl_grant;
srsran_npdsch_cfg_t npdsch_cfg;
// DL configuration for SIB1 transmissions
uint32_t sib1_sfn[4 * SIB1_NB_MAX_REP]; // there are 4 SIB1 TTIs in each hyper frame
srsran_nbiot_si_params_t si_params[SRSRAN_NBIOT_SI_TYPE_NITEMS];
bool si_tti[10240]; // We trade memory consumption for speed
uint16_t current_rnti;
uint32_t last_n_cce;
srsran_dci_location_t last_location;
float sample_offset;
} srsran_nbiot_ue_dl_t;
srsran_nbiot_ue_dl_t ue_dl;//主要变量
srsran_npdsch_t定义如下:
typedef struct SRSRAN_API {
srsran_nbiot_cell_t cell;
uint32_t max_re;
bool rnti_is_set;
uint16_t rnti;
// buffers
uint8_t data[SRSRAN_NPDSCH_MAX_TBS_CRC];
uint8_t data_enc[SRSRAN_NPDSCH_MAX_TBS_ENC];
float rm_f[SRSRAN_NPDSCH_MAX_TBS_ENC];
cf_t* ce[SRSRAN_MAX_PORTS];
cf_t* symbols[SRSRAN_MAX_PORTS];
cf_t* sib_symbols[SRSRAN_MAX_PORTS]; // extra buffer for SIB1 symbols as they may be interleaved with other NPDSCH
cf_t* tx_syms[SRSRAN_MAX_PORTS]; // pointer to either symbols or sib1_symbols
cf_t* x[SRSRAN_MAX_PORTS];
cf_t* d;
float* llr;
uint8_t* temp;
uint8_t* rm_b;
// tx & rx objects
srsran_modem_table_t mod;
srsran_viterbi_t decoder;
srsran_sequence_t seq[SRSRAN_NPDSCH_NUM_SEQ];
srsran_crc_t crc;
srsran_convcoder_t encoder;
} srsran_npdsch_t;
srsran_npdcch_t定义:
typedef struct SRSRAN_API {
srsran_nbiot_cell_t cell;
uint32_t nof_cce;
uint32_t ncce_bits;
uint32_t max_bits;
uint32_t i_n_start; /// start of the first OFDM symbol (signalled through NB-SIB1)
uint32_t nof_nbiot_refs; /// number of NRS symbols per OFDM symbol
uint32_t nof_lte_refs; /// number of CRS symbols per OFDM symbol
uint32_t num_decoded_symbols;
/* buffers */
cf_t* ce[SRSRAN_MAX_PORTS];
cf_t* symbols[SRSRAN_MAX_PORTS];
cf_t* x[SRSRAN_MAX_PORTS];
cf_t* d;
uint8_t* e;
float rm_f[3 * (SRSRAN_DCI_MAX_BITS + 16)];
float* llr[2]; // Two layers of LLRs for Format0 and Format1 NPDCCH
/* tx & rx objects */
srsran_modem_table_t mod;
srsran_sequence_t seq[SRSRAN_NOF_SF_X_FRAME];
srsran_viterbi_t decoder;
srsran_crc_t crc;
} srsran_npdcch_t;
信号数目的问题:
计算Channel Response - Magnitude(信道响应度)代码(计算相关系数同):
int numpoints = SRSRAN_NRE * 2;
bzero(tmp_plot2, sizeof(float) * numpoints);
int g = (numpoints - SRSRAN_NRE) / 2;
for (int i = 0; i < 12 * ue_dl.cell.base.nof_prb; i++) {
tmp_plot2[g + i] = 20 * log10(cabsf(ue_dl.ce[0][i]));
if (isinf(tmp_plot2[g + i])) {
tmp_plot2[g + i] = -80;
}
}
plot_real_setNewData(&pce, tmp_plot2, numpoints);//Channel Response - Magnitude展示图窗
星座图打印函数:
if (ue_dl.npdsch_cfg.nbits.nof_re) {
// plot NPDSCH
plot_scatter_setNewData(&constellation_plot, ue_dl.npdsch.d, ue_dl.npdsch_cfg.nbits.nof_re);
//for(int i=0;i<sizeof(ue_dl.npdsch.))
//printf("test num:%d\n",ue_dl.npdsch_cfg.nbits.nof_re);
/*
struct timespec timestamp;
clock_gettime(CLOCK_REALTIME,×tamp);
for(int i=0;i<ue_dl.npdsch_cfg.nbits.nof_re;i++){
printf("%.12f:%f+%fi\n",timestamp.tv_sec+timestamp.tv_nsec*1e-9,
creal(ue_dl.npdsch.d[i]),cimag(ue_dl.npdsch.d[i]));
}
printf("\n");*///打印星座图
} else if (ue_dl.npdcch.num_decoded_symbols) {
// plot NPDCCH
plot_scatter_setNewData(&constellation_plot, ue_dl.npdcch.d, ue_dl.npdcch.num_decoded_symbols);
//printf("test:ue_dl.npdcch.num_decoded_symbols\n");
}
srsran_ue_mib_nbiot_t的定义:
typedef struct SRSRAN_API {
srsran_sync_nbiot_t sfind;
cf_t* sf_symbols;
cf_t* ce[SRSRAN_MAX_PORTS];
srsran_ofdm_t fft;
srsran_chest_dl_nbiot_t chest;
srsran_npbch_t npbch;//承载MIB信息
uint8_t last_bch_payload[SRSRAN_MIB_NB_LEN];
uint32_t nof_tx_ports;
uint32_t nof_rx_antennas;
uint32_t sfn_offset;
uint32_t frame_cnt;
} srsran_ue_mib_nbiot_t;
prog_args来源
prog_args的信息为接收端自己的信息,n_cell_id为接收端的id
parse_args(&prog_args, argc, argv);
ue_mib用于解码MIB,type为srsran_ue_mib_nbiot_t
srsran_ue_mib_nbiot_t的定义如下:
typedef struct SRSRAN_API {
srsran_sync_nbiot_t sfind;
cf_t* sf_symbols;
cf_t* ce[SRSRAN_MAX_PORTS];
srsran_ofdm_t fft;
srsran_chest_dl_nbiot_t chest;
srsran_npbch_t npbch;//用于承载MIB
uint8_t last_bch_payload[SRSRAN_MIB_NB_LEN];
uint32_t nof_tx_ports;
uint32_t nof_rx_antennas;
uint32_t sfn_offset;
uint32_t frame_cnt;
} srsran_ue_mib_nbiot_t;
//注明:cf_t 是Complex float类型
srsran_npdch_t定义如下:
typedef struct SRSRAN_API {
srsran_nbiot_cell_t cell;
uint32_t frame_idx;
uint32_t nof_symbols;
// buffers
cf_t* ce[SRSRAN_MAX_PORTS];
cf_t* symbols[SRSRAN_MAX_PORTS];
cf_t* x[SRSRAN_MAX_PORTS];
cf_t* d;
float* llr;
float* temp;
float rm_f[SRSRAN_MIB_NB_ENC_LEN];
uint8_t* rm_b;
uint8_t data[SRSRAN_MIB_NB_CRC_LEN];
uint8_t data_enc[SRSRAN_MIB_NB_ENC_LEN];
srsran_nbiot_mode_t op_mode;
// tx & rx objects
srsran_modem_table_t mod;
srsran_sequence_t seq;
srsran_sequence_t seq_r14[SRSRAN_NPBCH_NUM_BLOCKS];
srsran_viterbi_t decoder;
srsran_crc_t crc;
srsran_convcoder_t encoder;
bool search_all_ports;
} srsran_npbch_t;
srsran_sync_nbiot定义如下:
srsran_ofdm_t定义如下:
typedef struct SRSRAN_API {
srsran_ofdm_cfg_t cfg;
srsran_dft_plan_t fft_plan;
srsran_dft_plan_t fft_plan_sf[2];
uint32_t max_prb;
uint32_t nof_symbols;
uint32_t nof_guards;
uint32_t nof_re;
uint32_t slot_sz;
uint32_t sf_sz;
cf_t* tmp; // for removing zero padding
bool mbsfn_subframe;
uint32_t mbsfn_guard_len;
uint32_t nof_symbols_mbsfn;
uint8_t non_mbsfn_region;
uint32_t window_offset_n;
cf_t* shift_buffer;
cf_t* window_offset_buffer;
cf_t phase_compensation[SRSRAN_MAX_NSYMB * SRSRAN_NOF_SLOTS_PER_SF];
srsran_cfr_t tx_cfr; ///< Tx CFR object
} srsran_ofdm_t;
srsran_chest_dl_nbiot_t的定义如下:
typedef struct {
srsran_nbiot_cell_t cell;
srsran_refsignal_dl_nbiot_t nrs_signal;
cf_t* pilot_estimates;
cf_t* pilot_estimates_average;
cf_t* pilot_recv_signal;
cf_t* tmp_noise;
uint32_t smooth_filter_len;
float smooth_filter[SRSRAN_CHEST_MAX_SMOOTH_FIL_LEN];
srsran_interp_linsrsran_vec_t srsran_interp_linvec;
srsran_interp_lin_t srsran_interp_lin;
float rssi[SRSRAN_MAX_PORTS];
float rsrp[SRSRAN_MAX_PORTS];
float noise_estimate[SRSRAN_MAX_PORTS];
srsran_chest_dl_noise_alg_t noise_alg;
} srsran_chest_dl_nbiot_t;
3.部分函数
信号接受入口
int main((int argc, char** argv){
....
// Set initial CFO for ue_sync
srsran_ue_sync_nbiot_set_cfo(&ue_sync, cfo);
srsran_npbch_decode_reset(&ue_mib.npbch);
INFO("\nEntering main loop...");
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
ret = srsran_ue_sync_nbiot_zerocopy_multi(&ue_sync, buff_ptrs);
...
//printf("state:%d,decode mib:%d,decode sib:%d,decode npdsch:%d\n",state,DECODE_MIB,DECODE_SIB,DECODE_NPDSCH);
/*state:未收到信号或者异常为0,
* 正常收到信号为1,
*DECODE MIB=0;
*DECODE SIB=1;
*DECODE NPDSCH=2;
*/
// srsran_ue_sync_nbiot_zerocopy_multi() returns 1 if successfully read 1 aligned subframe
if (ret == 1) {
switch (state) {
...
case DECODE_SIB:
if (!have_sib1) {
//printf("test run?\n");
/*
*have_sib1:false下表示未收到信号,受到信号后更新为true
*/
int dec_ret = srsran_nbiot_ue_dl_decode_npdsch(&ue_dl,
&buff_ptrs[0][prog_args.time_offset],
rx_tb,
system_frame_number,
srsran_ue_sync_nbiot_get_sfidx(&ue_sync),
SRSRAN_SIRNTI);
if (dec_ret == SRSRAN_SUCCESS) {
printf("SIB1 received\n");
srsran_sys_info_block_type_1_nb_t sib = {};
srsran_npdsch_sib1_unpack(rx_tb, &sib);
hyper_frame_number = sib.hyper_sfn;
have_sib1 = true;
...
}else if (!have_sib2 && !srsran_nbiot_ue_dl_is_sib1_sf(
&ue_dl, system_frame_number, srsran_ue_sync_nbiot_get_sfidx(&ue_sync))) {
//printf("test run?\n");
// SIB2 is transmitted over multiple subframes, so this needs to be called more than once ..
int dec_ret = srsran_nbiot_ue_dl_decode_npdsch(&ue_dl,
&buff_ptrs[0][prog_args.time_offset],
rx_tb,
system_frame_number,
srsran_ue_sync_nbiot_get_sfidx(&ue_sync),
SRSRAN_SIRNTI);
...
}
}
GUI部分获得星座图代码
//printf("test num:%d\n",ue_dl.npdsch_cfg.nbits.nof_re);
/*
struct timespec timestamp;
clock_gettime(CLOCK_REALTIME,×tamp);
for(int i=0;i<ue_dl.npdsch_cfg.nbits.nof_re;i++){
printf("%.12f:%f+%fi\n",timestamp.tv_sec+timestamp.tv_nsec*1e-9,
creal(ue_dl.npdsch.d[i]),cimag(ue_dl.npdsch.d[i]));
}
printf("\n");*///打印星座图