Commit d9b5c0c8 authored by Arash Sahbafard's avatar Arash Sahbafard Committed by laurent

Implement RFsim setdistance/getdistance telnet cmd

parent 7f22f1e5
......@@ -90,8 +90,12 @@
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 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},
{"","",NULL},
};
......@@ -369,6 +373,155 @@ 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 startServer(openair0_device *device) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
t->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