Commit 5662fb21 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/develop-ta' into integration_2022_wk41

parents f7dc97fe 23e63412
......@@ -510,7 +510,7 @@ int process_command(char *buf) {
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
cmddata->prnt=client_printf;
cmddata->debug=telnetparams.telnetdbg;
cmddata->cmdbuff=strdup(cmdb);
cmddata->cmdbuff=cmdb ? strdup(cmdb) : NULL;
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
} else {
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
* 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 i;
notifiedFIFO_t *afifo=NULL;
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
{
if( modulename == NULL || var == NULL || cmd == NULL) {
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
return -1;
}
int i;
for (i=0; i<TELNET_MAXCMD ; i++) {
if (telnetparams.CmdParsers[i].var == NULL) {
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
telnetparams.CmdParsers[i].cmd = cmd;
telnetparams.CmdParsers[i].var = var;
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
if (afifo == NULL) {
afifo = malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(afifo);
}
cmd->qptr = afifo;
}
cmdparser_t *CmdParser = &telnetparams.CmdParsers[i];
if (CmdParser->var == NULL) {
strncpy(CmdParser->module, modulename, sizeof(CmdParser->module) - 1);
CmdParser->cmd = cmd;
CmdParser->var = var;
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
i,telnetparams.CmdParsers[i].module);
i, CmdParser->module);
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;
}
......
......@@ -58,12 +58,14 @@ void measurcmd_display_rlcstats(telnet_printfunc_t prnt);
void measurcmd_display_phycpu(telnet_printfunc_t prnt);
void measurcmd_display_maccpu(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[] = {
// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}},
// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {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}},
// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}},
};
......@@ -89,6 +91,17 @@ void measurcmd_display_phycpu(telnet_printfunc_t prnt) {
PRINT_CPUMEAS_STATE,HDR);
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) {
eNB_MAC_INST *macvars = RC.mac[eNB_id];
......
......@@ -865,12 +865,13 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
cfg->tx_gain[i] = ru->att_tx;
cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
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],
cfg->rx_gain[i],
cfg->tx_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->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
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",
N_RB_DL,fp->first_carrier_offset,fp->nb_prefix_samples,fp->nb_prefix_samples0);
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, fp->ofdm_symbol_size);
}
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->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;
/// TA command and TAGID received from the gNB
uint16_t ta_command;
uint32_t ta_total;
uint8_t tag_id;
} 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) {
for (int i=0; i < max_chan ; i++) {
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));
display_channelmodel(defined_channels[i],debug,prnt);
prnt("----------------\n");
}
}
} 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 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->ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;
ul_time_alignment->ta_command = ta; //here
ul_time_alignment->ta_total += ta - 31;
ul_time_alignment->tag_id = tag;
/*
#ifdef DEBUG_HEADER_PARSING
......@@ -3709,7 +3712,10 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
#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;
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
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
// CSI
......
......@@ -68,13 +68,11 @@ void rxAddInput( const c16_t *input_sig,
// Energy in one sample to calibrate input noise
// 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;
// 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 nbTx=channelDesc->nb_tx;
for (int i=0; i<((int)nbSamples-dd); i++) {
c16_t *out_ptr=after_channel_sig+dd+i;
for (int i=0; i<nbSamples; i++) {
struct complex16 *out_ptr=after_channel_sig+i;
struct complexd rx_tmp= {0};
for (int txAnt=0; txAnt < nbTx; txAnt++) {
......@@ -88,7 +86,9 @@ void rxAddInput( const c16_t *input_sig,
// but it is not very usefull
// it would be better to split out each antenna in a separate flow
// 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.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
} //l
......
......@@ -90,8 +90,14 @@
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[] = {
{"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},
};
......@@ -369,6 +375,164 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
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) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
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->tx_bw=openair0_cfg->tx_bw;
rfsimulator_readconfig(rfsimulator);
LOG_W(HW, "rfsim: sample_rate %f\n", rfsimulator->sample_rate);
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");
device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ?
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment