|
|
|
@@ -76,15 +76,16 @@ extern RAN_CONTEXT_t RC;
|
|
|
|
|
/* configuration parameters for the rfsimulator device */
|
|
|
|
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
|
|
|
|
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
#define RFSIMULATOR_PARAMS_DESC {\
|
|
|
|
|
{"serveraddr", "<ip address to connect to>\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
|
|
|
|
|
{"serverport", "<port to connect to>\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
|
|
|
|
|
{RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
|
|
|
|
|
{"IQfile", "<file path to use when saving IQs>\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
|
|
|
|
|
{"modelname", "<channel model name>\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
|
|
|
|
|
{"ploss", "<channel path loss in dB>\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
|
|
|
|
|
{"forgetfact", "<channel forget factor ((0 to 1)>\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
|
|
|
|
|
{"offset", "<channel offset in samps>\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
|
|
|
|
|
#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
|
|
|
|
|
#define RFSIMULATOR_PARAMS_DESC { \
|
|
|
|
|
{"serveraddr", "<ip address to connect to>\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
|
|
|
|
|
{"serverport", "<port to connect to>\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
|
|
|
|
|
{RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
|
|
|
|
|
{"IQfile", "<file path to use when saving IQs>\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
|
|
|
|
|
{"modelname", "<channel model name>\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
|
|
|
|
|
{"ploss", "<channel path loss in dB>\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
|
|
|
|
|
{"forgetfact", "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
|
|
|
|
|
{"offset", "<channel offset in samps>\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -137,7 +138,7 @@ typedef struct {
|
|
|
|
|
} rfsimulator_state_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
static void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
buffer_t *ptr=&bridge->buf[sock];
|
|
|
|
|
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
|
|
|
|
|
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
|
|
|
|
@@ -195,7 +196,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
static void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
|
|
|
|
|
close(sock);
|
|
|
|
|
free(bridge->buf[sock].circularBuf);
|
|
|
|
@@ -206,12 +207,12 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
bridge->buf[sock].conn_sock=-1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void socketError(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
static void socketError(rfsimulator_state_t *bridge, int sock) {
|
|
|
|
|
if (bridge->buf[sock].conn_sock!=-1) {
|
|
|
|
|
LOG_W(HW,"Lost socket \n");
|
|
|
|
|
removeCirBuf(bridge, sock);
|
|
|
|
|
|
|
|
|
|
if (bridge->typeStamp==UE_MAGICDL_FDD)
|
|
|
|
|
if (bridge->typeStamp==UE_MAGICDL)
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -229,7 +230,7 @@ enum blocking_t {
|
|
|
|
|
blocking
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void setblocking(int sock, enum blocking_t active) {
|
|
|
|
|
static void setblocking(int sock, enum blocking_t active) {
|
|
|
|
|
int opts;
|
|
|
|
|
AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,"");
|
|
|
|
|
|
|
|
|
@@ -243,7 +244,7 @@ void setblocking(int sock, enum blocking_t active) {
|
|
|
|
|
|
|
|
|
|
static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps);
|
|
|
|
|
|
|
|
|
|
void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
|
|
|
|
static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
|
|
|
|
if (t->saveIQfile != -1) {
|
|
|
|
|
if (write(t->saveIQfile, _buf, count) != count )
|
|
|
|
|
LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno));
|
|
|
|
@@ -277,7 +278,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
|
|
|
|
static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
|
|
|
|
char *saveF=NULL;
|
|
|
|
|
char *modelname=NULL;
|
|
|
|
|
paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC;
|
|
|
|
@@ -312,9 +313,9 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
|
|
|
|
|
|
|
|
|
if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 ||
|
|
|
|
|
strncasecmp(rfsimulator->ip,"server",3) == 0 )
|
|
|
|
|
rfsimulator->typeStamp = ENB_MAGICDL_FDD;
|
|
|
|
|
rfsimulator->typeStamp = ENB_MAGICDL;
|
|
|
|
|
else
|
|
|
|
|
rfsimulator->typeStamp = UE_MAGICDL_FDD;
|
|
|
|
|
rfsimulator->typeStamp = UE_MAGICDL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
|
|
|
|
@@ -358,9 +359,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
|
|
|
|
|
return CMDSTATUS_FOUND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int server_start(openair0_device *device) {
|
|
|
|
|
static int startServer(openair0_device *device) {
|
|
|
|
|
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
|
|
|
|
|
t->typeStamp=ENB_MAGICDL_FDD;
|
|
|
|
|
t->typeStamp=ENB_MAGICDL;
|
|
|
|
|
AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
|
|
|
|
|
int enable = 1;
|
|
|
|
|
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
|
|
|
|
@@ -381,9 +382,9 @@ sin_addr:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int start_ue(openair0_device *device) {
|
|
|
|
|
static int startClient(openair0_device *device) {
|
|
|
|
|
rfsimulator_state_t *t = device->priv;
|
|
|
|
|
t->typeStamp=UE_MAGICDL_FDD;
|
|
|
|
|
t->typeStamp=UE_MAGICDL;
|
|
|
|
|
int sock;
|
|
|
|
|
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
|
|
|
|
|
struct sockaddr_in addr = {
|
|
|
|
@@ -458,7 +459,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
|
|
|
|
|
return nsamps;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
|
|
|
|
static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
|
|
|
|
return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -534,8 +535,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
|
|
|
|
|
|
|
|
|
// check the header and start block transfer
|
|
|
|
|
if ( b->headerMode==true && b->remainToTransfer==0) {
|
|
|
|
|
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
|
|
|
|
|
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
|
|
|
|
|
AssertFatal( (t->typeStamp == UE_MAGICDL && b->th.magic==ENB_MAGICDL) ||
|
|
|
|
|
(t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol");
|
|
|
|
|
b->headerMode=false;
|
|
|
|
|
|
|
|
|
|
if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS
|
|
|
|
@@ -606,7 +607,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
|
|
|
|
return nfds>0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
|
|
|
|
|
static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
|
|
|
|
|
if (nbAnt != 1) {
|
|
|
|
|
LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
|
|
|
|
|
}
|
|
|
|
@@ -748,31 +749,24 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|
|
|
|
signal_energy(samplesVoid[0], nsamps));
|
|
|
|
|
return nsamps;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
|
|
|
|
abort();
|
|
|
|
|
|
|
|
|
|
static int rfsimulator_get_stats(openair0_device *device) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) {
|
|
|
|
|
abort();
|
|
|
|
|
static int rfsimulator_reset_stats(openair0_device *device) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_get_stats(openair0_device *device) {
|
|
|
|
|
static void rfsimulator_end(openair0_device *device) {}
|
|
|
|
|
static int rfsimulator_stop(openair0_device *device) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_reset_stats(openair0_device *device) {
|
|
|
|
|
static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
void rfsimulator_end(openair0_device *device) {}
|
|
|
|
|
int rfsimulator_stop(openair0_device *device) {
|
|
|
|
|
static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int rfsimulator_write_init(openair0_device *device) {
|
|
|
|
|
static int rfsimulator_write_init(openair0_device *device) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
__attribute__((__visibility__("default")))
|
|
|
|
@@ -782,10 +776,10 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|
|
|
|
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
|
|
|
|
|
rfsimulator_readconfig(rfsimulator);
|
|
|
|
|
pthread_mutex_init(&Sockmutex, NULL);
|
|
|
|
|
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE");
|
|
|
|
|
device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ?
|
|
|
|
|
server_start :
|
|
|
|
|
start_ue;
|
|
|
|
|
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 ?
|
|
|
|
|
startServer :
|
|
|
|
|
startClient;
|
|
|
|
|
device->trx_get_stats_func = rfsimulator_get_stats;
|
|
|
|
|
device->trx_reset_stats_func = rfsimulator_reset_stats;
|
|
|
|
|
device->trx_end_func = rfsimulator_end;
|
|
|
|
@@ -795,7 +789,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|
|
|
|
device->trx_write_func = rfsimulator_write;
|
|
|
|
|
device->trx_read_func = rfsimulator_read;
|
|
|
|
|
/* let's pretend to be a b2x0 */
|
|
|
|
|
device->type = USRP_B200_DEV;
|
|
|
|
|
device->type = RFSIMULATOR;
|
|
|
|
|
device->openair0_cfg=&openair0_cfg[0];
|
|
|
|
|
device->priv = rfsimulator;
|
|
|
|
|
device->trx_write_init = rfsimulator_write_init;
|
|
|
|
|