PRACH example successfully transmitting RA and receiving RAR

This commit is contained in:
ismagom 2015-02-26 18:10:44 +01:00
parent 71fc73c85f
commit d5a0be5e92
19 changed files with 376 additions and 107 deletions

View File

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

View File

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

View File

@ -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<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)) {
@ -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,10 +447,8 @@ 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:
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));
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
ue_sync_get_last_timestamp(&ue_sync, &uhd_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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

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

View File

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

View File

@ -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(:)))

View File

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