|
|
|
@ -69,7 +69,8 @@ typedef struct {
|
|
|
|
|
float uhd_rx_freq;
|
|
|
|
|
float uhd_tx_freq;
|
|
|
|
|
float uhd_tx_freq_offset;
|
|
|
|
|
float uhd_gain;
|
|
|
|
|
float uhd_tx_gain;
|
|
|
|
|
float uhd_rx_gain;
|
|
|
|
|
}prog_args_t;
|
|
|
|
|
|
|
|
|
|
void args_default(prog_args_t *args) {
|
|
|
|
@ -81,13 +82,15 @@ void args_default(prog_args_t *args) {
|
|
|
|
|
args->uhd_rx_freq = 2112500000.0;
|
|
|
|
|
args->uhd_tx_freq = 1922500000.0;
|
|
|
|
|
args->uhd_tx_freq_offset = 8000000.0;
|
|
|
|
|
args->uhd_gain = 60.0;
|
|
|
|
|
args->uhd_tx_gain = 60.0;
|
|
|
|
|
args->uhd_rx_gain = 60.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void usage(prog_args_t *args, char *prog) {
|
|
|
|
|
printf("Usage: %s [agfFrlnv]\n", prog);
|
|
|
|
|
printf("\t-a UHD args [Default %s]\n", args->uhd_args);
|
|
|
|
|
printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_gain);
|
|
|
|
|
printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_rx_gain);
|
|
|
|
|
printf("\t-G UHD TX/RX gain [Default %.2f dB]\n", args->uhd_tx_gain);
|
|
|
|
|
printf("\t-f UHD RX freq [Default %.1f MHz]\n", args->uhd_rx_freq/1000000);
|
|
|
|
|
printf("\t-F UHD TX freq [Default %.1f MHz]\n", args->uhd_tx_freq/1000000);
|
|
|
|
|
printf("\t-r RNTI [Default 0x%x]\n",args->rnti);
|
|
|
|
@ -99,13 +102,16 @@ void usage(prog_args_t *args, char *prog) {
|
|
|
|
|
void parse_args(prog_args_t *args, int argc, char **argv) {
|
|
|
|
|
int opt;
|
|
|
|
|
args_default(args);
|
|
|
|
|
while ((opt = getopt(argc, argv, "agfFrlnv")) != -1) {
|
|
|
|
|
while ((opt = getopt(argc, argv, "agGfFrlnv")) != -1) {
|
|
|
|
|
switch (opt) {
|
|
|
|
|
case 'a':
|
|
|
|
|
args->uhd_args = argv[optind];
|
|
|
|
|
break;
|
|
|
|
|
case 'g':
|
|
|
|
|
args->uhd_gain = atof(argv[optind]);
|
|
|
|
|
args->uhd_rx_gain = atof(argv[optind]);
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
args->uhd_tx_gain = atof(argv[optind]);
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
args->uhd_rx_freq = atof(argv[optind]);
|
|
|
|
@ -175,7 +181,7 @@ cf_t *sf_buffer = NULL;
|
|
|
|
|
|
|
|
|
|
int generate_prach_sequences(){
|
|
|
|
|
for(int i=0;i<NOF_PRACH_SEQUENCES;i++){
|
|
|
|
|
if(prach_gen(&prach, i, 2, prach_buffers[i])){
|
|
|
|
|
if(prach_gen(&prach, i, 0, prach_buffers[i])){
|
|
|
|
|
fprintf(stderr, "Error generating prach sequence\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
@ -272,6 +278,8 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg)
|
|
|
|
|
return(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define kk
|
|
|
|
|
#define use_usrp
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
int ret;
|
|
|
|
@ -288,10 +296,11 @@ int main(int argc, char **argv) {
|
|
|
|
|
timestamp_t uhd_time;
|
|
|
|
|
timestamp_t next_tx_time;
|
|
|
|
|
const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6, 0x00, 0x00, 0x00};
|
|
|
|
|
uint8_t data[100];
|
|
|
|
|
uint8_t data[500];
|
|
|
|
|
|
|
|
|
|
parse_args(&prog_args, argc, argv);
|
|
|
|
|
|
|
|
|
|
#ifdef use_usrp
|
|
|
|
|
printf("Opening UHD device...\n");
|
|
|
|
|
if (cuhd_open(prog_args.uhd_args, &uhd)) {
|
|
|
|
|
fprintf(stderr, "Error opening uhd\n");
|
|
|
|
@ -299,10 +308,10 @@ int main(int argc, char **argv) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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");
|
|
|
|
|
float x = cuhd_set_rx_gain(uhd, prog_args.uhd_rx_gain);
|
|
|
|
|
printf("Set RX gain to %.1f dB\n", x);
|
|
|
|
|
x = cuhd_set_tx_gain(uhd, prog_args.uhd_tx_gain);
|
|
|
|
|
printf("Set TX gain to %.1f dB\n", x);
|
|
|
|
|
|
|
|
|
|
/* set receiver frequency */
|
|
|
|
|
cuhd_set_rx_freq(uhd, (double) prog_args.uhd_rx_freq);
|
|
|
|
@ -312,6 +321,9 @@ int main(int argc, char **argv) {
|
|
|
|
|
cuhd_set_tx_freq_offset(uhd, prog_args.uhd_tx_freq, prog_args.uhd_tx_freq_offset);
|
|
|
|
|
printf("Tunning TX receiver to %.3f MHz\n", (double ) prog_args.uhd_tx_freq/1000000);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef kk
|
|
|
|
|
ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
fprintf(stderr, "Error searching for cell\n");
|
|
|
|
@ -320,7 +332,17 @@ int main(int argc, char **argv) {
|
|
|
|
|
printf("Cell not found\n");
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
cell.id = 1;
|
|
|
|
|
cell.nof_ports = 1;
|
|
|
|
|
cell.nof_prb = 25;
|
|
|
|
|
cell.cp = CPNORM;
|
|
|
|
|
cell.phich_length = PHICH_NORM;
|
|
|
|
|
cell.phich_resources = R_1;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef use_usrp
|
|
|
|
|
|
|
|
|
|
/* set sampling frequency */
|
|
|
|
|
int srate = lte_sampling_freq_hz(cell.nof_prb);
|
|
|
|
|
if (srate != -1) {
|
|
|
|
@ -334,6 +356,8 @@ int main(int argc, char **argv) {
|
|
|
|
|
INFO("Stopping UHD and flushing buffer...\r",0);
|
|
|
|
|
cuhd_stop_rx_stream(uhd);
|
|
|
|
|
cuhd_flush_buffer(uhd);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (ue_mib_init(&ue_mib, cell)) {
|
|
|
|
|
fprintf(stderr, "Error initaiting UE MIB decoder\n");
|
|
|
|
@ -364,6 +388,12 @@ int main(int argc, char **argv) {
|
|
|
|
|
refsignal_drms_pusch_cfg_t drms_cfg;
|
|
|
|
|
bzero(&drms_cfg, sizeof(refsignal_drms_pusch_cfg_t));
|
|
|
|
|
drms_cfg.beta_pusch = 1.0;
|
|
|
|
|
drms_cfg.group_hopping_en = false;
|
|
|
|
|
drms_cfg.sequence_hopping_en = false;
|
|
|
|
|
drms_cfg.common.delta_ss = 0;
|
|
|
|
|
drms_cfg.common.cyclic_shift = 0;
|
|
|
|
|
drms_cfg.common.cyclic_shift_for_drms = 0;
|
|
|
|
|
drms_cfg.common.en_drms_2 = false;
|
|
|
|
|
ue_ul_set_pusch_cfg(&ue_ul, &drms_cfg, &hop_cfg);
|
|
|
|
|
|
|
|
|
|
cf_t *ul_signal = vec_malloc(sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb));
|
|
|
|
@ -373,159 +403,228 @@ int main(int argc, char **argv) {
|
|
|
|
|
}
|
|
|
|
|
bzero(ul_signal, 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");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ue_dl_init(&ue_dl, cell)) {
|
|
|
|
|
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize subframe counter */
|
|
|
|
|
sf_cnt = 0;
|
|
|
|
|
|
|
|
|
|
// Register Ctrl+C handler
|
|
|
|
|
signal(SIGINT, sig_int_handler);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef use_usrp
|
|
|
|
|
if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper_timed, uhd)) {
|
|
|
|
|
fprintf(stderr, "Error initiating ue_sync\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cuhd_start_rx_stream(uhd);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct timeval tdata[3];
|
|
|
|
|
uint16_t ra_rnti;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef kk
|
|
|
|
|
// Register Ctrl+C handler
|
|
|
|
|
signal(SIGINT, sig_int_handler);
|
|
|
|
|
state = DECODE_MIB;
|
|
|
|
|
#else
|
|
|
|
|
state = RECV_RAR;
|
|
|
|
|
#endif
|
|
|
|
|
/* Main loop */
|
|
|
|
|
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
|
|
|
|
|
|
|
|
|
|
#ifdef kk
|
|
|
|
|
ret = ue_sync_get_buffer(&ue_sync, &sf_buffer);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
fprintf(stderr, "Error calling ue_sync_work()\n");
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
ret = 1;
|
|
|
|
|
timestamp_t rx_time, tx_time;
|
|
|
|
|
cf_t dummy[4];
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
|
|
|
|
|
if (ret == 1) {
|
|
|
|
|
switch (state) {
|
|
|
|
|
case DECODE_MIB:
|
|
|
|
|
if (ue_sync_get_sfidx(&ue_sync) == 0) {
|
|
|
|
|
pbch_decode_reset(&ue_mib.pbch);
|
|
|
|
|
n = ue_mib_decode(&ue_mib, sf_buffer, bch_payload_unpacked, NULL, &sfn_offset);
|
|
|
|
|
if (n < 0) {
|
|
|
|
|
fprintf(stderr, "Error decoding UE MIB\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
} else if (n == MIB_FOUND) {
|
|
|
|
|
bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN);
|
|
|
|
|
bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn);
|
|
|
|
|
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
|
|
|
|
|
sfn = (sfn + sfn_offset)%1024;
|
|
|
|
|
state = SEND_PRACH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SEND_PRACH:
|
|
|
|
|
|
|
|
|
|
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
|
|
|
|
|
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
|
|
|
|
|
|
|
|
|
|
cfo_correct(&ue_sync.sfind.cfocorr,
|
|
|
|
|
prach_buffers[7], prach_buffers[7],
|
|
|
|
|
-ue_sync_get_cfo(&ue_sync) / lte_symbol_sz(cell.nof_prb));
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
next_tx_time.full_secs, next_tx_time.frac_secs);
|
|
|
|
|
|
|
|
|
|
ra_rnti = 2;
|
|
|
|
|
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_rnti(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync), ra_rnti);
|
|
|
|
|
if (n < 0) {
|
|
|
|
|
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
|
|
|
|
} else if (n > 0) {
|
|
|
|
|
|
|
|
|
|
gettimeofday(&tdata[2], NULL);
|
|
|
|
|
get_time_interval(tdata);
|
|
|
|
|
printf("time exec DL: %d\n",tdata[0].tv_usec);
|
|
|
|
|
|
|
|
|
|
gettimeofday(&tdata[1], NULL);
|
|
|
|
|
|
|
|
|
|
rar_unpack(data_rx, &rar_msg);
|
|
|
|
|
rar_msg_fprint(stdout, &rar_msg);
|
|
|
|
|
|
|
|
|
|
dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch);
|
|
|
|
|
ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
|
|
|
|
|
if (state != RECV_RAR) {
|
|
|
|
|
/* Run FFT for all subframe data */
|
|
|
|
|
lte_fft_run_sf(&ue_dl.fft, sf_buffer, ue_dl.sf_symbols);
|
|
|
|
|
|
|
|
|
|
ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb);
|
|
|
|
|
|
|
|
|
|
uint32_t ul_sf_idx = (ue_sync_get_sfidx(&ue_sync)+6)%10;
|
|
|
|
|
|
|
|
|
|
//ue_ul_set_cfo(&ue_ul, sync_get_cfo(&ue_sync.strack));
|
|
|
|
|
bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
|
|
|
|
|
n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, rar_msg.temp_c_rnti, ul_signal);
|
|
|
|
|
/* Get channel estimates for each port */
|
|
|
|
|
chest_dl_estimate(&ue_dl.chest, ue_dl.sf_symbols, ue_dl.ce, ue_sync_get_sfidx(&ue_sync));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sf_cnt > 1000) {
|
|
|
|
|
switch (state) {
|
|
|
|
|
case DECODE_MIB:
|
|
|
|
|
if (ue_sync_get_sfidx(&ue_sync) == 0) {
|
|
|
|
|
pbch_decode_reset(&ue_mib.pbch);
|
|
|
|
|
n = ue_mib_decode(&ue_mib, sf_buffer, bch_payload_unpacked, NULL, &sfn_offset);
|
|
|
|
|
if (n < 0) {
|
|
|
|
|
fprintf(stderr, "Error encoding PUSCH\n");
|
|
|
|
|
fprintf(stderr, "Error decoding UE MIB\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
} else if (n == MIB_FOUND) {
|
|
|
|
|
bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN);
|
|
|
|
|
bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn);
|
|
|
|
|
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
|
|
|
|
|
sfn = (sfn + sfn_offset)%1024;
|
|
|
|
|
state = SEND_PRACH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gettimeofday(&tdata[2], NULL);
|
|
|
|
|
get_time_interval(tdata);
|
|
|
|
|
printf("time exec UL: %d\n",tdata[0].tv_usec);
|
|
|
|
|
|
|
|
|
|
gettimeofday(&tdata[1], NULL);
|
|
|
|
|
cuhd_stop_rx_stream(uhd);
|
|
|
|
|
cuhd_flush_buffer(uhd);
|
|
|
|
|
gettimeofday(&tdata[2], NULL);
|
|
|
|
|
get_time_interval(tdata);
|
|
|
|
|
printf("time to stop RX: %d\n",tdata[0].tv_usec);
|
|
|
|
|
|
|
|
|
|
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SEND_PRACH:
|
|
|
|
|
|
|
|
|
|
uint32_t n_ta = lte_N_ta_new_rar(rar_msg.timing_adv_cmd);
|
|
|
|
|
printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta);
|
|
|
|
|
float time_adv_sec = ((float) n_ta)*LTE_TS;
|
|
|
|
|
|
|
|
|
|
vec_sc_prod_cfc(ul_signal, 2, ul_signal, SF_LEN_PRB(cell.nof_prb));
|
|
|
|
|
#ifdef kk
|
|
|
|
|
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
|
|
|
|
|
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
next_tx_time.full_secs, next_tx_time.frac_secs);
|
|
|
|
|
|
|
|
|
|
timestamp_copy(&next_tx_time, &uhd_time);
|
|
|
|
|
timestamp_add(&next_tx_time, 0, 0.006 - time_adv_sec); // send after 6 sub-frames (6 ms)
|
|
|
|
|
printf("Send %d samples PUSCH sfn: %d. Last frame time = %.6f"
|
|
|
|
|
"send PUSCH time = %.6f TA: %.1f us\n",
|
|
|
|
|
SF_LEN_PRB(cell.nof_prb), sfn, timestamp_real(&uhd_time),
|
|
|
|
|
timestamp_real(&next_tx_time), time_adv_sec*1000000);
|
|
|
|
|
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
|
|
|
|
|
next_tx_time.full_secs, next_tx_time.frac_secs);
|
|
|
|
|
|
|
|
|
|
vec_save_file("prach_example_signal", ul_signal, sizeof(cf_t)*7680);
|
|
|
|
|
go_exit = 1;
|
|
|
|
|
ra_rnti = 2;
|
|
|
|
|
rar_window_start = sfn+1;
|
|
|
|
|
rar_window_stop = sfn+3;
|
|
|
|
|
state = RECV_RAR;
|
|
|
|
|
}
|
|
|
|
|
if (sfn >= rar_window_stop) {
|
|
|
|
|
state = SEND_PRACH;
|
|
|
|
|
rar_trials++;
|
|
|
|
|
if (rar_trials >= 4) {
|
|
|
|
|
#else
|
|
|
|
|
cuhd_recv_with_time(uhd, dummy, 4, 1, &rx_time.full_secs, &rx_time.frac_secs);
|
|
|
|
|
|
|
|
|
|
timestamp_copy(&tx_time, &rx_time);
|
|
|
|
|
printf("Transmitting PRACH...\n");
|
|
|
|
|
vec_save_file("prach_tx", prach_buffers[7], prach_buffer_len*sizeof(cf_t));
|
|
|
|
|
while(1) {
|
|
|
|
|
timestamp_add(&tx_time, 0, 0.001); // send every (10 ms)
|
|
|
|
|
cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len,
|
|
|
|
|
tx_time.full_secs, tx_time.frac_secs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
case RECV_RAR:
|
|
|
|
|
#ifdef kk
|
|
|
|
|
|
|
|
|
|
if ((sfn == rar_window_start && ue_sync_get_sfidx(&ue_sync) > 3) || sfn > rar_window_start) {
|
|
|
|
|
printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync));
|
|
|
|
|
n = ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync), ra_rnti);
|
|
|
|
|
if (n < 0) {
|
|
|
|
|
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
|
|
|
|
} else if (n > 0) {
|
|
|
|
|
cuhd_stop_rx_stream(uhd);
|
|
|
|
|
cuhd_flush_buffer(uhd);
|
|
|
|
|
|
|
|
|
|
rar_unpack(data_rx, &rar_msg);
|
|
|
|
|
rar_msg_fprint(stdout, &rar_msg);
|
|
|
|
|
|
|
|
|
|
dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch);
|
|
|
|
|
ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
|
|
|
|
|
|
|
|
|
|
ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb);
|
|
|
|
|
|
|
|
|
|
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
|
|
|
|
|
|
|
|
|
|
bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
|
|
|
|
|
|
|
|
|
|
uint32_t n_ta = lte_N_ta_new_rar(rar_msg.timing_adv_cmd);
|
|
|
|
|
printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta);
|
|
|
|
|
float time_adv_sec = ((float) n_ta+15)/(15000.0*lte_symbol_sz(cell.nof_prb));
|
|
|
|
|
#define N_TX 5
|
|
|
|
|
const uint32_t rv[N_TX]={0,2,3,1,0};
|
|
|
|
|
for (int i=0; i<N_TX;i++) {
|
|
|
|
|
ra_pusch.rv_idx = rv[i];
|
|
|
|
|
uint32_t ul_sf_idx = (ue_sync_get_sfidx(&ue_sync)+6+i*8)%10;
|
|
|
|
|
|
|
|
|
|
n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, rar_msg.temp_c_rnti, ul_signal);
|
|
|
|
|
if (n < 0) {
|
|
|
|
|
fprintf(stderr, "Error encoding PUSCH\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec_sc_prod_cfc(ul_signal, 1.5, ul_signal, SF_LEN_PRB(cell.nof_prb));
|
|
|
|
|
/*
|
|
|
|
|
for (int i=0;i<7680;i++) {
|
|
|
|
|
if (i < 100) {
|
|
|
|
|
ul_signal[i] = 0;
|
|
|
|
|
} else {
|
|
|
|
|
ul_signal[i] = 0.5*cexpf(-I*2*M_PI*0.1*(float) i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
vec_save_file("pusch_tx", ul_signal, sizeof(cf_t)*SF_LEN_PRB(cell.nof_prb));
|
|
|
|
|
|
|
|
|
|
timestamp_copy(&next_tx_time, &uhd_time);
|
|
|
|
|
timestamp_add(&next_tx_time, 0, 0.006 + i*0.008 - time_adv_sec); // send after 6 sub-frames (6 ms)
|
|
|
|
|
printf("Send %d samples PUSCH sfn: %d. RV_idx=%d, Last frame time = %.6f "
|
|
|
|
|
"send PUSCH time = %.6f TA: %.1f us\n",
|
|
|
|
|
SF_LEN_PRB(cell.nof_prb), sfn, ra_pusch.rv_idx,
|
|
|
|
|
timestamp_real(&uhd_time),
|
|
|
|
|
timestamp_real(&next_tx_time), time_adv_sec*1000000);
|
|
|
|
|
|
|
|
|
|
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
|
|
|
|
|
next_tx_time.full_secs, next_tx_time.frac_secs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
go_exit = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (ue_sync_get_sfidx(&ue_sync) == 9) {
|
|
|
|
|
sfn++;
|
|
|
|
|
if (sfn == 1024) {
|
|
|
|
|
sfn = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (sfn >= rar_window_stop) {
|
|
|
|
|
state = SEND_PRACH;
|
|
|
|
|
rar_trials++;
|
|
|
|
|
if (rar_trials >= 1) {
|
|
|
|
|
go_exit = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
ra_pusch.mcs.mod = LTE_QPSK;
|
|
|
|
|
ra_pusch.mcs.tbs = 94;
|
|
|
|
|
ra_pusch.rv_idx = 0;
|
|
|
|
|
ra_pusch.prb_alloc.freq_hopping = 0;
|
|
|
|
|
ra_pusch.prb_alloc.L_prb = 4;
|
|
|
|
|
ra_pusch.prb_alloc.n_prb[0] = 19;
|
|
|
|
|
ra_pusch.prb_alloc.n_prb[1] = 19;
|
|
|
|
|
|
|
|
|
|
uint32_t ul_sf_idx = 4;
|
|
|
|
|
printf("L: %d\n", ra_pusch.prb_alloc.L_prb);
|
|
|
|
|
// ue_ul_set_cfo(&ue_ul, sync_get_cfo(&ue_sync.strack));
|
|
|
|
|
bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs);
|
|
|
|
|
n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, 111, ul_signal);
|
|
|
|
|
if (n < 0) {
|
|
|
|
|
fprintf(stderr, "Error encoding PUSCH\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec_save_file("pusch_tx", ul_signal, SF_LEN_PRB(cell.nof_prb)*sizeof(cf_t));
|
|
|
|
|
|
|
|
|
|
#ifdef use_usrp
|
|
|
|
|
cuhd_recv_with_time(uhd, dummy, 4, 1, &uhd_time.full_secs, &uhd_time.frac_secs);
|
|
|
|
|
timestamp_copy(&next_tx_time, &uhd_time);
|
|
|
|
|
while(1) {
|
|
|
|
|
timestamp_add(&next_tx_time, 0, 0.002); // send every 2 ms
|
|
|
|
|
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
|
|
|
|
|
next_tx_time.full_secs, next_tx_time.frac_secs);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
exit(-1);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (ue_sync_get_sfidx(&ue_sync) == 9) {
|
|
|
|
|
sfn++;
|
|
|
|
|
if (sfn == 1024) {
|
|
|
|
|
sfn = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (ret == 0) {
|
|
|
|
|
printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r",
|
|
|
|
|
sync_get_peak_value(&ue_sync.sfind),
|
|
|
|
|