mirror of https://github.com/PentHertz/srsLTE.git
PRACH example successfully transmitting RA and receiving RAR
This commit is contained in:
parent
71fc73c85f
commit
d5a0be5e92
|
@ -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<cuhd_handler*>(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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,6 +308,13 @@ 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);
|
||||
|
||||
|
@ -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,18 +369,65 @@ 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<NOF_PRACH_SEQUENCES;i++){
|
||||
prach_buffers[i] = (cf_t*)malloc(prach_buffer_len*sizeof(cf_t));
|
||||
if(!prach_buffers[i]) {
|
||||
perror("maloc");
|
||||
return -1;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
generate_prach_sequences();
|
||||
|
||||
refsignal_ul_t drms;
|
||||
refsignal_drms_pusch_cfg_t pusch_cfg;
|
||||
pusch_cfg.nof_prb = 3;
|
||||
bzero(&pusch_cfg, sizeof(refsignal_drms_pusch_cfg_t));
|
||||
if (refsignal_ul_init(&drms, cell)) {
|
||||
fprintf(stderr, "Error initiating refsignal_ul\n");
|
||||
exit(-1);
|
||||
}
|
||||
cf_t *drms_signal = vec_malloc(2*RE_X_RB*pusch_cfg.nof_prb*sizeof(cf_t));
|
||||
if (!drms_signal) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
for (uint32_t i=0;i<2;i++) {
|
||||
refsignal_dmrs_pusch_gen(&drms, &pusch_cfg, 2*4+i, &drms_signal[i*RE_X_RB*pusch_cfg.nof_prb]);
|
||||
}
|
||||
|
||||
if (pusch_init(&pusch, cell)) {
|
||||
fprintf(stderr, "Error initiating PUSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (harq_init(&pusch_harq, cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (lte_ifft_init(&fft, cell.cp, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initiating SC-FDMA modulator\n");
|
||||
exit(-1);
|
||||
}
|
||||
lte_fft_set_freq_shift(&fft, 0.5);
|
||||
|
||||
cf_t *ul_signal = vec_malloc(sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
|
||||
if (!ul_signal) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
bzero(ul_signal, sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
cf_t *sf_symbols = vec_malloc(sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
|
||||
if (!sf_symbols) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
bzero(sf_symbols, sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
state = DECODE_MIB;
|
||||
if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper_timed, uhd)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
|
@ -278,11 +439,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);
|
||||
|
||||
/* Initialize subframe counter */
|
||||
sf_cnt = 0;
|
||||
|
||||
|
@ -291,9 +447,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
cuhd_start_rx_stream(uhd);
|
||||
|
||||
timestamp_t uhd_time;
|
||||
timestamp_t next_frame_time;
|
||||
timestamp_t next_prach_time;
|
||||
struct timeval tdata[3];
|
||||
|
||||
/* Main loop */
|
||||
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
|
||||
|
@ -324,17 +478,79 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
case SEND_PRACH:
|
||||
|
||||
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
|
||||
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
|
||||
timestamp_init(&next_frame_time, uhd_time.full_secs, uhd_time.frac_secs);
|
||||
printf("Last frame time = %.6f\n", timestamp_real(&next_frame_time));
|
||||
|
||||
//Tx PRACH every 10 lte dl frames
|
||||
printf("TX PRACH\n");
|
||||
timestamp_copy(&next_prach_time, &next_frame_time);
|
||||
timestamp_add(&next_prach_time, 0, prach_time_offset);
|
||||
cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len, 0,
|
||||
next_prach_time.full_secs, next_prach_time.frac_secs);
|
||||
timestamp_copy(&next_tx_time, &uhd_time);
|
||||
timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms)
|
||||
printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n",
|
||||
sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time));
|
||||
cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len, 1,
|
||||
next_tx_time.full_secs, next_tx_time.frac_secs);
|
||||
|
||||
uint16_t ra_rnti = 2;
|
||||
ue_dl_set_rnti(&ue_dl, ra_rnti);
|
||||
rar_window_start = sfn+1;
|
||||
rar_window_stop = sfn+3;
|
||||
state = RECV_RAR;
|
||||
}
|
||||
break;
|
||||
case RECV_RAR:
|
||||
if ((sfn == rar_window_start && ue_sync_get_sfidx(&ue_sync) > 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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -52,6 +52,11 @@
|
|||
|
||||
typedef enum {CPNORM, CPEXT} lte_cp_t;
|
||||
|
||||
|
||||
#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
|
||||
|
|
|
@ -76,7 +76,6 @@ typedef struct LIBLTE_API {
|
|||
*/
|
||||
LIBLTE_API int dci_msg_to_ra_dl(dci_msg_t *msg,
|
||||
uint16_t msg_rnti,
|
||||
uint16_t c_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);
|
||||
|
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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,22 +126,31 @@ 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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 (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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
error(k)=mean(abs(mat-lib));
|
||||
subframe_lib=liblte_refsignal_pusch(ueConfig,puschConfig);
|
||||
|
||||
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(:)))
|
||||
|
||||
|
|
|
@ -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'};
|
||||
% 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:3:11;
|
||||
betas=0;
|
||||
|
||||
for i=1:length(TBs)
|
||||
for m=1:length(mods)
|
||||
|
|
Loading…
Reference in New Issue