add raw capture from UHD examples and fix a rfsim bug
This commit is contained in:
@@ -657,12 +657,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
||||
}
|
||||
if (samples_received == nsamps) s->wait_for_first_pps=0;
|
||||
}
|
||||
if ( getenv("recorded") ) {
|
||||
static int h=-1;
|
||||
if (h==-1)
|
||||
h=open(getenv("recorded"), O_RDONLY, 0);
|
||||
read(h, buff_tmp[0], nsamps*4);
|
||||
}
|
||||
|
||||
// bring RX data into 12 LSBs for softmodem RX
|
||||
for (int i=0; i<cc; i++) {
|
||||
|
||||
@@ -91,13 +91,13 @@ extern RAN_CONTEXT_t RC;
|
||||
|
||||
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||
static telnetshell_cmddef_t rfsimu_cmdarray[] = {
|
||||
{"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||
{"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||
{"","",NULL},
|
||||
};
|
||||
|
||||
static telnetshell_vardef_t rfsimu_vardef[] = {
|
||||
{"",0,NULL}
|
||||
};
|
||||
};
|
||||
pthread_mutex_t Sockmutex;
|
||||
|
||||
typedef struct complex16 sample_t; // 2*16 bits complex number
|
||||
@@ -170,11 +170,13 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
static bool init_done=false;
|
||||
|
||||
if (!init_done) {
|
||||
uint64_t rand;
|
||||
FILE *h=fopen("/dev/random","r");
|
||||
uint64_t rand;
|
||||
FILE *h=fopen("/dev/random","r");
|
||||
|
||||
if ( 1 != fread(&rand,sizeof(rand),1,h) )
|
||||
LOG_W(HW, "Simulator can't read /dev/random\n");
|
||||
fclose(h);
|
||||
|
||||
fclose(h);
|
||||
randominit(rand);
|
||||
tableNor(rand);
|
||||
init_done=true;
|
||||
@@ -189,7 +191,6 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
bridge->chan_offset, // maybe used for TA
|
||||
bridge->chan_pathloss); // path_loss in dB
|
||||
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
|
||||
|
||||
random_channel(ptr->channel_model,false);
|
||||
}
|
||||
}
|
||||
@@ -317,25 +318,29 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
||||
}
|
||||
|
||||
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
|
||||
char *modelname=NULL;
|
||||
char *modelname=NULL;
|
||||
int s = sscanf(buff,"%ms\n",&modelname);
|
||||
|
||||
if (s == 1) {
|
||||
int channelmod=modelid_fromname(modelname);
|
||||
|
||||
if (channelmod<0)
|
||||
prnt("ERROR: model %s unknown\n",modelname);
|
||||
else {
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
buffer_t *b=&t->buf[i];
|
||||
|
||||
if (b->conn_sock >= 0 ) {
|
||||
channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels,
|
||||
channelmod,
|
||||
t->sample_rate,
|
||||
t->tx_bw,
|
||||
30e-9, // TDL delay-spread parameter
|
||||
t->chan_forgetfact, // forgetting_factor
|
||||
t->chan_offset, // maybe used for TA
|
||||
t->chan_pathloss); // path_loss in dB
|
||||
channelmod,
|
||||
t->sample_rate,
|
||||
t->tx_bw,
|
||||
30e-9, // TDL delay-spread parameter
|
||||
t->chan_forgetfact, // forgetting_factor
|
||||
t->chan_offset, // maybe used for TA
|
||||
t->chan_pathloss); // path_loss in dB
|
||||
set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
|
||||
random_channel(newmodel,false);
|
||||
channel_desc_t *oldmodel=b->channel_model;
|
||||
@@ -346,8 +351,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prnt("ERROR: no model specified\n");
|
||||
prnt("ERROR: no model specified\n");
|
||||
}
|
||||
|
||||
free(modelname);
|
||||
return CMDSTATUS_FOUND;
|
||||
}
|
||||
@@ -368,7 +374,7 @@ sin_addr:
|
||||
};
|
||||
bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr));
|
||||
AssertFatal(listen(t->listen_sock, 5) == 0, "");
|
||||
struct epoll_event ev={0};
|
||||
struct epoll_event ev= {0};
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = t->listen_sock;
|
||||
AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, "");
|
||||
@@ -440,7 +446,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
|
||||
|
||||
if (t->lastWroteTS > timestamp+nsamps)
|
||||
LOG_E(HW,"Not supported to send Tx out of order (same in USRP) %lu, %lu\n",
|
||||
t->lastWroteTS, timestamp);
|
||||
t->lastWroteTS, timestamp);
|
||||
|
||||
t->lastWroteTS=timestamp+nsamps;
|
||||
|
||||
@@ -505,9 +511,9 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
||||
if ( b->headerMode)
|
||||
blockSz=b->remainToTransfer;
|
||||
else
|
||||
blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ?
|
||||
blockSz= b->transferPtr + b->remainToTransfer <= b->circularBufEnd ?
|
||||
b->remainToTransfer :
|
||||
b->circularBufEnd - 1 - b->transferPtr ;
|
||||
b->circularBufEnd - b->transferPtr ;
|
||||
|
||||
ssize_t sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
|
||||
|
||||
@@ -523,7 +529,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
||||
AssertFatal((b->remainToTransfer-=sz) >= 0, "");
|
||||
b->transferPtr+=sz;
|
||||
|
||||
if (b->transferPtr==b->circularBufEnd - 1)
|
||||
if (b->transferPtr==b->circularBufEnd )
|
||||
b->transferPtr=(char *)b->circularBuf;
|
||||
|
||||
// check the header and start block transfer
|
||||
@@ -552,14 +558,13 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memset(b->circularBuf, 0, sampleToByte(CirSize,1));
|
||||
}
|
||||
memset(b->circularBuf, 0, sampleToByte(CirSize,1));
|
||||
}
|
||||
|
||||
if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS < 1000)
|
||||
LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS );
|
||||
|
||||
b->lastReceivedTS=b->th.timestamp;
|
||||
|
||||
} else if ( b->lastReceivedTS > b->th.timestamp && b->th.size == 1 ) {
|
||||
LOG_W(HW,"Received Rx/Tx synchro out of order\n");
|
||||
b->trashingPacket=true;
|
||||
@@ -650,15 +655,15 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
// assuming this should have been done earlier if a Tx would exist
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
struct complex16 v= {0};
|
||||
void *samplesVoid[t->tx_num_channels];
|
||||
void *dummyS[t->tx_num_channels];
|
||||
|
||||
for ( int i=0; i < t->tx_num_channels; i++)
|
||||
samplesVoid[i]=(void *)&v;
|
||||
dummyS[i]=(void *)&v;
|
||||
|
||||
LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n",
|
||||
t->lastWroteTS, t->nextTimestamp);
|
||||
rfsimulator_write_internal(t, t->nextTimestamp,
|
||||
samplesVoid, 1,
|
||||
dummyS, 1,
|
||||
t->tx_num_channels, 1, true);
|
||||
} else {
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
@@ -706,8 +711,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
// it seems legacy behavior is: never in UL, each frame in DL
|
||||
if (reGenerateChannel)
|
||||
random_channel(ptr->channel_model,0);
|
||||
|
||||
if (t->poll_telnetcmdq)
|
||||
t->poll_telnetcmdq(t->telnetcmd_qid,t);
|
||||
t->poll_telnetcmdq(t->telnetcmd_qid,t);
|
||||
|
||||
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
|
||||
if ( ptr->channel_model != NULL ) // apply a channel model
|
||||
@@ -721,12 +727,13 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
else { // no channel modeling
|
||||
sample_t *out=(sample_t *)samplesVoid[a];
|
||||
int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
|
||||
|
||||
//LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
|
||||
for (int i=0; i < nsamps; i++) {//loop over nsamps
|
||||
for (int a_tx=0; a_tx<nbAnt_tx; a_tx++){//sum up signals from nbAnt_tx antennas
|
||||
out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
|
||||
out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
|
||||
} // end for a_tx
|
||||
for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
|
||||
out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
|
||||
out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
|
||||
} // end for a_tx
|
||||
} // end for i (number of samps)
|
||||
} // end of no channel modeling
|
||||
} // end for a (number of rx antennas)
|
||||
@@ -804,18 +811,20 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
||||
//randominit(0);
|
||||
set_taus_seed(0);
|
||||
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
|
||||
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
|
||||
add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
|
||||
|
||||
|
||||
if (addcmd != NULL) {
|
||||
rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME);
|
||||
rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME);
|
||||
addcmd("rfsimu",rfsimu_vardef,rfsimu_cmdarray);
|
||||
|
||||
for(int i=0; rfsimu_cmdarray[i].cmdfunc != NULL; i++) {
|
||||
if ( rfsimu_cmdarray[i].qptr != NULL) {
|
||||
if ( rfsimu_cmdarray[i].qptr != NULL) {
|
||||
rfsimulator->telnetcmd_qid = rfsimu_cmdarray[i].qptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ int fullread(int fd, void *_buf, int count) {
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
|
||||
if (l <= 0) return -1;
|
||||
if (l <= 0)
|
||||
return -1;
|
||||
|
||||
count -= l;
|
||||
buf += l;
|
||||
@@ -43,6 +44,44 @@ int fullread(int fd, void *_buf, int count) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
#define shift 4
|
||||
int32_t signal_energy(int32_t *input,uint32_t length) {
|
||||
int32_t i;
|
||||
int32_t temp,temp2;
|
||||
register __m64 mm0,mm1,mm2,mm3;
|
||||
__m64 *in = (__m64 *)input;
|
||||
mm0 = _mm_setzero_si64();//pxor(mm0,mm0);
|
||||
mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
|
||||
|
||||
for (i=0; i<length>>1; i++) {
|
||||
mm1 = in[i];
|
||||
mm2 = mm1;
|
||||
mm1 = _m_pmaddwd(mm1,mm1);
|
||||
mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
|
||||
mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes
|
||||
// mm2 = _m_psrawi(mm2,shift_DC);
|
||||
mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes
|
||||
}
|
||||
|
||||
mm1 = mm0;
|
||||
mm0 = _m_psrlqi(mm0,32);
|
||||
mm0 = _m_paddd(mm0,mm1);
|
||||
temp = _m_to_int(mm0);
|
||||
temp/=length;
|
||||
temp<<=shift; // this is the average of x^2
|
||||
// now remove the DC component
|
||||
mm2 = _m_psrlqi(mm3,32);
|
||||
mm2 = _m_paddw(mm2,mm3);
|
||||
mm2 = _m_pmaddwd(mm2,mm2);
|
||||
temp2 = _m_to_int(mm2);
|
||||
temp2/=(length*length);
|
||||
// temp2<<=(2*shift_DC);
|
||||
temp -= temp2;
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
return((temp>0)?temp:1);
|
||||
}
|
||||
|
||||
|
||||
void fullwrite(int fd, void *_buf, int count) {
|
||||
char *buf = _buf;
|
||||
@@ -131,8 +170,8 @@ void setblocking(int sock, enum blocking_t active) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc != 4) {
|
||||
printf("Need parameters: source file, server or destination IP, TCP port\n");
|
||||
if(argc < 4) {
|
||||
printf("Need parameters: source file, server or destination IP, TCP port (4043), 'UL|DL' if raw 2*16bits format: UL for UL IQ, DL for DL IQs \n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -147,10 +186,21 @@ int main(int argc, char *argv[]) {
|
||||
serviceSock=client_start(argv[2],atoi(argv[3]));
|
||||
}
|
||||
|
||||
uint64_t typeStamp=ENB_MAGICDL_FDD;
|
||||
boolean_t raw=false;
|
||||
|
||||
if ( argc == 5 ) {
|
||||
raw=true;
|
||||
|
||||
if (strcmp(argv[4],"UL") == 0 )
|
||||
typeStamp=UE_MAGICDL_FDD;
|
||||
}
|
||||
|
||||
samplesBlockHeader_t header;
|
||||
int bufSize=100000;
|
||||
void *buff=malloc(bufSize);
|
||||
uint64_t readTS=0;
|
||||
uint64_t timestamp=0;
|
||||
const int blockSize=1000;
|
||||
|
||||
while (1) {
|
||||
//Rewind the file to loop on the samples
|
||||
@@ -159,10 +209,21 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Read one block and send it
|
||||
setblocking(serviceSock, blocking);
|
||||
AssertFatal(read(fd,&header,sizeof(header)), "");
|
||||
|
||||
if ( raw ) {
|
||||
header.magic=typeStamp;
|
||||
header.size=blockSize;
|
||||
header.nbAnt=1;
|
||||
header.timestamp=timestamp;
|
||||
timestamp+=blockSize;
|
||||
header.option_value=0;
|
||||
header.option_flag=0;
|
||||
} else {
|
||||
AssertFatal(read(fd,&header,sizeof(header)), "");
|
||||
}
|
||||
|
||||
fullwrite(serviceSock, &header, sizeof(header));
|
||||
int dataSize=sizeof(int32_t)*header.size*header.nbAnt;
|
||||
uint64_t wroteTS=header.timestamp;
|
||||
|
||||
if (dataSize>bufSize) {
|
||||
void *new_buff = realloc(buff, dataSize);
|
||||
@@ -176,21 +237,28 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
AssertFatal(read(fd,buff,dataSize) == dataSize, "");
|
||||
|
||||
if (raw) // UHD shifts the 12 ADC values in MSB
|
||||
for (int i=0; i<header.size*header.nbAnt*2; i++)
|
||||
((int16_t *)buff)[i]/=16;
|
||||
|
||||
usleep(1000);
|
||||
printf("sending at ts: %lu, number of samples: %d, energy: %d\n",
|
||||
header.timestamp, header.size, signal_energy(buff, header.size));
|
||||
fullwrite(serviceSock, buff, dataSize);
|
||||
// Purge incoming samples
|
||||
setblocking(serviceSock, blocking);
|
||||
setblocking(serviceSock, notBlocking);
|
||||
int ret;
|
||||
|
||||
while(readTS < wroteTS) {
|
||||
if ( fullread(serviceSock, &header,sizeof(header)) != sizeof(header) ||
|
||||
fullread(serviceSock, buff, sizeof(int32_t)*header.size*header.nbAnt) !=
|
||||
sizeof(int32_t)*header.size*header.nbAnt
|
||||
) {
|
||||
do {
|
||||
char buff[64000];
|
||||
ret=read(serviceSock, buff, 64000);
|
||||
|
||||
if ( ret<0 && !( errno == EAGAIN || errno == EWOULDBLOCK ) ) {
|
||||
printf("error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
readTS=header.timestamp;
|
||||
}
|
||||
} while ( ret > 0 ) ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user