diff --git a/cuhd/lib/cuhd_imp.cpp b/cuhd/lib/cuhd_imp.cpp index 21703bcbd..b3650988f 100644 --- a/cuhd/lib/cuhd_imp.cpp +++ b/cuhd/lib/cuhd_imp.cpp @@ -121,9 +121,8 @@ int cuhd_open(char *args, void **h) { cuhd_handler *handler = new cuhd_handler(); std::string _args = std::string(args); - handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000" + ", num_recv_frames=512"); - -// handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=50000000" + ", num_recv_frames=512"); + handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000"); +// "num_recv_frames=1,num_send_frames=1,recv_frame_size=15360,send_frame_size=15360"); handler->usrp->set_clock_source("internal"); #ifdef HIDE_MESSAGES @@ -134,6 +133,7 @@ int cuhd_open(char *args, void **h) otw = "sc16"; cpu = "fc32"; uhd::stream_args_t stream_args(cpu, otw); + stream_args.args["spp"] = "120"; // Set the property handler->rx_stream = handler->usrp->get_rx_stream(stream_args); handler->tx_stream = handler->usrp->get_tx_stream(stream_args); @@ -310,6 +310,8 @@ int cuhd_send_timed(void *h, double frac_secs) { cuhd_handler* handler = static_cast(h); uhd::tx_metadata_t md; + md.start_of_burst = true; + md.end_of_burst = true; md.has_time_spec = true; md.time_spec = uhd::time_spec_t(secs, frac_secs); if (blocking) { diff --git a/lte/examples/pdsch_ue.c b/lte/examples/pdsch_ue.c index ba4c822d7..9d3feb1df 100644 --- a/lte/examples/pdsch_ue.c +++ b/lte/examples/pdsch_ue.c @@ -325,8 +325,6 @@ int main(int argc, char **argv) { exit(-1); } - ue_dl_set_user_rnti(&ue_dl, prog_args.rnti==SIRNTI?1:prog_args.rnti); - /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ ue_dl_set_rnti(&ue_dl, prog_args.rnti); diff --git a/lte/examples/prach_ue.c b/lte/examples/prach_ue.c index 5dcae6e1b..72f871e44 100644 --- a/lte/examples/prach_ue.c +++ b/lte/examples/prach_ue.c @@ -56,9 +56,6 @@ cell_search_cfg_t cell_detect_config = { float gain_offset = B210_DEFAULT_GAIN_CORREC; -double pss_time_offset = (6/14)*10e-3; -double prach_time_offset = 4*10e-3; //Subframe 4 - /********************************************************************** * Program arguments processing @@ -73,10 +70,6 @@ typedef struct { float uhd_tx_freq; float uhd_tx_freq_offset; float uhd_gain; - int net_port; - char *net_address; - int net_port_signal; - char *net_address_signal; }prog_args_t; void args_default(prog_args_t *args) { @@ -89,10 +82,6 @@ void args_default(prog_args_t *args) { args->uhd_tx_freq = 1922500000.0; args->uhd_tx_freq_offset = 8000000.0; args->uhd_gain = 60.0; - args->net_port = -1; - args->net_address = "127.0.0.1"; - args->net_port_signal = -1; - args->net_address_signal = "127.0.0.1"; } void usage(prog_args_t *args, char *prog) { @@ -149,7 +138,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) { /**********************************************************************/ /* TODO: Do something with the output data */ -uint8_t data[20000], data_packed[20000]; +uint8_t data_rx[20000]; bool go_exit = false; @@ -167,13 +156,16 @@ int cuhd_recv_wrapper_timed(void *h, void *data, uint32_t nsamples, timestamp_t extern float mean_exec_time; -enum receiver_state { DECODE_MIB, SEND_PRACH} state; +enum receiver_state { DECODE_MIB, SEND_PRACH, RECV_RAR} state; #define NOF_PRACH_SEQUENCES 52 ue_dl_t ue_dl; ue_sync_t ue_sync; prach_t prach; +pusch_t pusch; +lte_fft_t fft; +harq_t pusch_harq; cf_t *prach_buffers[NOF_PRACH_SEQUENCES]; int prach_buffer_len; @@ -193,6 +185,120 @@ int generate_prach_sequences(){ return 0; } +typedef enum{ + rar_tpc_n6dB = 0, + rar_tpc_n4dB, + rar_tpc_n2dB, + rar_tpc_0dB, + rar_tpc_2dB, + rar_tpc_4dB, + rar_tpc_6dB, + rar_tpc_8dB, + rar_tpc_n_items, +}rar_tpc_command_t; +static const char tpc_command_text[rar_tpc_n_items][8] = {"-6dB", "-4dB", "-2dB", "0dB", "2dB", "4dB", "6dB", "8dB"}; +typedef enum{ + rar_header_type_bi = 0, + rar_header_type_rapid, + rar_header_type_n_items, +}rar_header_t; +static const char rar_header_text[rar_header_type_n_items][8] = {"BI", "RAPID"}; + +typedef struct { + rar_header_t hdr_type; + bool hopping_flag; + rar_tpc_command_t tpc_command; + bool ul_delay; + bool csi_req; + uint16_t rba; + uint16_t timing_adv_cmd; + uint16_t temp_c_rnti; + uint8_t mcs; + uint8_t RAPID; + uint8_t BI; +}rar_msg_t; + +char *bool_to_string(bool x) { + if (x) { + return "Enabled"; + } else { + return "Disabled"; + } +} + +void rar_msg_fprint(FILE *stream, rar_msg_t *msg) +{ + fprintf(stream, "Header type: %s\n", rar_header_text[msg->hdr_type]); + fprintf(stream, "Hopping flag: %s\n", bool_to_string(msg->hopping_flag)); + fprintf(stream, "TPC command: %s\n", tpc_command_text[msg->tpc_command]); + fprintf(stream, "UL delay: %s\n", bool_to_string(msg->ul_delay)); + fprintf(stream, "CSI required: %s\n", bool_to_string(msg->csi_req)); + fprintf(stream, "RBA: %d\n", msg->rba); + fprintf(stream, "TA: %d\n", msg->timing_adv_cmd); + fprintf(stream, "T-CRNTI: %d\n", msg->temp_c_rnti); + fprintf(stream, "MCS: %d\n", msg->mcs); + fprintf(stream, "RAPID: %d\n", msg->RAPID); + fprintf(stream, "BI: %d\n", msg->BI); +} + +int rar_unpack(uint8_t *buffer, rar_msg_t *msg) +{ + int ret = LIBLTE_ERROR; + uint8_t *ptr = buffer; + + if(buffer != NULL && + msg != NULL) + { + ptr++; + msg->hdr_type = *ptr++; + if(msg->hdr_type == rar_header_type_bi) { + ptr += 2; + msg->BI = bit_unpack(&ptr, 4); + ret = LIBLTE_SUCCESS; + } else if (msg->hdr_type == rar_header_type_rapid) { + msg->RAPID = bit_unpack(&ptr, 6); + ptr++; + + msg->timing_adv_cmd = bit_unpack(&ptr, 11); + msg->hopping_flag = *ptr++; + msg->rba = bit_unpack(&ptr, 10); + msg->mcs = bit_unpack(&ptr, 4); + msg->tpc_command = (rar_tpc_command_t) bit_unpack(&ptr, 3); + msg->ul_delay = *ptr++; + msg->csi_req = *ptr++; + msg->temp_c_rnti = bit_unpack(&ptr, 16); + ret = LIBLTE_SUCCESS; + } + } + + return(ret); +} + +int rar_to_ra_pusch(rar_msg_t *rar, ra_pusch_t *ra, uint32_t nof_prb) { + bzero(ra, sizeof(ra_pusch_t)); + if (!rar->hopping_flag) { + ra->freq_hop_fl = hop_disabled; + } else { + fprintf(stderr, "FIXME: Frequency hopping in RAR not implemented\n"); + ra->freq_hop_fl = 1; + } + uint32_t riv = rar->rba; + // Truncate resource block assignment + uint32_t b = 0; + if (nof_prb <= 44) { + b = (uint32_t) (ceilf(log2((float) nof_prb*(nof_prb+1)/2))); + riv = riv & ((1<<(b+1))-1); + } + ra->type2_alloc.riv = riv; + ra->mcs_idx = rar->mcs; + printf("b: %d, RIV: %d\n", b, riv); + ra_type2_from_riv(riv, &ra->type2_alloc.L_crb, &ra->type2_alloc.RB_start, + nof_prb, nof_prb); + + ra_mcs_from_idx_ul(ra->mcs_idx, ra_nprb_ul(ra, nof_prb), &ra->mcs); + return LIBLTE_SUCCESS; +} + int main(int argc, char **argv) { int ret; lte_cell_t cell; @@ -202,7 +308,14 @@ int main(int argc, char **argv) { int n; uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN]; uint32_t sfn_offset; - + rar_msg_t rar_msg; + ra_pusch_t ra_pusch; + ra_ul_alloc_t prb_alloc; + uint32_t rar_window_start = 0, rar_trials = 0, rar_window_stop = 0; + timestamp_t uhd_time; + timestamp_t next_tx_time; + const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6}; + parse_args(&prog_args, argc, argv); printf("Opening UHD device...\n"); @@ -210,11 +323,12 @@ int main(int argc, char **argv) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } + /* Set receiver gain */ cuhd_set_rx_gain(uhd, prog_args.uhd_gain); cuhd_set_tx_gain(uhd, prog_args.uhd_gain); - cuhd_set_tx_antenna(uhd, "TX/RX"); + //cuhd_set_tx_antenna(uhd, "TX/RX"); /* set receiver frequency */ cuhd_set_rx_freq(uhd, (double) prog_args.uhd_rx_freq); @@ -241,7 +355,7 @@ int main(int argc, char **argv) { cuhd_set_tx_srate(uhd, (double) srate); } else { fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb); - return LIBLTE_ERROR; + exit(-1); } INFO("Stopping UHD and flushing buffer...\r",0); @@ -255,17 +369,64 @@ int main(int argc, char **argv) { if (prach_init(&prach, lte_symbol_sz(cell.nof_prb), 0, 0, false, 1)) { fprintf(stderr, "Error initializing PRACH\n"); - return -1; + exit(-1); } prach_buffer_len = prach.N_seq + prach.N_cp; for(int i=0;i 3) || sfn > rar_window_start) { + gettimeofday(&tdata[1], NULL); + printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync)); + n = ue_dl_decode(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync)); + if (n < 0) { + fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); + } else if (n > 0) { + printf("RAR received %d bits: ", n); + vec_fprint_hex(stdout, data_rx, n); + rar_unpack(data_rx, &rar_msg); + rar_msg_fprint(stdout, &rar_msg); + + pusch_set_rnti(&pusch, rar_msg.temp_c_rnti); + + rar_to_ra_pusch(&rar_msg, &ra_pusch, cell.nof_prb); + ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb); + ra_ul_alloc(&prb_alloc, &ra_pusch, 0, cell.nof_prb); + + printf("Sending ConnectionRequest in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync)); + verbose=VERBOSE_INFO; + if (harq_setup_ul(&pusch_harq, ra_pusch.mcs, 0, (ue_sync_get_sfidx(&ue_sync)+6)%10, &prb_alloc)) { + fprintf(stderr, "Error configuring HARQ process\n"); + exit(-1);; + } + if (pusch_encode(&pusch, &pusch_harq, (uint8_t*) conn_request_msg, sf_symbols)) { + fprintf(stderr, "Error encoding TB\n"); + exit(-1); + } + for (uint32_t i=0;i<2;i++) { + refsignal_drms_pusch_put(&drms, &pusch_cfg, &drms_signal[i*RE_X_RB*pusch_cfg.nof_prb], i, prb_alloc.n_prb[i], sf_symbols); + } + + lte_ifft_run_sf(&fft, sf_symbols, ul_signal); + + ue_sync_get_last_timestamp(&ue_sync, &uhd_time); + timestamp_copy(&next_tx_time, &uhd_time); + timestamp_add(&next_tx_time, 0, 0.006); // send after 6 sub-frames (6 ms) + printf("Send PUSCH sfn: %d. Last frame time = %.6f, send PUSCH time = %.6f\n", + sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time)); + gettimeofday(&tdata[2], NULL); + get_time_interval(tdata); + printf("time exec: %d\n",tdata[0].tv_usec); + cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb), 1, + next_tx_time.full_secs, next_tx_time.frac_secs); + go_exit = 1; + } + if (sfn >= rar_window_stop) { + state = SEND_PRACH; + rar_trials++; + if (rar_trials >= 10) { + go_exit = 1; + } + } + } break; } if (ue_sync_get_sfidx(&ue_sync) == 9) { diff --git a/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h b/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h index e90db5bca..0c20a0576 100644 --- a/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h +++ b/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h @@ -88,6 +88,13 @@ LIBLTE_API void refsignal_ul_free(refsignal_ul_t *q); LIBLTE_API bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg); +LIBLTE_API void refsignal_drms_pusch_put(refsignal_ul_t *q, + refsignal_drms_pusch_cfg_t *cfg, + cf_t *r_pusch, + uint32_t ns_idx, + uint32_t n_prb, + cf_t *sf_symbols); + LIBLTE_API int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t ns, cf_t *r_pusch); LIBLTE_API void refsignal_dmrs_pucch_gen(refsignal_ul_t *q, refsignal_drms_pucch_cfg_t *cfg, uint32_t ns, cf_t *r_pucch); diff --git a/lte/phy/include/liblte/phy/common/phy_common.h b/lte/phy/include/liblte/phy/common/phy_common.h index 3fc45a2ef..4c34eece1 100644 --- a/lte/phy/include/liblte/phy/common/phy_common.h +++ b/lte/phy/include/liblte/phy/common/phy_common.h @@ -52,9 +52,14 @@ typedef enum {CPNORM, CPEXT} lte_cp_t; -#define SIRNTI 0xFFFF -#define PRNTI 0xFFFE -#define MRNTI 0xFFFD + +#define CRNTI_START 0x003D +#define CRNTI_END 0xFFF3 +#define RARNTI_START 0x0001 +#define RARNTI_END 0x003C +#define SIRNTI 0xFFFF +#define PRNTI 0xFFFE +#define MRNTI 0xFFFD #define CELL_ID_UNKNOWN 1000 diff --git a/lte/phy/include/liblte/phy/phch/dci.h b/lte/phy/include/liblte/phy/phch/dci.h index b21fa7d3a..b1dd4d74b 100644 --- a/lte/phy/include/liblte/phy/phch/dci.h +++ b/lte/phy/include/liblte/phy/phch/dci.h @@ -75,8 +75,7 @@ typedef struct LIBLTE_API { * to ra structures ready to be passed to the harq setup function */ LIBLTE_API int dci_msg_to_ra_dl(dci_msg_t *msg, - uint16_t msg_rnti, - uint16_t c_rnti, + uint16_t msg_rnti, lte_cell_t cell, uint32_t cfi, ra_pdsch_t *ra_dl); @@ -102,8 +101,7 @@ LIBLTE_API bool dci_location_isvalid(dci_location_t *c); LIBLTE_API int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, - uint16_t msg_rnti, - uint16_t crnti); + uint16_t msg_rnti); LIBLTE_API void dci_msg_type_fprint(FILE *f, dci_msg_type_t type); diff --git a/lte/phy/include/liblte/phy/ue/ue_dl.h b/lte/phy/include/liblte/phy/ue/ue_dl.h index 71a4d1bba..ebac41afc 100644 --- a/lte/phy/include/liblte/phy/ue/ue_dl.h +++ b/lte/phy/include/liblte/phy/ue/ue_dl.h @@ -75,7 +75,6 @@ typedef struct LIBLTE_API { uint64_t pkts_total; uint64_t nof_pdcch_detected; - uint16_t user_rnti; uint16_t current_rnti; }ue_dl_t; @@ -101,7 +100,4 @@ LIBLTE_API void ue_dl_reset(ue_dl_t *q); LIBLTE_API void ue_dl_set_rnti(ue_dl_t *q, uint16_t rnti); -LIBLTE_API void ue_dl_set_user_rnti(ue_dl_t *q, - uint16_t user_rnti); - #endif \ No newline at end of file diff --git a/lte/phy/lib/ch_estimation/src/refsignal_ul.c b/lte/phy/lib/ch_estimation/src/refsignal_ul.c index a05299f0e..ad10b3969 100644 --- a/lte/phy/lib/ch_estimation/src/refsignal_ul.c +++ b/lte/phy/lib/ch_estimation/src/refsignal_ul.c @@ -243,6 +243,12 @@ bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cf } } +void refsignal_drms_pusch_put(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, cf_t *r_pusch, uint32_t ns_idx, uint32_t n_prb, cf_t *sf_symbols) { + if (ns_idx < 2) { + uint32_t L = (ns_idx+1)*CP_NSYMB(q->cell.cp)-4; + memcpy(&sf_symbols[RE_IDX(q->cell.nof_prb, L, n_prb*RE_X_RB)], r_pusch, cfg->nof_prb*RE_X_RB*sizeof(cf_t)); + } +} /* Generate DRMS for PUSCH signal according to 5.5.2.1 of 36.211 */ int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t ns, cf_t *r_pusch) { diff --git a/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c b/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c index ad062a58f..8706bd21e 100644 --- a/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c +++ b/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c @@ -50,7 +50,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) lte_cell_t cell; refsignal_ul_t refs; refsignal_drms_pusch_cfg_t pusch_cfg; - cf_t *signal; uint32_t sf_idx; if (nrhs != NOF_INPUTS) { @@ -62,7 +61,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Field NCellID not found in UE config\n"); return; } - cell.nof_prb = 100; + if (mexutils_read_uint32_struct(UECFG, "NULRB", &cell.nof_prb)) { + mexErrMsgTxt("Field NCellID not found in UE config\n"); + return; + } cell.cp = CPNORM; cell.nof_ports = 1; @@ -103,7 +105,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } pusch_cfg.nof_prb = mexutils_read_f(p, &prbset); - free(prbset); if (mexutils_read_uint32_struct(PUSCHCFG, "DynCyclicShift", &pusch_cfg.common.cyclic_shift_for_drms)) { pusch_cfg.common.cyclic_shift_for_drms = 0; @@ -125,23 +126,32 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexPrintf("delta_ss: %d, ",pusch_cfg.common.delta_ss); mexPrintf("hopping_method: %d\n, ",pusch_cfg.hopping_method); - signal = vec_malloc(2*RE_X_RB*pusch_cfg.nof_prb*sizeof(cf_t)); + cf_t *signal = vec_malloc(2*RE_X_RB*pusch_cfg.nof_prb*sizeof(cf_t)); if (!signal) { perror("malloc"); return; } + cf_t *sf_symbols = vec_malloc(SF_LEN_RE(cell.nof_prb, cell.cp)*sizeof(cf_t)); + if (!sf_symbols) { + perror("malloc"); + return; + } + bzero(sf_symbols, SF_LEN_RE(cell.nof_prb, cell.cp)*sizeof(cf_t)); for (uint32_t i=0;i<2;i++) { //mexPrintf("Generating DRMS for ns=%d, nof_prb=%d\n", 2*sf_idx+i,pusch_cfg.nof_prb); refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, 2*sf_idx+i, &signal[i*RE_X_RB*pusch_cfg.nof_prb]); } - + for (uint32_t i=0;i<2;i++) { + refsignal_drms_pusch_put(&refs, &pusch_cfg, &signal[i*RE_X_RB*pusch_cfg.nof_prb], i, prbset[0], sf_symbols); + } if (nlhs >= 1) { - mexutils_write_cf(signal, &plhs[0], 2*RE_X_RB*pusch_cfg.nof_prb, 1); + mexutils_write_cf(sf_symbols, &plhs[0], SF_LEN_RE(cell.nof_prb, cell.cp), 1); } refsignal_ul_free(&refs); free(signal); - + free(prbset); + return; } diff --git a/lte/phy/lib/phch/src/dci.c b/lte/phy/lib/phch/src/dci.c index 87e7a6615..d9aa1d145 100644 --- a/lte/phy/lib/phch/src/dci.c +++ b/lte/phy/lib/phch/src/dci.c @@ -41,7 +41,7 @@ #include "liblte/phy/utils/debug.h" -int dci_msg_to_ra_dl(dci_msg_t *msg, uint16_t msg_rnti, uint16_t c_rnti, +int dci_msg_to_ra_dl(dci_msg_t *msg, uint16_t msg_rnti, lte_cell_t cell, uint32_t cfi, ra_pdsch_t *ra_dl) { @@ -56,7 +56,7 @@ int dci_msg_to_ra_dl(dci_msg_t *msg, uint16_t msg_rnti, uint16_t c_rnti, ret = LIBLTE_ERROR; dci_msg_type_t type; - if (dci_msg_get_type(msg, &type, cell.nof_prb, msg_rnti, c_rnti)) { + if (dci_msg_get_type(msg, &type, cell.nof_prb, msg_rnti)) { fprintf(stderr, "Can't get DCI message type\n"); return ret; } @@ -68,7 +68,11 @@ int dci_msg_to_ra_dl(dci_msg_t *msg, uint16_t msg_rnti, uint16_t c_rnti, if (type.type == PDSCH_SCHED) { bzero(ra_dl, sizeof(ra_pdsch_t)); - if (dci_msg_unpack_pdsch(msg, ra_dl, cell.nof_prb, msg_rnti != SIRNTI)) { + bool crc_is_crnti = false; + if (msg_rnti >= CRNTI_START && msg_rnti <= CRNTI_END) { + crc_is_crnti = true; + } + if (dci_msg_unpack_pdsch(msg, ra_dl, cell.nof_prb, crc_is_crnti)) { fprintf(stderr, "Can't unpack PDSCH message\n"); return ret; } @@ -303,7 +307,6 @@ int dci_format0_unpack(dci_msg_t *msg, ra_pusch_t *data, uint32_t nof_prb) { uint32_t riv = bit_unpack(&y, riv_nbits(nof_prb) - n_ul_hop); ra_type2_from_riv(riv, &data->type2_alloc.L_crb, &data->type2_alloc.RB_start, nof_prb, nof_prb); - bit_pack((uint32_t) riv, &y, riv_nbits(nof_prb) - n_ul_hop); data->type2_alloc.riv = riv; /* unpack MCS according to 8.6 of 36.213 */ @@ -599,7 +602,7 @@ int dci_format1As_unpack(dci_msg_t *msg, ra_pdsch_t *data, uint32_t nof_prb, y++; // MSB of TPC is reserved data->type2_alloc.n_prb1a = *y++; // LSB indicates N_prb_1a for TBS } - + uint32_t n_prb; if (crc_is_crnti) { n_prb = ra_nprb_dl(data, nof_prb); @@ -788,9 +791,9 @@ void dci_msg_type_fprint(FILE *f, dci_msg_type_t type) { } int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, - uint16_t msg_rnti, uint16_t crnti) + uint16_t msg_rnti) { - DEBUG("Get message type: nof_bits=%d, msg_rnti=0x%x, crnti=0x%x\n", msg->nof_bits, msg_rnti, crnti); + DEBUG("Get message type: nof_bits=%d, msg_rnti=0x%x\n", msg->nof_bits, msg_rnti); if (msg->nof_bits == dci_format_sizeof(Format0, nof_prb) && !msg->data[0]) { type->type = PUSCH_SCHED; @@ -801,7 +804,7 @@ int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, type->format = Format1; return LIBLTE_SUCCESS; } else if (msg->nof_bits == dci_format_sizeof(Format1A, nof_prb)) { - if (msg_rnti == crnti) { + if (msg_rnti >= CRNTI_START && msg_rnti <= CRNTI_END) { type->type = RA_PROC_PDCCH; type->format = Format1A; } else { diff --git a/lte/phy/lib/phch/src/prach.c b/lte/phy/lib/phch/src/prach.c index 6a0fa51dc..b5779f36a 100644 --- a/lte/phy/lib/phch/src/prach.c +++ b/lte/phy/lib/phch/src/prach.c @@ -384,7 +384,7 @@ int prach_gen(prach_t *p, uint32_t K = DELTA_F/DELTA_F_RA; uint32_t begin = PHI + (K*k_0) + (K/2); - printf("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin); + DEBUG("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin); // Map dft-precoded sequence to ifft bins memset(p->ifft_in, 0, begin*sizeof(cf_t)); memcpy(&p->ifft_in[begin], p->dft_seqs[seq_index], p->N_zc * sizeof(cf_t)); diff --git a/lte/phy/lib/phch/src/ra.c b/lte/phy/lib/phch/src/ra.c index 3a416dacc..590d33791 100644 --- a/lte/phy/lib/phch/src/ra.c +++ b/lte/phy/lib/phch/src/ra.c @@ -524,13 +524,36 @@ int ra_tbs_to_table_idx(uint32_t tbs, uint32_t n_prb) { } void ra_pusch_fprint(FILE *f, ra_pusch_t *ra, uint32_t nof_prb) { - fprintf(f, "Frequency Hopping:\t"); + fprintf(f, " - Resource Allocation Type 2 mode :\t%s\n", + ra->type2_alloc.mode == t2_loc ? "Localized" : "Distributed"); + + fprintf(f, " + Frequency Hopping:\t\t\t"); if (ra->freq_hop_fl == hop_disabled) { - fprintf(f, "No"); + fprintf(f, "No\n"); } else { - fprintf(f, "Yes"); + fprintf(f, "Yes\n"); + } + fprintf(f, " + Resource Indicator Value:\t\t%d\n", ra->type2_alloc.riv); + if (ra->type2_alloc.mode == t2_loc) { + fprintf(f, " + VRB Assignment:\t\t\t%d VRB starting with VRB %d\n", + ra->type2_alloc.L_crb, ra->type2_alloc.RB_start); + } else { + fprintf(f, " + VRB Assignment:\t\t\t%d VRB starting with VRB %d\n", + ra->type2_alloc.L_crb, ra->type2_alloc.RB_start); + fprintf(f, " + VRB gap selection:\t\t\tGap %d\n", + ra->type2_alloc.n_gap == t2_ng1 ? 1 : 2); + fprintf(f, " + VRB gap:\t\t\t\t%d\n", + ra_type2_ngap(nof_prb, ra->type2_alloc.n_gap == t2_ng1)); } + + fprintf(f, " - Number of PRBs:\t\t\t%d\n", ra_nprb_ul(ra, nof_prb)); + fprintf(f, " - Modulation and coding scheme index:\t%d\n", ra->mcs_idx); + fprintf(f, " - Modulation type:\t\t\t%s\n", lte_mod_string(ra->mcs.mod)); + fprintf(f, " - Transport block size:\t\t%d\n", ra->mcs.tbs); + fprintf(f, " - New data indicator:\t\t\t%s\n", ra->ndi ? "Yes" : "No"); + fprintf(f, " - Redundancy version:\t\t\t%d\n", ra->rv_idx); + fprintf(f, " - TPC command for PUCCH:\t\t--\n"); } char *ra_type_string(ra_type_t alloc_type) { diff --git a/lte/phy/lib/phch/test/dci_unpacking.c b/lte/phy/lib/phch/test/dci_unpacking.c index 8688c0ff2..32b69ef77 100644 --- a/lte/phy/lib/phch/test/dci_unpacking.c +++ b/lte/phy/lib/phch/test/dci_unpacking.c @@ -82,7 +82,7 @@ int main(int argc, char **argv) { dci_msg_type_t dci_type; msg.nof_bits = len; - if (dci_msg_get_type(&msg, &dci_type, nof_prb, SIRNTI, 1234)) { + if (dci_msg_get_type(&msg, &dci_type, nof_prb, SIRNTI)) { fprintf(stderr, "Can't obtain DCI message type\n"); exit(-1); } diff --git a/lte/phy/lib/phch/test/pdcch_file_test.c b/lte/phy/lib/phch/test/pdcch_file_test.c index aedd8fb4c..4c5e3defd 100644 --- a/lte/phy/lib/phch/test/pdcch_file_test.c +++ b/lte/phy/lib/phch/test/pdcch_file_test.c @@ -255,7 +255,7 @@ int main(int argc, char **argv) { if (crc_rem == rnti) { dci_msg_type_t type; - if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti, 1234)) { + if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti)) { fprintf(stderr, "Can't get DCI message type\n"); exit(-1); } diff --git a/lte/phy/lib/phch/test/pdsch_file_test.c b/lte/phy/lib/phch/test/pdsch_file_test.c index 538789b4a..5c648ad1a 100644 --- a/lte/phy/lib/phch/test/pdsch_file_test.c +++ b/lte/phy/lib/phch/test/pdsch_file_test.c @@ -279,7 +279,7 @@ int main(int argc, char **argv) { } if (crc_rem == rnti) { - if (dci_msg_to_ra_dl(&dci_msg, rnti, 1234, cell, cfi, &ra_dl)) { + if (dci_msg_to_ra_dl(&dci_msg, rnti, cell, cfi, &ra_dl)) { fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); goto goout; } diff --git a/lte/phy/lib/phch/test/pusch_encode_test_mex.c b/lte/phy/lib/phch/test/pusch_encode_test_mex.c index 70dc9067d..9db626df2 100644 --- a/lte/phy/lib/phch/test/pusch_encode_test_mex.c +++ b/lte/phy/lib/phch/test/pusch_encode_test_mex.c @@ -110,12 +110,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } ra_ul_alloc_t prb_alloc; + bzero(&prb_alloc, sizeof(ra_ul_alloc_t)); prb_alloc.L_prb = mexutils_read_f(p, &prbset); prb_alloc.n_prb[2*sf_idx] = prbset[0]; prb_alloc.n_prb[2*sf_idx+1] = prbset[0]; free(prbset); - mexPrintf("L_prb: %d, n_prb: %d\n", prb_alloc.L_prb, prb_alloc.n_prb[0]); + mexPrintf("L_prb: %d, n_prb: %d\n", prb_alloc.L_prb, prb_alloc.n_prb[2*sf_idx]); uint8_t *trblkin = NULL; mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin); diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index 72a67a191..5013dd228 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -51,7 +51,6 @@ int ue_dl_init(ue_dl_t *q, bzero(q, sizeof(ue_dl_t)); q->cell = cell; - q->user_rnti = 0; q->pkt_errors = 0; q->pkts_total = 0; @@ -143,10 +142,6 @@ void ue_dl_free(ue_dl_t *q) { } } -void ue_dl_set_user_rnti(ue_dl_t *q, uint16_t user_rnti) { - q->user_rnti = user_rnti; -} - void ue_dl_set_rnti(ue_dl_t *q, uint16_t rnti) { q->current_rnti = rnti; pdsch_set_rnti(&q->pdsch, rnti); @@ -239,9 +234,10 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui INFO("Decoded DCI message RNTI: 0x%x\n", crc_rem); if (crc_rem == q->current_rnti) { + found_dci++; q->nof_pdcch_detected++; - if (dci_msg_to_ra_dl(&dci_msg, q->current_rnti, q->user_rnti, q->cell, cfi, &ra_dl)) { + if (dci_msg_to_ra_dl(&dci_msg, q->current_rnti, q->cell, cfi, &ra_dl)) { fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); return LIBLTE_ERROR; } @@ -249,13 +245,11 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui if (q->current_rnti != SIRNTI) { rvidx = ra_dl.rv_idx; } - if (rvidx == 0) { - if (harq_setup_dl(&q->harq_process[0], ra_dl.mcs, rvidx, sf_idx, &ra_dl.prb_alloc)) { - fprintf(stderr, "Error configuring HARQ process\n"); - return LIBLTE_ERROR; - } + if (harq_setup_dl(&q->harq_process[0], ra_dl.mcs, rvidx, sf_idx, &ra_dl.prb_alloc)) { + fprintf(stderr, "Error configuring HARQ process\n"); + return LIBLTE_ERROR; } - if (q->harq_process[0].mcs.mod > 0) { + if (q->harq_process[0].mcs.mod > 0 && q->harq_process[0].mcs.tbs >= 0) { ret = pdsch_decode(&q->pdsch, &q->harq_process[0], q->sf_symbols, q->ce, chest_dl_get_noise_estimate(&q->chest), data); diff --git a/matlab/tests/drms_pusch_test.m b/matlab/tests/drms_pusch_test.m index 067be1ead..506a25533 100644 --- a/matlab/tests/drms_pusch_test.m +++ b/matlab/tests/drms_pusch_test.m @@ -1,4 +1,4 @@ -ueConfig=struct('CyclicPrefixUL','Normal','NTxAnts',1); +ueConfig=struct('CyclicPrefixUL','Normal','NTxAnts',1,'NULRB',25); puschConfig=struct('NLayers',1,'OrthCover','Off'); addpath('../../debug/lte/phy/lib/ch_estimation/test') @@ -6,13 +6,13 @@ addpath('../../debug/lte/phy/lib/ch_estimation/test') Hopping={'Off','Sequence','Group'}; k=1; -for prb=6:6 - for ncell=0:2 - for ns=0:9 - for h=1:3 - for sg=0:29 - for cs=0:7 - for ds=0:7 +for prb=3 + for ncell=0 + for ns=8:9 + for h=1 + for sg=0 + for cs=0 + for ds=0 ueConfig.NCellID=ncell; ueConfig.NSubframe=ns; @@ -24,9 +24,13 @@ for prb=6:6 puschConfig.DynCyclicShift=ds; [mat, info]=ltePUSCHDRS(ueConfig,puschConfig); - lib=liblte_refsignal_pusch(ueConfig,puschConfig); + ind=ltePUSCHDRSIndices(ueConfig, puschConfig); + subframe_mat = lteULResourceGrid(ueConfig); + subframe_mat(ind)=mat; + + subframe_lib=liblte_refsignal_pusch(ueConfig,puschConfig); - error(k)=mean(abs(mat-lib)); + error(k)=mean(abs(subframe_mat(:)-subframe_lib(:))); disp(error(k)) if (error(k) > 10^-3) k=1; @@ -42,7 +46,7 @@ end plot(error); disp(info) -disp(length(mat)) -n=1:length(mat); -plot(n,real(mat(n)),n,real(lib(n))) +disp(length(subframe_mat)) +n=1:length(subframe_mat(:)); +plot(n,real(subframe_mat(:)),n,real(subframe_lib(:))) diff --git a/matlab/tests/pusch_test.m b/matlab/tests/pusch_test.m index 0468815d9..9c2bce604 100644 --- a/matlab/tests/pusch_test.m +++ b/matlab/tests/pusch_test.m @@ -1,14 +1,20 @@ clear -ueConfig=struct('NCellID',3,'NULRB',25,'NSubframe',0,'RNTI',1,'CyclicPrefixUL','Normal','NTxAnts',1); -puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[0 1]','Modulation','QPSK','RV',0,'Shortened',0); +ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1); +puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[0 1 2]','Modulation','QPSK','RV',0,'Shortened',0); addpath('../../debug/lte/phy/lib/phch/test') - TBs=0:13:211; - cqilen=[0, 8, 17]; - mods={'QPSK','16QAM','64QAM'}; - rvs=0; - betas=0:3:11; +% TBs=0:13:211; +% cqilen=[0, 8, 17]; +% mods={'QPSK','16QAM','64QAM'}; +% rvs=0; +% betas=0:3:11; + +TBs=56; +cqilen=0; +mods={'QPSK'}; +rvs=0; +betas=0; for i=1:length(TBs) for m=1:length(mods)