diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f2345a08b4..a0dfa7beca 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -780,7 +780,7 @@ void *UE_thread(void *arg) { msgToPush->key=slot_nr; pushTpool(Tpool, msgToPush); - if ( getenv("RFSIMULATOR") ||IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") + if ( IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") // FixMe: Wait previous thread is done, because race conditions seems too bad // in case of actual RF board, the overlap between threads mitigate the issue // We must receive one message, that proves the slot processing is done diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index eb4620096e..50a43282dc 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -30,7 +30,7 @@ #include #define TPUT_WINDOW_LENGTH 100 - +#define ScaleZone 4 #define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe)); int otg_enabled; @@ -57,6 +57,7 @@ typedef struct OAIgraph { int h; int waterFallh; double *waterFallAvg; + boolean_t initDone; int iteration; void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id); void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id); @@ -104,8 +105,9 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_ if (type==WATERFALL) { graph->waterFallh=h-15; graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh); - for (int i=0; i< graph->waterFallh; i++) - graph->waterFallAvg[i]=0; + + for (int i=0; i< graph->waterFallh; i++) + graph->waterFallAvg[i]=0; graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label); graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label); @@ -129,8 +131,7 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_ graph->maxY=0; graph->minX=0; graph->minY=0; - - + graph->initDone=false; graph->iteration=0; } @@ -153,13 +154,24 @@ static OAIgraph_t nrUEcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_NR } static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) { - if ( maxX > graph->maxX || maxY > graph->maxY || minX < graph->minX || minY < graph->minY ) { + if ( maxX > graph->maxX || minX < graph->minX || + abs(maxX-graph->maxX)>abs(graph->maxX)/2 || + abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) { + graph->maxX/=2; + graph->minX/=2; graph->maxX=max(graph->maxX,maxX); graph->minX=min(graph->minX,minX); + fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2); + } + + if ( maxY > graph->maxY || minY < graph->minY || + abs(maxY-graph->maxY)>abs(graph->maxY)/2 || + abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) { + graph->maxY/=2; + graph->minY/=2; graph->maxY=max(graph->maxY,maxY); graph->minY=min(graph->minY,minY); - fl_set_xyplot_ybounds(graph->graph, graph->minY, graph->maxY); - fl_set_xyplot_xbounds(graph->graph, graph->minX, graph->maxX); + fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2); } } @@ -167,7 +179,6 @@ static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len float *old_x; float *old_y; int old_len=-1; - //LOG_E(HW,"enter oai_xygraph_getbuff, it=%d\n",graph->iteration); if (graph->iteration >1) fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len); @@ -213,16 +224,17 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye graph->iteration++; } -static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize) { +static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { fl_winset(FL_ObjWin(graph->graph)); const int samplesPerPixel=datasize/graph->w; - int row=graph->iteration%(graph->waterFallh); + int displayPart=graph->waterFallh-ScaleZone; + int row=graph->iteration%displayPart; double avg=0; - for (int i=0; i waterFallh; i++) + for (int i=0; i < displayPart; i++) avg+=graph->waterFallAvg[i]; - avg/=graph->waterFallh; + avg/=displayPart; graph->waterFallAvg[row]=0; for (int pix=0; pixw; pix++) { @@ -249,10 +261,22 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in if (val > avg*100 ) col=3; - fl_point(pix, graph->iteration%(graph->waterFallh), water_colors[col]); + fl_point(pix, graph->iteration%displayPart, water_colors[col]); } - fl_set_object_label_f(graph->text, "average I/Q module: %4.1f", sqrt(avg)); + if (graph->initDone==false) { + for ( int i=0; i < graph->waterFallh; i++ ) + for ( int j = 0 ; j < graph->w ; j++ ) + fl_point(j, i, FL_BLACK); + + for ( int i=1; iwaterFallh; j++) + fl_point(i*(graph->w/divisions),j, FL_WHITE); + + graph->initDone=true; + } + + fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg)); graph->iteration++; } @@ -298,7 +322,9 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc static void gNBWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms; //use 1st antenna - genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0], frame_parms->samples_per_frame); + genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0], + frame_parms->samples_per_frame, frame_parms->slots_per_frame, + "X axis:one frame in time"); } /* replaced by waterfall @@ -336,7 +362,9 @@ static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *p static void gNBfreqWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms; //use 1st antenna - genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP); + genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP, + frame_parms->slots_per_frame, + "X axis: Frequency domain, one frame"); } /* @@ -453,7 +481,7 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) { fdui->graph[2] = gNBcommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100, "Channel Frequency domain (RE, one frame)", FL_RED ); fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h); - curY+=h+15; + curY+=h+20; // LLR of PUSCH fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW ); @@ -542,7 +570,9 @@ static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eN // Received signal in time domain of receive antenna 0 genericWaterFall(graph, (scopeSample_t *) phy_vars_ue->common_vars.rxdata[0], - phy_vars_ue->frame_parms.samples_per_frame); + phy_vars_ue->frame_parms.samples_per_frame, + phy_vars_ue->frame_parms.slots_per_frame, + "X axis: one frame time"); } /* replaced by waterfall @@ -566,7 +596,9 @@ static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int //use 1st antenna genericWaterFall(graph, (scopeSample_t *)phy_vars_ue->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0], - frame_parms->samples_per_slot_wCP); + frame_parms->samples_per_slot_wCP, + phy_vars_ue->frame_parms.slots_per_frame, + "X axis: one frame frequency" ); } /* @@ -629,6 +661,8 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i scopeSample_t *pbch_comp = (scopeSample_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; float *I, *Q; oai_xygraph_getbuff(graph, &I, &Q, 180*3, 0); + memset(I,0,180*3*sizeof(*I)); + memset(Q,0,180*3*sizeof(*Q)); int first_symbol=1; int base=0; @@ -651,7 +685,7 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i } AssertFatal(base <= 180*3,""); - oai_xygraph(graph,I,Q,base,0,10); + oai_xygraph(graph,I,Q,base,0, 10); } static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { @@ -806,7 +840,7 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) { fdui->graph[2] = nrUEcommonGraph(ueFreqWaterFall, WATERFALL, 0, curY, 800, 100, "Channel Frequency (RE, one slot)", FL_RED ); fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h); - curY+=h+15; + curY+=h+20; // LLR of PBCH fdui->graph[3] = nrUEcommonGraph(uePbchLLR, FL_POINTS_XYPLOT, 0, curY, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN ); @@ -892,9 +926,12 @@ static void *nrUEscopeThread(void *arg) { OAI_phy_scope_t *form_nrue=create_phy_scope_nrue(0); while (!oai_exit) { + fl_freeze_form(form_nrue->phy_scope); phy_scope_nrUE(form_nrue, ue, 0,0); + fl_unfreeze_form(form_nrue->phy_scope); + fl_redraw_form(form_nrue->phy_scope); usleep(99*1000); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 12eb853595..4a9de9b559 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1236,10 +1236,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b; rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3; - LOG_W(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length); - for (int i=0; i< rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length ; i++) - printf("%x:", dlsch0->harq_processes[harq_pid]->b[i]); - printf ("ret: %d\n", ret); + LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length); rx_ind.number_pdus = 1; // send to mac diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 89d298af08..41574cbe6d 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1500,11 +1500,11 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index } sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; if (*(int64_t*)sib1 != 1) { - printf("%llx\n", *(int64_t*)sib1); - xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + printf("%llx\n", *(int64_t*)sib1); + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); } else - LOG_E(PHY, "sib1 is starting by 8 times 0\n"); + LOG_E(PHY, "sib1 is starting by 8 times 0\n"); } return 0; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e260bf3540..dd29d01fae 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -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",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, + {"setmodel","",(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; ibuf[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; achannel_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_txcircularBuf[((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_txcircularBuf[((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; } diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index 73f6321ffe..daf0133af2 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -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>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 0 ) ; } return 0;