Merge remote-tracking branch 'origin/develop-ta' into integration_2022_wk41
This commit is contained in:
@@ -510,7 +510,7 @@ int process_command(char *buf) {
|
|||||||
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
|
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
|
||||||
cmddata->prnt=client_printf;
|
cmddata->prnt=client_printf;
|
||||||
cmddata->debug=telnetparams.telnetdbg;
|
cmddata->debug=telnetparams.telnetdbg;
|
||||||
cmddata->cmdbuff=strdup(cmdb);
|
cmddata->cmdbuff=cmdb ? strdup(cmdb) : NULL;
|
||||||
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
|
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
|
||||||
} else {
|
} else {
|
||||||
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
|
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
|
||||||
@@ -845,33 +845,42 @@ int telnetsrv_autoinit(void) {
|
|||||||
* function at init time. the telnet server is delivered with a set of commands which
|
* function at init time. the telnet server is delivered with a set of commands which
|
||||||
* will be loaded or not depending on the telnet section of the config file
|
* will be loaded or not depending on the telnet section of the config file
|
||||||
*/
|
*/
|
||||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) {
|
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
|
||||||
int i;
|
{
|
||||||
notifiedFIFO_t *afifo=NULL;
|
|
||||||
|
|
||||||
if( modulename == NULL || var == NULL || cmd == NULL) {
|
if( modulename == NULL || var == NULL || cmd == NULL) {
|
||||||
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
|
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
for (i=0; i<TELNET_MAXCMD ; i++) {
|
for (i=0; i<TELNET_MAXCMD ; i++) {
|
||||||
if (telnetparams.CmdParsers[i].var == NULL) {
|
cmdparser_t *CmdParser = &telnetparams.CmdParsers[i];
|
||||||
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
|
if (CmdParser->var == NULL) {
|
||||||
telnetparams.CmdParsers[i].cmd = cmd;
|
strncpy(CmdParser->module, modulename, sizeof(CmdParser->module) - 1);
|
||||||
telnetparams.CmdParsers[i].var = var;
|
CmdParser->cmd = cmd;
|
||||||
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
CmdParser->var = var;
|
||||||
if (afifo == NULL) {
|
|
||||||
afifo = malloc(sizeof(notifiedFIFO_t));
|
|
||||||
initNotifiedFIFO(afifo);
|
|
||||||
}
|
|
||||||
cmd->qptr = afifo;
|
|
||||||
}
|
|
||||||
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
|
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
|
||||||
i,telnetparams.CmdParsers[i].module);
|
i, CmdParser->module);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == TELNET_MAXCMD) {
|
||||||
|
fprintf(stderr, "[TELNETSRV] TELNET_MAXCMD reached, cannot add new module %s\n", modulename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifiedFIFO_t *afifo = NULL;
|
||||||
|
for (int k = 0; cmd[k].cmdfunc != NULL ; k++) {
|
||||||
|
if (cmd[k].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||||
|
if (afifo == NULL) {
|
||||||
|
afifo = malloc(sizeof(notifiedFIFO_t));
|
||||||
|
initNotifiedFIFO(afifo);
|
||||||
|
}
|
||||||
|
cmd[k].qptr = afifo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,12 +58,14 @@ void measurcmd_display_rlcstats(telnet_printfunc_t prnt);
|
|||||||
void measurcmd_display_phycpu(telnet_printfunc_t prnt);
|
void measurcmd_display_phycpu(telnet_printfunc_t prnt);
|
||||||
void measurcmd_display_maccpu(telnet_printfunc_t prnt);
|
void measurcmd_display_maccpu(telnet_printfunc_t prnt);
|
||||||
void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt);
|
void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt);
|
||||||
|
void measurcmd_display_phyta(telnet_printfunc_t prnt);
|
||||||
|
|
||||||
|
|
||||||
static telnet_measurgroupdef_t nrUEmeasurgroups[] = {
|
static telnet_measurgroupdef_t nrUEmeasurgroups[] = {
|
||||||
// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}},
|
// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}},
|
||||||
// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}},
|
// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}},
|
||||||
{"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}},
|
{"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}},
|
||||||
|
{"phyta", GROUP_CPUSTATS, 0, measurcmd_display_phyta, {NULL}},
|
||||||
// {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}},
|
// {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}},
|
||||||
// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}},
|
// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}},
|
||||||
};
|
};
|
||||||
@@ -89,6 +91,17 @@ void measurcmd_display_phycpu(telnet_printfunc_t prnt) {
|
|||||||
PRINT_CPUMEAS_STATE,HDR);
|
PRINT_CPUMEAS_STATE,HDR);
|
||||||
measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t));
|
measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t));
|
||||||
}
|
}
|
||||||
|
void measurcmd_display_phyta(telnet_printfunc_t prnt)
|
||||||
|
{
|
||||||
|
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[0][0];
|
||||||
|
prnt("%s PHY TA stats\n", HDR);
|
||||||
|
prnt("N_TA_offset %d\n", UE->N_TA_offset);
|
||||||
|
for (int i = 0; i < UE->n_connected_gNB; ++i) {
|
||||||
|
NR_UL_TIME_ALIGNMENT_t *ta = &UE->ul_time_alignment[i];
|
||||||
|
prnt("gNB %d TA command %d TA total %d TAG ID %d\n", i, ta->ta_command, ta->ta_total, ta->tag_id);
|
||||||
|
}
|
||||||
|
prnt("timing_advance %d (samples)\n", UE->timing_advance);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
void measurcmd_display_maccpu(telnet_printfunc_t prnt) {
|
void measurcmd_display_maccpu(telnet_printfunc_t prnt) {
|
||||||
eNB_MAC_INST *macvars = RC.mac[eNB_id];
|
eNB_MAC_INST *macvars = RC.mac[eNB_id];
|
||||||
|
|||||||
+3
-2
@@ -865,12 +865,13 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
|
|||||||
cfg->tx_gain[i] = ru->att_tx;
|
cfg->tx_gain[i] = ru->att_tx;
|
||||||
cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
|
cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
|
||||||
cfg->configFilename = rf_config_file;
|
cfg->configFilename = rf_config_file;
|
||||||
LOG_I(PHY, "Channel %d: setting tx_gain offset %.0f, rx_gain offset %.0f, tx_freq %.0f Hz, rx_freq %.0f Hz, tune_offset %.0f Hz\n",
|
LOG_I(PHY, "Channel %d: setting tx_gain offset %.0f, rx_gain offset %.0f, tx_freq %.0f Hz, rx_freq %.0f Hz, tune_offset %.0f Hz, sample_rate %.0f Hz\n",
|
||||||
i, cfg->tx_gain[i],
|
i, cfg->tx_gain[i],
|
||||||
cfg->rx_gain[i],
|
cfg->rx_gain[i],
|
||||||
cfg->tx_freq[i],
|
cfg->tx_freq[i],
|
||||||
cfg->rx_freq[i],
|
cfg->rx_freq[i],
|
||||||
cfg->tune_offset);
|
cfg->tune_offset,
|
||||||
|
cfg->sample_rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,8 +193,8 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
|
|||||||
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
|
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
|
||||||
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
|
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
|
||||||
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
|
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
|
||||||
LOG_I(PHY,"Init: N_RB_DL %d, first_carrier_offset %d, nb_prefix_samples %d,nb_prefix_samples0 %d\n",
|
LOG_W(PHY,"Init: N_RB_DL %d, first_carrier_offset %d, nb_prefix_samples %d,nb_prefix_samples0 %d, ofdm_symbol_size %d\n",
|
||||||
N_RB_DL,fp->first_carrier_offset,fp->nb_prefix_samples,fp->nb_prefix_samples0);
|
N_RB_DL,fp->first_carrier_offset,fp->nb_prefix_samples,fp->nb_prefix_samples0, fp->ofdm_symbol_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
|
uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
|
||||||
@@ -417,6 +417,8 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
|
|||||||
frame_parms->get_samples_slot_timestamp = &get_samples_slot_timestamp;
|
frame_parms->get_samples_slot_timestamp = &get_samples_slot_timestamp;
|
||||||
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
|
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
|
||||||
|
|
||||||
|
LOG_W(PHY, "samples_per_subframe %d/per second %d, wCP %d\n", frame_parms->samples_per_subframe, 1000*frame_parms->samples_per_subframe, frame_parms->samples_per_subframe_wCP);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -642,6 +642,7 @@ typedef struct NR_UL_TIME_ALIGNMENT {
|
|||||||
char ta_slot;
|
char ta_slot;
|
||||||
/// TA command and TAGID received from the gNB
|
/// TA command and TAGID received from the gNB
|
||||||
uint16_t ta_command;
|
uint16_t ta_command;
|
||||||
|
uint32_t ta_total;
|
||||||
uint8_t tag_id;
|
uint8_t tag_id;
|
||||||
} NR_UL_TIME_ALIGNMENT_t;
|
} NR_UL_TIME_ALIGNMENT_t;
|
||||||
|
|
||||||
|
|||||||
@@ -1944,9 +1944,10 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
|
|||||||
} else if ( strcmp(subcmd,"current") == 0) {
|
} else if ( strcmp(subcmd,"current") == 0) {
|
||||||
for (int i=0; i < max_chan ; i++) {
|
for (int i=0; i < max_chan ; i++) {
|
||||||
if (defined_channels[i] != NULL) {
|
if (defined_channels[i] != NULL) {
|
||||||
prnt("model %i %s type %s: \n----------------\n", i, (defined_channels[i]->model_name !=NULL)?defined_channels[i]->model_name:"(no name set)",
|
prnt("model %i %s type %s:\n", i, (defined_channels[i]->model_name !=NULL)?defined_channels[i]->model_name:"(no name set)",
|
||||||
map_int_to_str(channelmod_names,defined_channels[i]->modelid));
|
map_int_to_str(channelmod_names,defined_channels[i]->modelid));
|
||||||
display_channelmodel(defined_channels[i],debug,prnt);
|
display_channelmodel(defined_channels[i],debug,prnt);
|
||||||
|
prnt("----------------\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3699,9 +3699,12 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
/*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
/*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
||||||
uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/
|
uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/
|
||||||
|
|
||||||
|
const int ta = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
||||||
|
const int tag = ((NR_MAC_CE_TA *)pduP)[1].TAGID;
|
||||||
ul_time_alignment->apply_ta = 1;
|
ul_time_alignment->apply_ta = 1;
|
||||||
ul_time_alignment->ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
ul_time_alignment->ta_command = ta; //here
|
||||||
ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;
|
ul_time_alignment->ta_total += ta - 31;
|
||||||
|
ul_time_alignment->tag_id = tag;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#ifdef DEBUG_HEADER_PARSING
|
#ifdef DEBUG_HEADER_PARSING
|
||||||
@@ -3709,7 +3712,10 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
|
if (ta == 31)
|
||||||
|
LOG_D(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d TA total %d\n", frameP, slot, ta, tag, CC_id, ul_time_alignment->ta_total);
|
||||||
|
else
|
||||||
|
LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d TA total %d\n", frameP, slot, ta, tag, CC_id, ul_time_alignment->ta_total);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_CON_RES_ID:
|
case DL_SCH_LCID_CON_RES_ID:
|
||||||
@@ -4082,7 +4088,10 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
|
|||||||
|
|
||||||
// TA command
|
// TA command
|
||||||
ul_time_alignment->apply_ta = 1;
|
ul_time_alignment->apply_ta = 1;
|
||||||
ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5);
|
const int ta = rar->TA2 + (rar->TA1 << 5);
|
||||||
|
ul_time_alignment->ta_command = 31 + ta;
|
||||||
|
ul_time_alignment->ta_total = ta;
|
||||||
|
LOG_W(MAC, "received TA command %d\n", ul_time_alignment->ta_command);
|
||||||
|
|
||||||
#ifdef DEBUG_RAR
|
#ifdef DEBUG_RAR
|
||||||
// CSI
|
// CSI
|
||||||
|
|||||||
@@ -68,13 +68,11 @@ void rxAddInput( const c16_t *input_sig,
|
|||||||
// Energy in one sample to calibrate input noise
|
// Energy in one sample to calibrate input noise
|
||||||
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
|
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
|
||||||
const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256;
|
const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256;
|
||||||
// Fixme: we don't fill the offset length samples at begining ?
|
|
||||||
// anyway, in today code, channel_offset=0
|
|
||||||
const int dd = abs(channelDesc->channel_offset);
|
const int dd = abs(channelDesc->channel_offset);
|
||||||
const int nbTx=channelDesc->nb_tx;
|
const int nbTx=channelDesc->nb_tx;
|
||||||
|
|
||||||
for (int i=0; i<((int)nbSamples-dd); i++) {
|
for (int i=0; i<nbSamples; i++) {
|
||||||
c16_t *out_ptr=after_channel_sig+dd+i;
|
struct complex16 *out_ptr=after_channel_sig+i;
|
||||||
struct complexd rx_tmp= {0};
|
struct complexd rx_tmp= {0};
|
||||||
|
|
||||||
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
||||||
@@ -88,7 +86,9 @@ void rxAddInput( const c16_t *input_sig,
|
|||||||
// but it is not very usefull
|
// but it is not very usefull
|
||||||
// it would be better to split out each antenna in a separate flow
|
// it would be better to split out each antenna in a separate flow
|
||||||
// that will allow to mix ru antennas freely
|
// that will allow to mix ru antennas freely
|
||||||
c16_t tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
|
// (X + cirSize) % cirSize to ensure that index is positive
|
||||||
|
const int idx = ((TS + i - l - dd) * nbTx + txAnt + CirSize) % CirSize;
|
||||||
|
const struct complex16 tx16 = input_sig[idx];
|
||||||
rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
|
rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
|
||||||
rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
|
rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
|
||||||
} //l
|
} //l
|
||||||
|
|||||||
@@ -90,8 +90,14 @@
|
|||||||
|
|
||||||
|
|
||||||
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||||
|
static int rfsimu_setdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||||
|
static int rfsimu_getdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||||
|
static int rfsimu_vtime_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||||
static telnetshell_cmddef_t rfsimu_cmdarray[] = {
|
static telnetshell_cmddef_t rfsimu_cmdarray[] = {
|
||||||
{"setmodel","<model name> <model type>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
{"setmodel","<model name> <model type>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||||
|
{"setdistance","<model name> <distance>", (cmdfunc_t)rfsimu_setdistance_cmd, TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||||
|
{"getdistance","<model name>", (cmdfunc_t) rfsimu_getdistance_cmd, TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||||
|
{"vtime","", (cmdfunc_t) rfsimu_vtime_cmd, TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||||
{"","",NULL},
|
{"","",NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -369,6 +375,164 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
|
|||||||
return CMDSTATUS_FOUND;
|
return CMDSTATUS_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static void print_cirBuf(struct complex16 *circularBuf,
|
||||||
|
// uint64_t firstSample,
|
||||||
|
// uint32_t cirSize,
|
||||||
|
// int neg,
|
||||||
|
// int pos,
|
||||||
|
// int nbTx)
|
||||||
|
//{
|
||||||
|
// for (int i = -neg; i < pos ; ++i) {
|
||||||
|
// for (int txAnt = 0; txAnt < nbTx; txAnt++) {
|
||||||
|
// const int idx = ((firstSample + i) * nbTx + txAnt + cirSize) % cirSize;
|
||||||
|
// if (i == 0)
|
||||||
|
// printf("->");
|
||||||
|
// printf("%08x%08x\n", circularBuf[idx].r, circularBuf[idx].i);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// printf("\n");
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void rfsimu_offset_change_cirBuf(struct complex16 *circularBuf,
|
||||||
|
uint64_t firstSample,
|
||||||
|
uint32_t cirSize,
|
||||||
|
int old_offset,
|
||||||
|
int new_offset,
|
||||||
|
int nbTx)
|
||||||
|
{
|
||||||
|
//int start = max(new_offset, old_offset) + 10;
|
||||||
|
//int end = 10;
|
||||||
|
//printf("new_offset %d old_offset %d start %d end %d\n", new_offset, old_offset, start, end);
|
||||||
|
//printf("ringbuffer before:\n");
|
||||||
|
//print_cirBuf(circularBuf, firstSample, cirSize, start, end, nbTx);
|
||||||
|
|
||||||
|
int doffset = new_offset - old_offset;
|
||||||
|
if (doffset > 0) {
|
||||||
|
/* Moving away, creating a gap. We need to insert "zero" samples between
|
||||||
|
* the previous (end of the) slot and the new slot (at the ringbuffer
|
||||||
|
* index) to prevent that the receiving side detects things that are not
|
||||||
|
* in the channel (e.g., samples that have already been delivered). */
|
||||||
|
for (int i = new_offset; i > 0; --i) {
|
||||||
|
for (int txAnt = 0; txAnt < nbTx; txAnt++) {
|
||||||
|
const int newidx = ((firstSample - i) * nbTx + txAnt + cirSize) % cirSize;
|
||||||
|
if (i > doffset) {
|
||||||
|
// shift samples not read yet
|
||||||
|
const int oldidx = (newidx + doffset) % cirSize;
|
||||||
|
circularBuf[newidx] = circularBuf[oldidx];
|
||||||
|
} else {
|
||||||
|
// create zero samples between slots
|
||||||
|
const struct complex16 nullsample = {0, 0};
|
||||||
|
circularBuf[newidx] = nullsample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Moving closer, creating overlap between samples. For simplicity, we
|
||||||
|
* simply drop `doffset` samples at the end of the previous slot
|
||||||
|
* (this is, in a sense, arbitrary). In a real channel, there would be
|
||||||
|
* some overlap between samples, e.g., for `doffset == 1` we could add
|
||||||
|
* two samples. I think that we cannot do that for multiple samples,
|
||||||
|
* though, and so we just drop some */
|
||||||
|
// drop the last -doffset samples of the previous slot
|
||||||
|
for (int i = old_offset; i > -doffset; --i) {
|
||||||
|
for (int txAnt = 0; txAnt < nbTx; txAnt++) {
|
||||||
|
const int oldidx = ((firstSample - i) * nbTx + txAnt + cirSize) % cirSize;
|
||||||
|
const int newidx = (oldidx - doffset) % cirSize;
|
||||||
|
circularBuf[newidx] = circularBuf[oldidx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("ringbuffer after:\n");
|
||||||
|
//print_cirBuf(circularBuf, firstSample, cirSize, start, end, nbTx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsimu_setdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
prnt("%s() buffer \"%s\"\n", __func__, buff);
|
||||||
|
|
||||||
|
char *modelname;
|
||||||
|
int distance;
|
||||||
|
int s = sscanf(buff,"%m[^ ] %d\n", &modelname, &distance);
|
||||||
|
if (s != 2) {
|
||||||
|
prnt("require exact two parameters\n");
|
||||||
|
return CMDSTATUS_VARNOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||||
|
const double sample_rate = t->sample_rate;
|
||||||
|
const double c = 299792458; /* 3e8 */
|
||||||
|
|
||||||
|
const int new_offset = (double) distance * sample_rate / c;
|
||||||
|
const double new_distance = (double) new_offset * c / sample_rate;
|
||||||
|
|
||||||
|
prnt("\nnew_offset %d new (exact) distance %.3f m\n", new_offset, new_distance);
|
||||||
|
|
||||||
|
/* Set distance in rfsim and channel model, update channel and ringbuffer */
|
||||||
|
for (int i=0; i<FD_SETSIZE; i++) {
|
||||||
|
buffer_t *b=&t->buf[i];
|
||||||
|
if (b->conn_sock <= 0
|
||||||
|
|| b->channel_model == NULL
|
||||||
|
|| b->channel_model->model_name == NULL
|
||||||
|
|| strcmp(b->channel_model->model_name, modelname) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
channel_desc_t *cd = b->channel_model;
|
||||||
|
const int old_offset = cd->channel_offset;
|
||||||
|
cd->channel_offset = new_offset;
|
||||||
|
|
||||||
|
const int nbTx = cd->nb_tx;
|
||||||
|
rfsimu_offset_change_cirBuf(b->circularBuf, t->nextRxTstamp, CirSize, old_offset, new_offset, nbTx);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(modelname);
|
||||||
|
|
||||||
|
return CMDSTATUS_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsimu_getdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
prnt("%s() buffer \"%s\"\n", __func__, buff);
|
||||||
|
|
||||||
|
char *modelname;
|
||||||
|
int s = sscanf(buff,"%ms\n", &modelname);
|
||||||
|
if (s != 1) {
|
||||||
|
prnt("require exact two parameters\n");
|
||||||
|
return CMDSTATUS_VARNOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||||
|
const double sample_rate = t->sample_rate;
|
||||||
|
const double c = 299792458; /* 3e8 */
|
||||||
|
|
||||||
|
for (int i=0; i<FD_SETSIZE; i++) {
|
||||||
|
buffer_t *b=&t->buf[i];
|
||||||
|
if (b->conn_sock <= 0
|
||||||
|
|| b->channel_model == NULL
|
||||||
|
|| b->channel_model->model_name == NULL
|
||||||
|
|| strcmp(b->channel_model->model_name, modelname) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
channel_desc_t *cd = b->channel_model;
|
||||||
|
const int offset = cd->channel_offset;
|
||||||
|
const double distance = (double) offset * c / sample_rate;
|
||||||
|
prnt("\noffset %d distance %.3f m\n", offset, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMDSTATUS_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsimu_vtime_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg)
|
||||||
|
{
|
||||||
|
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||||
|
const openair0_timestamp ts = t->nextRxTstamp;
|
||||||
|
const double sample_rate = t->sample_rate;
|
||||||
|
prnt("vtime measurement: TS %llu sample_rate %.3f\n", ts, sample_rate);
|
||||||
|
return CMDSTATUS_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
static int startServer(openair0_device *device) {
|
static int startServer(openair0_device *device) {
|
||||||
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
|
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
|
||||||
t->typeStamp=ENB_MAGICDL;
|
t->typeStamp=ENB_MAGICDL;
|
||||||
@@ -772,6 +936,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|||||||
rfsimulator->sample_rate=openair0_cfg->sample_rate;
|
rfsimulator->sample_rate=openair0_cfg->sample_rate;
|
||||||
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
||||||
rfsimulator_readconfig(rfsimulator);
|
rfsimulator_readconfig(rfsimulator);
|
||||||
|
LOG_W(HW, "rfsim: sample_rate %f\n", rfsimulator->sample_rate);
|
||||||
pthread_mutex_init(&Sockmutex, NULL);
|
pthread_mutex_init(&Sockmutex, NULL);
|
||||||
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side");
|
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side");
|
||||||
device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ?
|
device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ?
|
||||||
|
|||||||
Reference in New Issue
Block a user