Commit 69735e14 authored by Laurent THOMAS's avatar Laurent THOMAS

SMVB tool

parent 86881b14
...@@ -2869,6 +2869,11 @@ add_executable(replay_node ...@@ -2869,6 +2869,11 @@ add_executable(replay_node
) )
target_link_libraries (replay_node minimal_lib) target_link_libraries (replay_node minimal_lib)
add_executable(convertSMVB
${OPENAIR_TARGETS}/ARCH/rfsimulator/convert_SMVB.c
)
target_link_libraries (convertSMVB minimal_lib)
add_executable(measurement_display add_executable(measurement_display
${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c)
target_link_libraries (measurement_display minimal_lib) target_link_libraries (measurement_display minimal_lib)
......
...@@ -83,9 +83,14 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { ...@@ -83,9 +83,14 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
} }
if (*ptr == NULL) { if (*ptr == NULL) {
*ptr = malloc(length>40?length:40);
// LTS: dummy fix, waiting Francois full fix in 4G branch // LTS: dummy fix, waiting Francois full fix in 4G branch
// the issue is we don't know at this point the size we will get // the issue is we don't know at this point the size we will get
// for parmeters on the command line,
// The length sould probably managed, in a later version
// 100 is a very large value for a string parameter of today OAI
if (length<100)
length=100;
*ptr = malloc(length);
if ( *ptr != NULL) { if ( *ptr != NULL) {
memset(*ptr,0,length); memset(*ptr,0,length);
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <common/utils/simple_executable.h>
#include <sys/sendfile.h>
volatile int oai_exit = 0;
#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);
}
#define RS_head 256
void write_RS_header(int fd, ssize_t sz, int samplingRate) {
const char l1[]="{TYPE: SMU-WV,0}";
const char l2[]="{COMMENT: Generated by OAI}";
const char l3[]="{DATE: %Y-%m-%d;%H:%M:%S}";
const char l4[]="{LEVEL OFFS: 0.000000,0.00000}";
const char l5[]="{CLOCK: %d}";
const char l6[]="{SAMPLES: %ld}";
const char l7[]="{WAVEFORM-%ld: #";
write(fd,l1,strlen(l1));
write(fd,l2,strlen(l2));
time_t t=time(NULL);
struct tm *tmp=localtime(&t);
AssertFatal(tmp != NULL,"");
char outstr[200];
strftime(outstr, sizeof(outstr), l3, tmp);
write(fd,outstr,strlen(outstr));
write(fd,l4,strlen(l4));
sprintf(outstr,l5,samplingRate);
write(fd,outstr,strlen(outstr));
sprintf(outstr,l6,sz);
write(fd,outstr,strlen(outstr));
sprintf(outstr,l7,sz*4+1);
for (int i=lseek(fd,0,SEEK_CUR)+strlen(outstr); i<RS_head; i++)
write(fd," ",1);
write(fd,outstr,strlen(outstr));
}
int main(int argc, char *argv[]) {
if(argc < 4) {
printf("This program converts\n a stored I/Q file in rfsimulator saved IQ format or\n a raw I/Q file (signed 16bits)\nto R&S format\nNeed parameters: source file, destination file, sampling rate in Hz \n");
exit(1);
}
int fdIn=open(argv[1],O_RDONLY);
AssertFatal(fdIn != -1, "file: %s", argv[1]);
off_t fileSize=lseek(fdIn, 0, SEEK_END);
lseek(fdIn, 0, SEEK_SET);
int fdOut=creat(argv[2], 0660);
AssertFatal(fdOut != -1, "file: %s", argv[1]);
int samplingRate=atoi(argv[3]);
boolean_t raw=true;
uint64_t magic;
read(fdIn, &magic, sizeof(magic));
if ( magic== UE_MAGICDL || magic == UE_MAGICUL || magic== ENB_MAGICDL || magic == ENB_MAGICUL )
raw=false;
lseek(fdIn, 0, SEEK_SET);
if (raw) {
// sequence of 2*16 bits ints, as R&S we need only to add the header
write_RS_header(fdOut, fileSize, samplingRate);
ssize_t bytesCopied=0;
// We could consider rescaling
while (bytesCopied != fileSize) {
ssize_t res = sendfile(fdOut, fdIn, &bytesCopied, fileSize);
AssertFatal(res>0,"");
}
} else {
samplesBlockHeader_t header, firstHeader;
int bufSize=100000;
void *buff=malloc(bufSize);
int ret=read(fdIn,&firstHeader,sizeof(header));
AssertFatal(ret== sizeof(header),"");
lseek(fdIn, 0, SEEK_SET);
AssertFatal(firstHeader.nbAnt==1, "R&S SMBV is one Tx\n");
uint64_t timestamp=firstHeader.timestamp;
uint32_t zero=0,zeros[64]={0};
// Reserve room for the header
lseek(fdOut, RS_head, SEEK_SET);
int nb=0;
while (read(fdIn,&header,sizeof(header)) == sizeof(header)) {
int dataSize=sizeof(int32_t)*header.size*header.nbAnt;
AssertFatal(header.nbAnt==1,"");
if (dataSize>bufSize) {
void *new_buff = realloc(buff, dataSize);
if (new_buff == NULL)
AssertFatal(false, "Could not reallocate");
else
buff = new_buff;
}
while (timestamp+64<header.timestamp){
write(fdOut,&zeros,sizeof(zeros));
timestamp+=64;
}
while (timestamp <header.timestamp){
write(fdOut,&zero,sizeof(zero));
timestamp++;
}
ssize_t ret=read(fdIn,buff,dataSize);
AssertFatal(ret == dataSize, "");
for (int i=0; i<header.size*header.nbAnt*2; i++)
((int16_t *)buff)[i]*=16;
ret=write(fdOut, buff, dataSize);
AssertFatal(ret == dataSize, "");
timestamp+=header.size;
nb++;
}
printf("converted %ld samples, control: %ld, %d, %ld\n", timestamp, header.size+header.timestamp, nb, firstHeader.timestamp);
free(buff);
lseek(fdOut, 0, SEEK_SET);
write_RS_header(fdOut,timestamp-firstHeader.timestamp, samplingRate);
lseek(fdOut, 0, SEEK_END);
}
write(fdOut,"}",1);
close(fdOut);
close(fdIn);
return 0;
}
...@@ -178,6 +178,7 @@ int main(int argc, char *argv[]) { ...@@ -178,6 +178,7 @@ int main(int argc, char *argv[]) {
int fd; int fd;
AssertFatal((fd=open(argv[1],O_RDONLY)) != -1, "file: %s", argv[1]); AssertFatal((fd=open(argv[1],O_RDONLY)) != -1, "file: %s", argv[1]);
off_t fileSize=lseek(fd, 0, SEEK_END); off_t fileSize=lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
int serviceSock; int serviceSock;
if (strcmp(argv[2],"server")==0) { if (strcmp(argv[2],"server")==0) {
...@@ -186,15 +187,23 @@ int main(int argc, char *argv[]) { ...@@ -186,15 +187,23 @@ int main(int argc, char *argv[]) {
serviceSock=client_start(argv[2],atoi(argv[3])); serviceSock=client_start(argv[2],atoi(argv[3]));
} }
uint64_t typeStamp=ENB_MAGICDL_FDD; uint64_t typeStamp=ENB_MAGICDL;
boolean_t raw=false; boolean_t raw=false;
if ( argc == 5 ) { if ( argc == 5 ) {
raw=true; raw=true;
if (strcmp(argv[4],"UL") == 0 ) if (strcmp(argv[4],"UL") == 0 )
typeStamp=UE_MAGICDL_FDD; typeStamp=UE_MAGICUL;
}
uint64_t magic;
read(fd,&magic,sizeof(magic));
if (magic== UE_MAGICDL || magic == UE_MAGICUL || magic== ENB_MAGICDL || magic == ENB_MAGICUL ) {
printf("detected rfsimulator recorded file\n");
raw=false;
} }
lseek(fd, 0, SEEK_SET);
samplesBlockHeader_t header; samplesBlockHeader_t header;
int bufSize=100000; int bufSize=100000;
...@@ -207,8 +216,11 @@ int main(int argc, char *argv[]) { ...@@ -207,8 +216,11 @@ int main(int argc, char *argv[]) {
while (1) { while (1) {
//Rewind the file to loop on the samples //Rewind the file to loop on the samples
if ( lseek(fd, 0, SEEK_CUR) >= fileSize ) if ( lseek(fd, 0, SEEK_CUR) >= fileSize ) {
lseek(fd, 0, SEEK_SET); lseek(fd, 0, SEEK_SET);
// we will increment timestamp when we roll on the file
timestamp+=header.timestamp+header.size;
}
// Read one block and send it // Read one block and send it
setblocking(serviceSock, blocking); setblocking(serviceSock, blocking);
...@@ -223,6 +235,7 @@ int main(int argc, char *argv[]) { ...@@ -223,6 +235,7 @@ int main(int argc, char *argv[]) {
header.option_flag=0; header.option_flag=0;
} else { } else {
AssertFatal(read(fd,&header,sizeof(header)), ""); AssertFatal(read(fd,&header,sizeof(header)), "");
header.timestamp+=timestamp;
} }
fullwrite(serviceSock, &header, sizeof(header)); fullwrite(serviceSock, &header, sizeof(header));
...@@ -240,11 +253,9 @@ int main(int argc, char *argv[]) { ...@@ -240,11 +253,9 @@ int main(int argc, char *argv[]) {
} }
AssertFatal(read(fd,buff,dataSize) == dataSize, ""); AssertFatal(read(fd,buff,dataSize) == dataSize, "");
if (raw) // UHD shifts the 12 ADC values in MSB if (raw) // UHD shifts the 12 ADC values in MSB
for (int i=0; i<header.size*header.nbAnt*2; i++) for (int i=0; i<header.size*header.nbAnt*2; i++)
((int16_t *)buff)[i]/=16; ((int16_t *)buff)[i]/=16;
usleep(1000); usleep(1000);
printf("sending at ts: %lu, number of samples: %d, energy: %d\n", printf("sending at ts: %lu, number of samples: %d, energy: %d\n",
header.timestamp, header.size, signal_energy(buff, header.size)); header.timestamp, header.size, signal_energy(buff, header.size));
......
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