Commit a9982cf5 authored by hardy's avatar hardy

Merge remote-tracking branch 'origin/NRUE_usedlschparallel' into integration_2021_wk42_b

parents 82ba8ab0 94c7ad6f
......@@ -15,7 +15,7 @@ channelmod = {
ds_tdl = 0;
},
{
model_name = "rfsimu_channel_ue1"
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 0;
noise_power_dB = 0;
......
......@@ -219,7 +219,7 @@ gNBs =
GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR";
GNB_INTERFACE_NAME_FOR_NGU = "eth0";
GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
GNB_PORT_FOR_NGU = 2152; # Spec 2152
};
}
......
......@@ -51,6 +51,7 @@
#include <dlfcn.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <form.h>
#include "common/utils/load_module_shlib.h"
#include "common/config/config_userapi.h"
#include "common/utils/threadPool/thread-pool.h"
......@@ -62,25 +63,18 @@
#include "telnetsrv_proccmd.h"
static char *telnet_defstatmod[] = {"softmodem","phy","loader","measur"};
static telnetsrv_params_t telnetparams;
#define TELNETSRV_LISTENADDR 0
#define TELNETSRV_LISTENPORT 1
#define TELNETSRV_PRIORITY 2
#define TELNETSRV_DEBUG 3
#define TELNETSRV_LOOPC 4
#define TELNETSRV_LOOPD 5
#define TELNETSRV_HISFILE 6
#define TELNETSRV_HISSIZE 7
#define TELNETSRV_PHYBSIZE 8
#define TELNETSRV_STATICMOD 9
#define TELNETSRV_SHRMOD 10
#define TELNETSRV_OPTNAME_STATICMOD "staticmod"
#define TELNETSRV_OPTNAME_SHRMOD "shrmod"
paramdef_t telnetoptions[] = {
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for telnet utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{"listenaddr", "<listen ip address>\n", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 },
{"listenport", "<local port>\n", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 },
{"listenstdin", "enable input from stdin\n", PARAMFLAG_BOOL, uptr:&(telnetparams.listenstdin), defuintval:0, TYPE_UINT, 0 },
{"priority", "<scheduling policy (0-99)\n", 0, iptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 },
{"debug", "<debug level>\n", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 },
{"loopcount", "<loop command iterations>\n", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 },
......@@ -88,8 +82,8 @@ paramdef_t telnetoptions[] = {
{"histfile", "<history file name>\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
{"histsize", "<history sizes>\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
{"phypbsize", "<phy dump buff size (bytes)>\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
{"staticmod", "<static modules selection>\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
{"shrmod", "<dynamic modules selection>\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
{TELNETSRV_OPTNAME_STATICMOD, "<static modules selection>\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
{TELNETSRV_OPTNAME_SHRMOD, "<dynamic modules selection>\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
};
int get_phybsize(void) {
......@@ -682,6 +676,77 @@ void run_telnetsrv(void) {
return;
}
void run_telnetclt(void) {
int sock;
struct sockaddr_in name;
pthread_setname_np(pthread_self(), "telnetclt");
set_sched(pthread_self(),0,telnetparams.priority);
char prompt[sizeof(TELNET_PROMPT_PREFIX)+10];
sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL));
name.sin_family = AF_INET;
struct in_addr addr;
inet_aton("127.0.0.1", &addr) ;
name.sin_addr.s_addr = addr.s_addr;
name.sin_port = htons((unsigned short)(telnetparams.listenport));
while (1) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
fprintf(stderr,"[TELNETSRV] Error %s on socket call\n",strerror(errno));
if(connect(sock, (void *) &name, sizeof(name)))
fprintf(stderr,"[TELNETSRV] Error %s on connect call\n",strerror(errno));
struct timeval ts;
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
while (1) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(sock, &fds);
FD_SET(STDIN_FILENO , &fds);
// wait for data
int nready = select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts);
if (nready < 0) {
perror("select. Error");
break;
}
else if (nready == 0) {
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
}
else if ( FD_ISSET(sock, &fds)) {
int rv;
char inbuf[TELNET_MAX_MSGLENGTH*2];
memset(inbuf,0,sizeof(inbuf));
rv = recv(sock , inbuf , sizeof(inbuf)-1 , 0);
if (rv > 0) {
printf("%s",inbuf);
}
else if (rv == 0) {
printf("Connection closed by the remote end\n\r");
break;
}
else {
perror("recv error");
break;
}
}
else if (FD_ISSET(STDIN_FILENO , &fds)) {
char *inbuf=NULL;
size_t inlen=0;
inlen = getline( &inbuf,&inlen, stdin);
if ( inlen > 0 ) {
if ( send(sock, inbuf,inlen, 0) < 0)
break;
}
free(inbuf);
}
}
close(sock);
}
return;
} /* run_telnetclt */
void poll_telnetcmdq(void *qid, void *arg) {
notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid);
......@@ -720,10 +785,10 @@ void exec_moduleinit(char *modname) {
int add_embeddedmodules(void) {
int ret=0;
for(int i=0; i<telnetoptions[TELNETSRV_STATICMOD].numelt; i++) {
int pindex = config_paramidx_fromname(telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t), TELNETSRV_OPTNAME_STATICMOD);
for(int i=0; i<telnetoptions[pindex].numelt; i++) {
ret++;
exec_moduleinit(telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]);
exec_moduleinit(telnetoptions[pindex].strlistptr[i]);
}
return ret;
......@@ -733,16 +798,16 @@ int add_sharedmodules(void) {
char initfunc[TELNET_CMD_MAXSIZE+9];
void (*fptr)(void);
int ret=0;
for(int i=0; i<telnetoptions[TELNETSRV_SHRMOD].numelt; i++) {
sprintf(initfunc,"add_%s_cmds",telnetoptions[TELNETSRV_SHRMOD].strlistptr[i]);
int pindex = config_paramidx_fromname(telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t), TELNETSRV_OPTNAME_SHRMOD);
for(int i=0; i<telnetoptions[pindex].numelt; i++) {
sprintf(initfunc,"add_%s_cmds",telnetoptions[pindex].strlistptr[i]);
fptr = dlsym(RTLD_DEFAULT,initfunc);
if ( fptr != NULL) {
fptr();
ret++;
} else {
fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]);
fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[pindex].strlistptr[i]);
}
}
......@@ -767,6 +832,12 @@ int telnetsrv_autoinit(void) {
add_telnetcmd("telnet", telnet_vardef, telnet_cmdarray);
add_embeddedmodules();
if ( telnetparams.listenstdin ) {
if(pthread_create(&telnetparams.telnetclt_pthread,NULL, (void *(*)(void *))run_telnetclt, NULL) != 0) {
fprintf(stderr,"[TELNETSRV] Error %s on pthread_create f() run_telnetclt \n",strerror(errno));
return -1;
}
}
return 0;
}
......@@ -807,7 +878,7 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
/* function which will be called by the shared lib loader, to check shared lib version
against main exec version. version mismatch no considered as fatal (interfaces not supposed to change)
against main exec version. version mismatch not considered as fatal (interfaces not supposed to change)
*/
int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildversion) {
#ifndef PACKAGE_VERSION
......
......@@ -108,6 +108,7 @@ typedef struct cmdparser {
/* global variables used by the telnet server */
typedef struct {
pthread_t telnet_pthread; // thread id of the telnet server
pthread_t telnetclt_pthread; // thread id of the telnet client (used when listenstdin set to true)
int telnetdbg; // debug level of the server
int priority; // server running priority
char *histfile; // command history
......@@ -119,6 +120,7 @@ typedef struct {
char msgbuff[TELNET_MAX_MSGLENGTH]; // internal buffer of the client_printf function which is used to print to the client terminal */
unsigned int listenport; // ip port the telnet server is listening on
unsigned int listenaddr; // ip address the telnet server is listening on
unsigned int listenstdin; // enable command input from stdin
unsigned int loopcount; // loop command param: number of loop iteration
unsigned int loopdelay; // loop command param: delay in ms between 2 iterations
unsigned int phyprntbuff_size; // for phy module, dump_eNB_stats function buffer size
......
/*
* 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
*
* 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
*/
/*! \file common/utils/telnetsrv/telnetsrv_nrue_measurements.c
* \brief: implementation of telnet commands related to nrUE measurments
* \author Francois TABURET
* \date 2021
* \version 0.1
* \company NOKIA BellLabs France
* \email: francois.taburet@nokia-bell-labs.com
* \note
* \warning
*/
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define TELNETSERVERCODE
#include "telnetsrv.h"
#include "common/utils/LOG/log.h"
#include "common/config/config_userapi.h"
#include "telnetsrv_measurements.h"
#include "telnetsrv_ltemeasur_def.h"
#include "telnetsrv_cpumeasur_def.h"
#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
#include "openair1/PHY/phy_extern_nr_ue.h"
void measurcmd_display_macstats(telnet_printfunc_t prnt);
void measurcmd_display_macstats_ue(telnet_printfunc_t prnt);
void measurcmd_display_rlcstats(telnet_printfunc_t prnt);
void measurcmd_display_phycpu(telnet_printfunc_t prnt);
void measurcmd_display_maccpu(telnet_printfunc_t prnt);
void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt);
static telnet_measurgroupdef_t nrUEmeasurgroups[] = {
// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}},
// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}},
{"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}},
// {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}},
// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}},
};
#define TELNET_NUM_NRUEMEASURGROUPS (sizeof(nrUEmeasurgroups)/sizeof(telnet_measurgroupdef_t))
static double cpufreq;
#define HDR "---------------------------------"
int get_measurgroups(telnet_measurgroupdef_t **measurgroups) {
*measurgroups = nrUEmeasurgroups;
return TELNET_NUM_NRUEMEASURGROUPS;
}
void measurcmd_display_phycpu(telnet_printfunc_t prnt) {
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[0][0];
telnet_cpumeasurdef_t cpumeasur[]=CPU_PHYNRUE_MEASURE;
prnt("%s cpu (%1.1g GHz) measurements: PHY (cpustats %s) %s\n",HDR,cpufreq,
PRINT_CPUMEAS_STATE,HDR);
measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t));
}
/*
void measurcmd_display_maccpu(telnet_printfunc_t prnt) {
eNB_MAC_INST *macvars = RC.mac[eNB_id];
telnet_cpumeasurdef_t cpumeasur[]=CPU_MACENB_MEASURE;
prnt("%s cpu (%1.1g GHz) measurements: MAC (cpustats %s) %s\n",HDR,cpufreq,
PRINT_CPUMEAS_STATE,HDR);
measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t));
}
void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt) {
pdcp_stats_t *pdcpvars = &(eNB_pdcp_stats[eNB_id]);
telnet_cpumeasurdef_t cpumeasur[]=CPU_PDCPENB_MEASURE;
prnt("%s cpu (%1.1g GHz) measurements: PDCP (cpustats %s) %s \n",HDR,cpufreq,
PRINT_CPUMEAS_STATE,HDR);
measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t));
}
//----------------------------------------------------------------------------------------------------
void measurcmd_display_macstats_ue(telnet_printfunc_t prnt) {
UE_info_t *UE_info = &(RC.mac[eNB_id]->UE_info);
for (int UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) {
for (int i=0; i<UE_info->numactiveCCs[UE_id]; i++) {
int CC_id = UE_info->ordered_CCids[i][UE_id];
prnt("%s UE %i Id %i CCid %i %s\n",HDR,i,UE_id,CC_id,HDR);
eNB_UE_STATS *macuestatptr = &(UE_info->eNB_UE_stats[CC_id][UE_id]);
telnet_ltemeasurdef_t statsptr[]=LTEMAC_UEMEASURE;
measurcmd_display_measures(prnt, statsptr, sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t));
}
}
} // measurcmd_display_macstats_ue
void measurcmd_display_macstats(telnet_printfunc_t prnt) {
for (int CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) {
eNB_STATS *macstatptr=&(RC.mac[eNB_id]->eNB_stats[CC_id]);
telnet_ltemeasurdef_t statsptr[]=LTEMAC_MEASURE;
prnt("%s eNB %i mac stats CC %i frame %u %s\n",
HDR, eNB_id, CC_id, RC.mac[eNB_id]->frame,HDR);
measurcmd_display_measures(prnt,statsptr,sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t));
}
} // measurcmd_display_macstats
void measurcmd_display_one_rlcstat(telnet_printfunc_t prnt, int UE_id, telnet_ltemeasurdef_t *statsptr, int num_rlcmeasure, unsigned int *rlcstats,
char *rbid_str, protocol_ctxt_t *ctxt, const srb_flag_t srb_flagP, const rb_id_t rb_idP)
{
int rlc_status = rlc_stat_req(ctxt,srb_flagP,rb_idP,
rlcstats, rlcstats+1, rlcstats+2, rlcstats+3, rlcstats+4, rlcstats+5,
rlcstats+6, rlcstats+7, rlcstats+8, rlcstats+9, rlcstats+10, rlcstats+11,
rlcstats+12, rlcstats+13, rlcstats+14, rlcstats+15, rlcstats+16, rlcstats+17,
rlcstats+18, rlcstats+19, rlcstats+20, rlcstats+21, rlcstats+22, rlcstats+23,
rlcstats+24, rlcstats+25, rlcstats+26, rlcstats+27);
if (rlc_status == RLC_OP_STATUS_OK) {
prnt("%s UE %i RLC %s mode %s %s\n",HDR,UE_id, rbid_str,
(rlcstats[0]==RLC_MODE_AM)? "AM": (rlcstats[0]==RLC_MODE_UM)?"UM":"NONE",HDR);
measurcmd_display_measures(prnt, statsptr, num_rlcmeasure);
}
} // status measurcmd_rlc_stat_req
void measurcmd_display_rlcstats(telnet_printfunc_t prnt) {
protocol_ctxt_t ctxt;
UE_info_t *UE_info = &(RC.mac[eNB_id]->UE_info);
telnet_ltemeasurdef_t statsptr[]=LTE_RLCMEASURE;
int num_rlcmeasure = sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t );
unsigned int *rlcstats = malloc(num_rlcmeasure*sizeof(unsigned int));
eNB_MAC_INST *eNB = RC.mac[eNB_id];
for(int i=0; i <num_rlcmeasure ; i++) {
statsptr[i].vptr = rlcstats + i;
}
for (int UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) {
#define NB_eNB_INST 1
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_info->eNB_UE_stats[0][UE_id].crnti,
eNB->frame,eNB->subframe,eNB_id);
measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH);
measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DTCH", &ctxt, SRB_FLAG_NO, DTCH-2);
}
} // measurcmd_display_macstats_ue
*/
......@@ -8,9 +8,9 @@ set(TELNETSRV_SOURCE
)
add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} )
target_link_libraries(telnetsrv PRIVATE history)
target_link_libraries(telnetsrv PRIVATE history ncurses form )
foreach(TELNETLIB enb gnb 4gUE 5gUE)
foreach(TELNETLIB enb gnb 4Gue 5Gue)
set(TELNETLIB_SRCS "")
foreach(TELNETLIB_ASRC measurements phycmd)
set(TELNETLIB_SRC ${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_${TELNETLIB}_${TELNETLIB_ASRC}.c)
......
......@@ -64,13 +64,30 @@ void measurcmd_display_groups(telnet_printfunc_t prnt,telnet_measurgroupdef_t *m
} /* measurcmd_display_groups */
/*----------------------------------------------------------------------------------------------------*/
/* cpu measurements functions */
static char *stridx(int max,int i, char *buff) {
if (max>1)
sprintf(buff,"[%d]",i);
else
sprintf(buff," ");
return buff;
}
void measurcmd_display_cpumeasures(telnet_printfunc_t prnt, telnet_cpumeasurdef_t *cpumeasure, int cpumeasure_size) {
for (int i=0; i<cpumeasure_size; i++) {
prnt("%02d %*s: %15.3f us; %15d %s",i,TELNET_MAXMEASURNAME_LEN-1,(cpumeasure+i)->statname,
((cpumeasure+i)->astatptr->trials!=0)?(((cpumeasure+i)->astatptr->diff)/((cpumeasure+i)->astatptr->trials))/cpufreq/1000:0,
(cpumeasure+i)->astatptr->trials, ((i%2)==1)?"|\n":" | " );
int p=0;
char stridx1[16];
char stridx2[16];
for (int i=0; i<cpumeasure_size; i++)
for (int o1=0;o1<cpumeasure[i].num_occur1;o1++)
for (int o2=0;o2<=cpumeasure[i].num_occur2;o2++)
{
prnt("%02d %*s%s%s: %15.3f us; %15d %s",p,TELNET_MAXMEASURNAME_LEN+7,(cpumeasure+i)->statname,
stridx(cpumeasure[i].num_occur1,o1,stridx1),stridx(cpumeasure[i].num_occur2,o2,stridx2),
((cpumeasure+i+o1+o2)->astatptr->trials!=0)?(((cpumeasure+i+o1+o2)->astatptr->diff)/((cpumeasure+i+o1+o2)->astatptr->trials))/cpufreq/1000:0,
(cpumeasure+i+o1+o2)->astatptr->trials, ((p%2)==1)?"|\n":" | " );
p++;
}
prnt("\n\n");
} /* measurcmd_display_measures */
......@@ -141,7 +158,13 @@ int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt) {
int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2);
if (s>0) {
if ( strcmp(subcmd,"groups") == 0) {
if ( strcmp(subcmd,"inq") == 0) {
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL);
time_stats_msg_t *msgdata=NotifiedFifoData(msg);
msgdata->msgid = TIMESTAT_MSGID_DISPLAY;
msgdata->displayFunc = prnt;
pushNotifiedFIFO(&measur_fifo, msg);
} else if ( strcmp(subcmd,"groups") == 0){
measurcmd_display_groups(prnt,measurgroups,num_measurgroups);
badcmd=0;
} else {
......@@ -182,13 +205,13 @@ int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt) {
int badcmd=1;
if (debug > 0)
prnt(" measurcmd_show received %s\n",buf);
prnt(" measurcmd_cpustats received %s\n",buf);
int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2);
if (s>0) {
if ( strcmp(subcmd,"enable") == 0) {
cpumeas(CPUMEAS_ENABLE);
badcmd=0;
} else if ( strcmp(subcmd,"disable") == 0) {
cpumeas(CPUMEAS_DISABLE);
......@@ -203,6 +226,64 @@ int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt) {
free(subcmd);
return CMDSTATUS_FOUND;
}
void measurcmd_async_help(telnet_printfunc_t prnt) {
}
int measurcmd_async(char *buf, int debug, telnet_printfunc_t prnt) {
char *subcmd=NULL;
int idx1, idx2;
int okcmd=0;
if (buf == NULL) {
measurcmd_async_help(prnt);
return CMDSTATUS_FOUND;
}
if (debug > 0)
prnt(" measurcmd_async received %s\n",buf);
int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2);
if (s==1) {
if ( strcmp(subcmd,"enable") == 0) {
init_meas();
okcmd=1;
} else if ( strcmp(subcmd,"disable") == 0) {
end_meas();
okcmd=1;
}
} else if ( s == 3 ) {
int msgid;
if ( strcmp(subcmd,"enable") == 0) {
msgid = TIMESTAT_MSGID_ENABLE;
okcmd=1;
} else if ( strcmp(subcmd,"disable") == 0) {
msgid = TIMESTAT_MSGID_DISABLE;
okcmd=1;
} else if ( strcmp(subcmd,"display") == 0) {
msgid = TIMESTAT_MSGID_DISPLAY;
okcmd=1;
}
if (okcmd) {
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL);
time_stats_msg_t *msg = (time_stats_msg_t *)NotifiedFifoData(nfe);
msg->msgid = msgid ;
msg->displayFunc = prnt;
for(int i=idx1; i<idx2; i++) {
msg->timestat_id =i;
pushNotifiedFIFO(&measur_fifo, nfe);
}
}
}
if (!(okcmd)) {
prnt("Unknown command: %s\n",buf);
}
free(subcmd);
return CMDSTATUS_FOUND;
}
/*-------------------------------------------------------------------------------------*/
/* function called at telnet server init to add the measur command */
......
......@@ -49,6 +49,9 @@ typedef struct cpumeasurdef {
char statname[TELNET_MAXMEASURNAME_LEN];
time_stats_t *astatptr;
unsigned int statemask;
uint8_t num_occur1;
uint8_t num_occur2;
uint8_t num_occur3;
} telnet_cpumeasurdef_t;
typedef struct ltemeasurdef {
......@@ -60,6 +63,7 @@ typedef struct ltemeasurdef {
#define GROUP_LTESTATS 0
#define GROUP_CPUSTATS 1
typedef void(*measur_dislayfunc_t)(telnet_printfunc_t prnt);
typedef struct mesurgroupdef {
char groupname[TELNET_MAXMEASURNAME_LEN];
......@@ -79,9 +83,11 @@ typedef struct mesurgroupdef {
#ifdef TELNETSRV_MEASURMENTS_MAIN
int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt);
int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt);
int measurcmd_async(char *buf, int debug, telnet_printfunc_t prnt);
telnetshell_cmddef_t measur_cmdarray[] = {
{"show", "groups | <group name>" , measurcmd_show},
{"show", "groups | <group name> | inq" , measurcmd_show},
{"cpustats","[enable | disable]",measurcmd_cpustats},
{"async","[enable | disable]",measurcmd_async},
{"","",NULL}
};
......
......@@ -129,18 +129,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
rxdata_ptr = (int16_t *)tmp_dft_in;
}
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft(dftsize,
rxdata_ptr,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset];
......@@ -249,18 +245,14 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
}
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft(dftsize,
rxdata_ptr,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
......
......@@ -236,11 +236,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag) {
#if UE_TIMING_TRACE
time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
#endif
uint32_t A,E;
uint32_t G;
uint32_t ret,offset;
......@@ -411,21 +410,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
for (r=0; r<harq_process->C; r++) {
//printf("start rx segment %d\n",r);
E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
#if UE_TIMING_TRACE
start_meas(dlsch_deinterleaving_stats);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
nr_deinterleaving_ldpc(E,
harq_process->Qm,
harq_process->w[r], // [hna] w is e
dlsch_llr+r_offset);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
stop_meas(dlsch_deinterleaving_stats);
#endif
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,E,harq_process->F,
Kr*3,
......@@ -455,15 +448,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
return(dlsch->max_ldpc_iterations + 1);
} else {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
r_offset += E;
......@@ -492,9 +481,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
if (err_flag == 0) {
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
//set first 2*Z_c bits to zeros
memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
//set Filler bits
......@@ -545,13 +532,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
for (int k=0; k<A>>3; k++)
LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
}
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
#endif
}
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
......@@ -645,11 +629,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag) {
#if UE_TIMING_TRACE
time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
#endif
uint32_t A,E;
uint32_t G;
uint32_t ret,offset;
......@@ -812,7 +795,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
notifiedFIFO_elt_t *res_dl;
opp_enabled=1;
if (harq_process->C>1) {
for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++) {
if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
......@@ -867,9 +849,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
dlsch_llr+r_offset,
&harq_process->w[r]);
*/
#if UE_TIMING_TRACE
start_meas(dlsch_deinterleaving_stats);
#endif
nr_deinterleaving_ldpc(E,
harq_process->Qm,
harq_process->w[r],
......@@ -879,12 +859,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
for (int i =0; i<16; i++)
LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
#if UE_TIMING_TRACE
stop_meas(dlsch_deinterleaving_stats);
#endif
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
......@@ -915,15 +891,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
return(dlsch->max_ldpc_iterations);
} else {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
......@@ -966,9 +938,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
*/
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
/*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
inv_d[cnt] = (1)*harq_process->d[r][cnt];
......@@ -1037,11 +1007,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
for (int k=0; k<32; k++)
LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
#endif
}
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
err_flag = 1;
......@@ -1135,7 +1104,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
}
void nr_dlsch_decoding_process(void *arg) {
nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
......@@ -1167,11 +1135,10 @@ void nr_dlsch_decoding_process(void *arg) {
proc->instance_cnt_dlsch_td=-1;
//proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe;
proc->decoder_thread_available = 1;
#if UE_TIMING_TRACE
time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
#endif
uint32_t A,E;
uint32_t G;
uint32_t ret;
......@@ -1272,9 +1239,7 @@ void nr_dlsch_decoding_process(void *arg) {
Kr_bytes = Kr>>3;
K_bits_F = Kr-harq_process->F;
E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
#if UE_TIMING_TRACE
start_meas(dlsch_deinterleaving_stats);
#endif
nr_deinterleaving_ldpc(E,
harq_process->Qm,
harq_process->w[r],
......@@ -1284,13 +1249,8 @@ void nr_dlsch_decoding_process(void *arg) {
for (int i =0; i<16; i++)
LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
#if UE_TIMING_TRACE
stop_meas(dlsch_deinterleaving_stats);
#endif
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,
......@@ -1319,15 +1279,11 @@ void nr_dlsch_decoding_process(void *arg) {
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
//return(dlsch->max_ldpc_iterations);
} else {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
......@@ -1364,9 +1320,7 @@ void nr_dlsch_decoding_process(void *arg) {
Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
}
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
// LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
/*
for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
......@@ -1412,10 +1366,7 @@ void nr_dlsch_decoding_process(void *arg) {
if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
for (int k=0; k<2; k++)
LOG_D(PHY,"segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
#endif
}
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
......
......@@ -163,9 +163,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
// int avg_0[2];
// int avg_1[2];
#if UE_TIMING_TRACE
uint8_t slot = 0;
#endif
unsigned char aatx=0,aarx=0;
......@@ -331,12 +329,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
DevAssert(dlsch1_harq);
}
#if UE_TIMING_TRACE
if(symbol > ue->frame_parms.symbols_per_slot>>1)
{
slot = 1;
}
#endif
#ifdef DEBUG_HARQ
printf("Demod dlsch0_harq->pmi_alloc %d\n", dlsch0_harq->pmi_alloc);
......@@ -346,9 +342,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint8_t config_type = dlsch0_harq->dmrsConfigType;
if (beamforming_mode==0) {//No beamforming
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif
if (dlsch0_harq->Nl > 1)//More than or equal 2 layers
nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
pdsch_vars[gNB_id]->dl_ch_estimates,
......@@ -389,7 +383,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
......@@ -398,11 +391,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
#endif
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif
n_tx = dlsch0_harq->Nl;
n_rx = frame_parms->nb_antennas_rx;
......@@ -416,18 +406,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
len,
nb_rb_pdsch);
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
#endif
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif
if (first_symbol_flag==1) {
if (beamforming_mode==0){
nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
......@@ -482,19 +467,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
#endif
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
#endif
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif
// Now channel compensation
if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
......@@ -539,18 +519,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
0);
}
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
#endif
// MRC
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif
if (frame_parms->nb_antennas_rx > 1) {
if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
......@@ -603,19 +578,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//i_mod should have been passed as a parameter
}
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
#endif
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif
/* Store the valid DL RE's */
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = len;
......@@ -692,14 +661,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
#endif
// Please keep it: useful for debugging
#ifdef DEBUG_PDSCH_RX
......
......@@ -126,15 +126,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
// initialization of structure
current_ssb = create_ssb_node(l,hf);
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_dmrs_correlation(ue,proc,0,0,i,i-pbch_initial_symbol,current_ssb);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
......@@ -150,15 +146,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
NR_UE_SSB *temp_ptr=best_ssb;
while (ret!=0 && temp_ptr != NULL) {
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
// computing channel estimation for selected best ssb
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_channel_estimation(ue,proc,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
ret = nr_rx_pbch(ue,
proc,
......
......@@ -18,17 +18,27 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#define _GNU_SOURCE
#include <stdio.h>
#include "time_meas.h"
#include <math.h>
#include <unistd.h>
#include <string.h>
#include "assertions.h"
#ifndef PHYSIM
#include <pthread.h>
#include "common/config/config_userapi.h"
#endif
// global var for openair performance profiler
int opp_enabled = 0;
double cpu_freq_GHz __attribute__ ((aligned(32)));
double cpu_freq_GHz __attribute__ ((aligned(32)))=0.0;
#ifndef PHYSIM
static uint32_t max_cpumeasur;
static time_stats_t **measur_table;
notifiedFIFO_t measur_fifo;
#endif
double get_cpu_freq_GHz(void)
{
if (cpu_freq_GHz <1 ) {
......@@ -133,3 +143,112 @@ double get_time_meas_us(time_stats_t *ts)
return 0;
}
#ifndef PHYSIM
/* function for the asynchronous measurment module: cpu stat are sent to a dedicated thread
* which is in charge of computing the cpu time spent in a given function/algorithm...
*/
time_stats_t *register_meas(char *name)
{
for (int i=0; i<max_cpumeasur; i++) {
if (measur_table[i] == NULL) {
measur_table[i] = (time_stats_t *)malloc(sizeof(time_stats_t));
memset(measur_table[i] ,0,sizeof(time_stats_t));
measur_table[i]->meas_name = strdup(name);
measur_table[i]->meas_index = i;
measur_table[i]->tpoolmsg =newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL);
measur_table[i]->tstatptr = (time_stats_msg_t *)NotifiedFifoData(measur_table[i]->tpoolmsg);
return measur_table[i];
}
}
return NULL;
}
void free_measurtbl(void) {
for (int i=0; i<max_cpumeasur; i++) {
if (measur_table[i] != NULL) {
free(measur_table[i]->meas_name);
delNotifiedFIFO_elt(measur_table[i]->tpoolmsg);
free(measur_table[i]);
}
}
//free the fifo...
}
void run_cpumeasur(void) {
struct sched_param schedp;
pthread_setname_np(pthread_self(), "measur");
schedp.sched_priority=0;
int rt=pthread_setschedparam(pthread_self(), SCHED_IDLE, &schedp);
AssertFatal(rt==0, "couldn't set measur thread priority: %s\n",strerror(errno));
initNotifiedFIFO(&measur_fifo);
while(1) {
notifiedFIFO_elt_t *msg = pullNotifiedFIFO(&measur_fifo);
time_stats_msg_t *tsm = (time_stats_msg_t *)NotifiedFifoData(msg);
switch(tsm->msgid) {
case TIMESTAT_MSGID_START:
measur_table[tsm->timestat_id]->in=tsm->ts;
(measur_table[tsm->timestat_id]->trials)++;
break;
case TIMESTAT_MSGID_STOP:
/// process duration is the difference between two clock points
measur_table[tsm->timestat_id]->p_time = (tsm->ts - measur_table[tsm->timestat_id]->in);
measur_table[tsm->timestat_id]->diff += measur_table[tsm->timestat_id]->p_time;
if ( measur_table[tsm->timestat_id]->p_time > measur_table[tsm->timestat_id]->max )
measur_table[tsm->timestat_id]->max = measur_table[tsm->timestat_id]->p_time;
break;
case TIMESTAT_MSGID_DISPLAY:
{
char aline[256];
int start, stop;
if (tsm->displayFunc != NULL) {
if(tsm->timestat_id >= 0) {
start=tsm->timestat_id ;
stop=start+1;
}
else {
start=0;
stop=max_cpumeasur ;
}
for (int i=start ; i<stop ; i++) {
if (measur_table[i] != NULL) {
sprintf(aline,"%s: %15.3f us ",measur_table[i]->meas_name, measur_table[i]->trials==0?0:( (measur_table[i]->trials/measur_table[i]->diff )/ cpu_freq_GHz /1000 ));
tsm->displayFunc(aline);
}
}
}
}
break;
case TIMESTAT_MSGID_END:
free_measurtbl();
delNotifiedFIFO_elt(msg);
pthread_exit(NULL);
break;
default:
break;
}
delNotifiedFIFO_elt(msg);
}
}
void init_meas(void) {
pthread_t thid;
paramdef_t cpumeasur_params[] = CPUMEASUR_PARAMS_DESC;
int numparams=sizeof(cpumeasur_params)/sizeof(paramdef_t);
int rt = config_get( cpumeasur_params,numparams,CPUMEASUR_SECTION);
AssertFatal(rt >= 0, "cpumeasur configuration couldn't be performed");
measur_table=calloc(max_cpumeasur,sizeof( time_stats_t *));
AssertFatal(measur_table!=NULL, "couldn't allocate %u cpu measurements entries\n",max_cpumeasur);
rt=pthread_create(&thid,NULL, (void *(*)(void *))run_cpumeasur, NULL);
AssertFatal(rt==0, "couldn't create cpu measurment thread: %s\n",strerror(errno));
}
void end_meas(void) {
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL);
time_stats_msg_t *msg = (time_stats_msg_t *)NotifiedFifoData(nfe);
msg->msgid = TIMESTAT_MSGID_END ;
pushNotifiedFIFO(&measur_fifo, nfe);
}
#endif
......@@ -31,30 +31,56 @@
#include <pthread.h>
#include <linux/kernel.h>
#include <linux/types.h>
#ifndef PHYSIM
#include "common/utils/threadPool/thread-pool.h"
#endif
// global var to enable openair performance profiler
extern int opp_enabled;
extern double cpu_freq_GHz __attribute__ ((aligned(32)));;
// structure to store data to compute cpu measurment
#if defined(__x86_64__) || defined(__i386__)
typedef struct {
long long in;
long long diff;
long long p_time; /*!< \brief absolute process duration */
long long diff_square; /*!< \brief process duration square */
long long max;
int trials;
int meas_flag;
} time_stats_t;
#define OAI_CPUTIME_TYPE long long
#elif defined(__arm__)
#define OAI_CPUTIME_TYPE uint32_t
#else
#error "building on unsupported CPU architecture"
#endif
#define TIMESTAT_MSGID_START 0 /*!< \brief send time at measure starting point */
#define TIMESTAT_MSGID_STOP 1 /*!< \brief send time at measure end point */
#define TIMESTAT_MSGID_ENABLE 2 /*!< \brief enable measure point */
#define TIMESTAT_MSGID_DISABLE 3 /*!< \brief disable measure point */
#define TIMESTAT_MSGID_DISPLAY 10 /*!< \brief display measure */
#define TIMESTAT_MSGID_END 11 /*!< \brief stops the measure threads and free assocated resources */
typedef void(*meas_printfunc_t)(const char* format, ...);
typedef struct {
uint32_t in;
uint32_t diff;
uint32_t p_time; /*!< \brief absolute process duration */
uint32_t diff_square; /*!< \brief process duration square */
uint32_t max;
int trials;
} time_stats_t;
int msgid; /*!< \brief message id, as defined by TIMESTAT_MSGID_X macros */
int timestat_id; /*!< \brief points to the time_stats_t entry in cpumeas table */
OAI_CPUTIME_TYPE ts; /*!< \brief time stamp */
meas_printfunc_t displayFunc; /*!< \brief function to call when DISPLAY message is received*/
} time_stats_msg_t;
typedef struct {
OAI_CPUTIME_TYPE in; /*!< \brief time at measure starting point */
OAI_CPUTIME_TYPE diff; /*!< \brief average difference between time at starting point and time at endpoint*/
OAI_CPUTIME_TYPE p_time; /*!< \brief absolute process duration */
OAI_CPUTIME_TYPE diff_square; /*!< \brief process duration square */
OAI_CPUTIME_TYPE max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
int trials; /*!< \brief number of start point - end point iterations */
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
#ifndef PHYSIM
notifiedFIFO_elt_t *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations*/
#endif
} time_stats_t;
#define MEASURE_ENABLED(X) (X->meas_enabled)
static inline void start_meas(time_stats_t *ts) __attribute__((always_inline));
static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
......@@ -137,4 +163,28 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
dst_ts->max=src_ts->max;
}
}
#ifndef PHYSIM
extern notifiedFIFO_t measur_fifo;
#define CPUMEASUR_SECTION "cpumeasur"
#define CPUMEASUR_PARAMS_DESC { \
{"max_cpumeasur", "Max number of cpu measur entries", 0, uptr:&max_cpumeasur, defintval:100, TYPE_UINT, 0},\
}
void init_meas(void);
time_stats_t *register_meas(char *name);
#define START_MEAS(X) send_meas(X, TIMESTAT_MSGID_START)
#define STOP_MEAS(X) send_meas(X, TIMESTAT_MSGID_STOP)
static inline void send_meas(time_stats_t *ts, int msgid) {
if (MEASURE_ENABLED(ts) ) {
ts->tstatptr->timestat_id=ts->meas_index;
ts->tstatptr->msgid = msgid ;
ts->tstatptr->ts = rdtsc_oai();
pushNotifiedFIFO(&measur_fifo, ts->tpoolmsg);
}
}
void end_meas(void);
#endif //ifndef PHYSIM
#endif
This diff is collapsed.
......@@ -429,7 +429,9 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL;
while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) {
while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:D:e:m:w:T:U:q")) != -1) {
switch (c) {
case 'f':
scg_fd = fopen(optarg,"r");
......@@ -595,7 +597,7 @@ int main(int argc, char **argv)
case 'b':
g_rbSize = atoi(optarg);
break;
case 'd':
case 'D':
dlsch_threads = atoi(optarg);
break;
case 'e':
......@@ -668,7 +670,7 @@ int main(int argc, char **argv)
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
printf("-P Print DLSCH performances\n");
printf("-w Write txdata to binary file (one frame)\n");
printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
printf("-D number of dlsch threads, 0: no dlsch parallelization\n");
exit (-1);
break;
}
......@@ -685,7 +687,7 @@ int main(int argc, char **argv)
if (snr1set==0)
snr1 = snr0+10;
init_dlsch_tpool(dlsch_threads);
RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
......@@ -977,7 +979,11 @@ int main(int argc, char **argv)
reset_meas(&msgDataTx->phy_proc_tx);
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
pushTpool(gNB->threadPool,msgL1Tx);
if (dlsch_threads ) {
init_dlsch_tpool(dlsch_threads);
pthread_t dlsch0_threads;
threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1);
}
for (SNR = snr0; SNR < snr1; SNR += .2) {
varArray_t *table_tx=initVarArray(1000,sizeof(double));
......
......@@ -704,6 +704,12 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
pc5s_header->rb_id,
rab_id,
pc5s_header->data_size);
/* pointers to pc5s_header fields possibly not aligned because pc5s_header points to a packed structure
* Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and
* gcc, from v9, now warns about it. fix these warnings by using local variables
*/
uint32_t sourceL2Id = pc5s_header->sourceL2Id;
uint32_t destinationL2Id = pc5s_header->destinationL2Id;
pdcp_data_req(
&ctxt,
SRB_FLAG_NO,
......@@ -713,9 +719,11 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
pc5s_header->data_size,
(unsigned char *)receive_buf,
PDCP_TRANSMISSION_MODE_DATA,
&pc5s_header->sourceL2Id,
&pc5s_header->destinationL2Id
&sourceL2Id,
&destinationL2Id
);
pc5s_header->sourceL2Id = sourceL2Id;
pc5s_header->destinationL2Id=destinationL2Id;
} else { /* else of h_rc == HASH_TABLE_OK */
MSC_LOG_RX_DISCARDED_MESSAGE(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
......@@ -759,6 +767,12 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
pc5s_header->rb_id,
DEFAULT_RAB_ID,
pc5s_header->data_size);
/* pointers to pc5s_header fields possibly not aligned because pc5s_header points to a packed structure
* Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and
* gcc, from v9, now warns about it. fix these warnings by using local variables
*/
uint32_t sourceL2Id = pc5s_header->sourceL2Id;
uint32_t destinationL2Id = pc5s_header->destinationL2Id;
pdcp_data_req (
&ctxt,
SRB_FLAG_NO,
......@@ -768,9 +782,11 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
pc5s_header->data_size,
(unsigned char *)receive_buf,
PDCP_TRANSMISSION_MODE_DATA,
&pc5s_header->sourceL2Id,
&pc5s_header->destinationL2Id
&sourceL2Id,
&destinationL2Id
);
pc5s_header->sourceL2Id = sourceL2Id;
pc5s_header->destinationL2Id=destinationL2Id;
}
} /* end of !ctxt.enb_flag */
......
......@@ -2969,6 +2969,12 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize = siWindowLength_int[sib1->si_WindowLength];
LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
ctxt_pP->module_id, eNB_index, ctxt_pP->module_id );
/* pointers to SIperiod inthe Info struct points to a packed structure
* Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and
* gcc, from v9, now warns about it. fix these warnings by removing the indirection on data
* Not sure if SiPeriod can be modified, reassign after function call for security
*/
uint16_t Aligned_SIperiod = UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod;
rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index,
(LTE_RadioResourceConfigCommonSIB_t *)NULL,
(struct LTE_PhysicalConfigDedicated *)NULL,
......@@ -2981,7 +2987,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,
UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config,
(LTE_MobilityControlInfo_t *) NULL,
&UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize,
&UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod,
&Aligned_SIperiod,
NULL,
NULL,
NULL,
......@@ -2995,6 +3001,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod=Aligned_SIperiod;
LOG_I(RRC,"Setting SIStatus bit 0 to 1\n");
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1;
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag;
......
......@@ -364,7 +364,7 @@ typedef struct UE_RRC_INFO_s {
uint8_t SIwindowsize_MBMS; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40
uint8_t handoverTarget;
HO_STATE_t ho_state;
uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120
uint16_t SIperiod ; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120
uint16_t SIperiod_MBMS; //!< Corresponds to the SIB1-MBMS si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 TODO
unsigned short UE_index;
uint32_t T300_active;
......
......@@ -81,7 +81,12 @@ int as_message_decode(const char* buffer, as_message_t* msg, int length)
LOG_FUNC_IN;
int bytes;
Byte_t** data = NULL;
/* pointers to msg fields possibly not aligned because msg points to a packed structure
* Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and
* gcc, from v9, now warns about it. fix these warnings by removing the indirection on data
* (in fact i don't understand this code data seems to be useless...)
*/
Byte_t *data = NULL;
/* Get the message type */
msg->msgID = *(uint16_t*)(buffer);
......@@ -91,49 +96,49 @@ int as_message_decode(const char* buffer, as_message_t* msg, int length)
case AS_NAS_ESTABLISH_REQ:
/* NAS signalling connection establish request */
bytes += sizeof(nas_establish_req_t) - sizeof(Byte_t*);
data = &msg->msg.nas_establish_req.initialNasMsg.data;
data = msg->msg.nas_establish_req.initialNasMsg.data;
break;
case AS_NAS_ESTABLISH_IND:
/* NAS signalling connection establishment indication */
bytes += sizeof(nas_establish_ind_t) - sizeof(Byte_t*);
data = &msg->msg.nas_establish_ind.initialNasMsg.data;
data = msg->msg.nas_establish_ind.initialNasMsg.data;
break;
case AS_NAS_ESTABLISH_RSP:
/* NAS signalling connection establishment response */
bytes += sizeof(nas_establish_rsp_t) - sizeof(Byte_t*);
data = &msg->msg.nas_establish_rsp.nasMsg.data;
data = msg->msg.nas_establish_rsp.nasMsg.data;
break;
case AS_NAS_ESTABLISH_CNF:
/* NAS signalling connection establishment confirm */
bytes += sizeof(nas_establish_cnf_t) - sizeof(Byte_t*);
data = &msg->msg.nas_establish_cnf.nasMsg.data;
data = msg->msg.nas_establish_cnf.nasMsg.data;
break;
case AS_UL_INFO_TRANSFER_REQ:
/* Uplink L3 data transfer request */
bytes += sizeof(ul_info_transfer_req_t) - sizeof(Byte_t*);
data = &msg->msg.ul_info_transfer_req.nasMsg.data;
data = msg->msg.ul_info_transfer_req.nasMsg.data;
break;
case AS_UL_INFO_TRANSFER_IND:
/* Uplink L3 data transfer indication */
bytes += sizeof(ul_info_transfer_ind_t) - sizeof(Byte_t*);
data = &msg->msg.ul_info_transfer_ind.nasMsg.data;
data = msg->msg.ul_info_transfer_ind.nasMsg.data;
break;
case AS_DL_INFO_TRANSFER_REQ:
/* Downlink L3 data transfer request */
bytes += sizeof(dl_info_transfer_req_t) - sizeof(Byte_t*);
data = &msg->msg.dl_info_transfer_req.nasMsg.data;
data = msg->msg.dl_info_transfer_req.nasMsg.data;
break;
case AS_DL_INFO_TRANSFER_IND:
/* Downlink L3 data transfer indication */
bytes += sizeof(dl_info_transfer_ind_t) - sizeof(Byte_t*);
data = &msg->msg.dl_info_transfer_ind.nasMsg.data;
data = msg->msg.dl_info_transfer_ind.nasMsg.data;
break;
case AS_BROADCAST_INFO_IND:
......@@ -166,7 +171,8 @@ int as_message_decode(const char* buffer, as_message_t* msg, int length)
if (bytes > 0) {
if (data) {
/* Set the pointer to dedicated NAS information */
*data = (Byte_t*)(buffer + bytes);
/* wasn't data already computed above for specific cases here we override ?? */
data = (Byte_t *)buffer + bytes;
}
/* Decode the message */
......@@ -201,7 +207,9 @@ int as_message_encode(char* buffer, as_message_t* msg, int length)
LOG_FUNC_IN;
int bytes = sizeof(msg->msgID);
as_nas_info_t* nas_msg = NULL;
as_nas_info_t nas_msg;
Byte_t *dataptr=NULL;
uint32_t len=0;
switch (msg->msgID) {
case AS_BROADCAST_INFO_IND:
......@@ -237,25 +245,30 @@ int as_message_encode(char* buffer, as_message_t* msg, int length)
case AS_NAS_ESTABLISH_REQ:
/* NAS signalling connection establish request */
bytes += sizeof(nas_establish_req_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.nas_establish_req.initialNasMsg;
nas_msg = msg->msg.nas_establish_req.initialNasMsg;
break;
case AS_NAS_ESTABLISH_IND:
/* NAS signalling connection establish indication */
bytes += sizeof(nas_establish_ind_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.nas_establish_ind.initialNasMsg;
nas_msg = msg->msg.nas_establish_ind.initialNasMsg;
dataptr=(Byte_t *)&(msg->msg.nas_establish_ind.initialNasMsg.data);
len=msg->msg.nas_establish_ind.initialNasMsg.length;
break;
case AS_NAS_ESTABLISH_RSP:
/* NAS signalling connection establish response */
bytes += sizeof(nas_establish_rsp_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.nas_establish_rsp.nasMsg;
nas_msg = msg->msg.nas_establish_rsp.nasMsg;
break;
case AS_NAS_ESTABLISH_CNF:
/* NAS signalling connection establish confirm */
bytes += sizeof(nas_establish_cnf_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.nas_establish_cnf.nasMsg;
nas_msg = msg->msg.nas_establish_cnf.nasMsg;
dataptr=(Byte_t *)&(msg->msg.nas_establish_cnf.nasMsg.data);
len=msg->msg.nas_establish_ind.initialNasMsg.length;
break;
case AS_NAS_RELEASE_REQ:
......@@ -271,7 +284,7 @@ int as_message_encode(char* buffer, as_message_t* msg, int length)
case AS_UL_INFO_TRANSFER_REQ:
/* Uplink L3 data transfer request */
bytes += sizeof(ul_info_transfer_req_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.ul_info_transfer_req.nasMsg;
nas_msg = msg->msg.ul_info_transfer_req.nasMsg;
break;
case AS_UL_INFO_TRANSFER_CNF:
......@@ -282,13 +295,13 @@ int as_message_encode(char* buffer, as_message_t* msg, int length)
case AS_UL_INFO_TRANSFER_IND:
/* Uplink L3 data transfer indication */
bytes += sizeof(ul_info_transfer_ind_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.ul_info_transfer_ind.nasMsg;
nas_msg = msg->msg.ul_info_transfer_ind.nasMsg;
break;
case AS_DL_INFO_TRANSFER_REQ:
/* Downlink L3 data transfer */
bytes += sizeof(dl_info_transfer_req_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.dl_info_transfer_req.nasMsg;
nas_msg = msg->msg.dl_info_transfer_req.nasMsg;
break;
case AS_DL_INFO_TRANSFER_CNF:
......@@ -299,7 +312,8 @@ int as_message_encode(char* buffer, as_message_t* msg, int length)
case AS_DL_INFO_TRANSFER_IND:
/* Downlink L3 data transfer indication */
bytes += sizeof(dl_info_transfer_ind_t) - sizeof(Byte_t*);
nas_msg = &msg->msg.dl_info_transfer_ind.nasMsg;
nas_msg = msg->msg.dl_info_transfer_ind.nasMsg;
break;
case AS_RAB_ESTABLISH_REQ:
......@@ -343,14 +357,14 @@ int as_message_encode(char* buffer, as_message_t* msg, int length)
/* Encode the AS message */
memcpy(buffer, (unsigned char*)msg, bytes);
if ( nas_msg && (nas_msg->length > 0) ) {
if ( (dataptr!=NULL) && (len > 0) ) {
/* Copy the NAS message */
memcpy(buffer + bytes, nas_msg->data, nas_msg->length);
bytes += nas_msg->length;
memcpy(buffer + bytes, nas_msg.data, nas_msg.length);
bytes += len;
/* Release NAS message memory */
free(nas_msg->data);
nas_msg->length = 0;
nas_msg->data = NULL;
free(nas_msg.data);
len=0;
dataptr = NULL;
}
LOG_FUNC_RETURN (bytes);
......
......@@ -136,17 +136,25 @@ static int _emm_as_encrypt(
static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg);
static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *,
ul_info_transfer_req_t *);
static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *,
nas_establish_req_t *);
static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *);
static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *);
static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, ul_info_transfer_req_t *);
static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *);
static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *);
/* prototyping of the following function modified: the last parameter turned to a void pointer
* instead of a ponter to the union field of the as_msg packed structure. This is to avoid new warnings introduced
* from gcc V9 which warns when accessing fields in a packed structure which may result in an alignment problem
* at run time. Modifications allow gcc to know at compile time that it cannot assume any alignment for those pointers.
* On X86 this is not fatal, as at run time the problem can be fixed (but it's better for perf to avoid). On other
* processor as Arm i think it can end in seg fault
*/
static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *,
void *ul_info_transfer_req_unaligned);
static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *,
void *nas_establish_req_unaligned);
static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, void *ul_info_transfer_req_unaligned);
static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, void *ul_info_transfer_req_unaligned);
static int _emm_as_release_req(const emm_as_release_t *, void *nas_release_req_unaligned);
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
......@@ -938,32 +946,32 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg)
case _EMMAS_DATA_REQ:
as_msg.msgID = _emm_as_data_req(user->emm_data,
&msg->u.data,
&as_msg.msg.ul_info_transfer_req);
(void *)(&as_msg.msg.ul_info_transfer_req));
break;
case _EMMAS_STATUS_IND:
as_msg.msgID = _emm_as_status_ind(user->emm_data,
&msg->u.status,
&as_msg.msg.ul_info_transfer_req);
(void *)(&as_msg.msg.ul_info_transfer_req));
break;
case _EMMAS_RELEASE_REQ:
as_msg.msgID = _emm_as_release_req(
&msg->u.release,
&as_msg.msg.nas_release_req);
(void *)(&as_msg.msg.nas_release_req));
break;
case _EMMAS_SECURITY_RES:
as_msg.msgID = _emm_as_security_res(user->emm_data,
&msg->u.security,
&as_msg.msg.ul_info_transfer_req);
(void *)(&as_msg.msg.ul_info_transfer_req));
break;
case _EMMAS_ESTABLISH_REQ:
as_msg.msgID = _emm_as_establish_req(user->emm_data,
&msg->u.establish,
&as_msg.msg.nas_establish_req);
(void *)(&as_msg.msg.nas_establish_req));
break;
......@@ -1069,10 +1077,10 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg)
** **
***************************************************************************/
static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg,
ul_info_transfer_req_t *as_msg)
void *ul_info_transfer_req_unaligned)
{
LOG_FUNC_IN;
ul_info_transfer_req_t *as_msg = (ul_info_transfer_req_t *)ul_info_transfer_req_unaligned;
int size = 0;
int is_encoded = FALSE;
......@@ -1165,12 +1173,12 @@ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg
** **
***************************************************************************/
static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *msg,
ul_info_transfer_req_t *as_msg)
void *ul_info_transfer_req_unaligned)
{
LOG_FUNC_IN;
int size = 0;
ul_info_transfer_req_t *as_msg = (ul_info_transfer_req_t *)ul_info_transfer_req_unaligned;
LOG_TRACE(INFO, "EMMAS-SAP - Send AS status indication (cause=%d)",
msg->emm_cause);
......@@ -1239,12 +1247,12 @@ static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t
** **
***************************************************************************/
static int _emm_as_release_req(const emm_as_release_t *msg,
nas_release_req_t *as_msg)
void *nas_release_req_unaligned)
{
LOG_FUNC_IN;
LOG_TRACE(INFO, "EMMAS-SAP - Send AS release request");
nas_release_req_t *as_msg = (nas_release_req_t *)nas_release_req_unaligned;
/* Setup the AS message */
if (msg->guti) {
as_msg->s_tmsi.MMEcode = msg->guti->gummei.MMEcode;
......@@ -1279,10 +1287,10 @@ static int _emm_as_release_req(const emm_as_release_t *msg,
** **
***************************************************************************/
static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *msg,
ul_info_transfer_req_t *as_msg)
void *ul_info_transfer_req_unaligned)
{
LOG_FUNC_IN;
ul_info_transfer_req_t *as_msg=(ul_info_transfer_req_t *)ul_info_transfer_req_unaligned;
int size = 0;
LOG_TRACE(INFO, "EMMAS-SAP - Send AS security response");
......@@ -1373,12 +1381,12 @@ static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_securit
** **
***************************************************************************/
static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *msg,
nas_establish_req_t *as_msg)
void *nas_establish_req_unaligned)
{
LOG_FUNC_IN;
int size = 0;
nas_establish_req_t *as_msg = (nas_establish_req_t *)nas_establish_req_unaligned;
LOG_TRACE(INFO, "EMMAS-SAP - Send AS connection establish request");
nas_message_t nas_msg;
......
......@@ -141,11 +141,11 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data)
case AS_CELL_INFO_CNF: {
/* Received cell information confirm */
const cell_info_cnf_t *info = &msg->msg.cell_info_cnf;
int cell_found = (info->errCode == AS_SUCCESS);
rc = nas_proc_cell_info(user, cell_found, info->tac,
info->cellID, info->rat,
info->rsrp, info->rsrq);
/* remove using pointers to fiels of the packed structure msg as it
* triggers warnings with gcc version 9 */
const cell_info_cnf_t info = msg->msg.cell_info_cnf;
int cell_found = (info.errCode == AS_SUCCESS);
rc = nas_proc_cell_info(user, cell_found, info.tac, info.cellID, info.rat, info.rsrp, info.rsrq);
break;
}
......@@ -157,12 +157,12 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data)
case AS_NAS_ESTABLISH_CNF: {
/* Received NAS signalling connection establishment confirm */
const nas_establish_cnf_t *confirm = &msg->msg.nas_establish_cnf;
const nas_establish_cnf_t confirm = msg->msg.nas_establish_cnf;
if ( (confirm->errCode == AS_SUCCESS) ||
(confirm->errCode == AS_TERMINATED_NAS) ) {
rc = nas_proc_establish_cnf(user, confirm->nasMsg.data,
confirm->nasMsg.length);
if ( (confirm.errCode == AS_SUCCESS) ||
(confirm.errCode == AS_TERMINATED_NAS) ) {
rc = nas_proc_establish_cnf(user, confirm.nasMsg.data,
confirm.nasMsg.length);
} else {
LOG_TRACE(WARNING, "NET-MAIN - "
"Initial NAS message not delivered");
......@@ -191,10 +191,10 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data)
break;
case AS_DL_INFO_TRANSFER_IND: {
const dl_info_transfer_ind_t *info = &msg->msg.dl_info_transfer_ind;
const dl_info_transfer_ind_t info = msg->msg.dl_info_transfer_ind;
/* Received downlink data transfer indication */
rc = nas_proc_dl_transfer_ind(user, info->nasMsg.data,
info->nasMsg.length);
rc = nas_proc_dl_transfer_ind(user, info.nasMsg.data,
info.nasMsg.length);
break;
}
......
......@@ -74,6 +74,12 @@ class gtpEndPoint {
int ipVersion;
map<int,teidData_t> ue2te_mapping;
map<int,rntiData_t> te2ue_mapping;
// we use the same port number for source and destination address
// this allow using non standard gtp port number (different from 2152)
// and so, for example tu run 4G and 5G cores on one system
tcp_udp_port_t get_dstport() {
return (tcp_udp_port_t)atol(addr.destinationService);
}
};
class gtpEndPoints {
......@@ -99,6 +105,8 @@ int legacyInstanceMapping=0;
#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a)
#define GTPV1U_HEADER_SIZE (8)
static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen,
bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) {
AssertFatal(extHdrFlag==false,"Not developped");
......@@ -299,7 +307,6 @@ static int udpServerSocket(openAddr_s addr) {
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
return -1;
}
int sockfd=-1;
// loop through all the results and bind to the first we can
......@@ -459,17 +466,18 @@ int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
create_tunnel_req->rnti,
create_tunnel_req->num_tunnels,
create_tunnel_req->sgw_S1u_teid[0]);
tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport();
for (int i = 0; i < create_tunnel_req->num_tunnels; i++) {
AssertFatal(create_tunnel_req->eps_bearer_id[i] > 4,
"From legacy code not clear, seems impossible (bearer=%d)\n",
create_tunnel_req->eps_bearer_id[i]);
int incoming_rb_id=create_tunnel_req->eps_bearer_id[i]-4;
teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti,
incoming_rb_id,
create_tunnel_req->eps_bearer_id[i],
create_tunnel_req->sgw_S1u_teid[i],
create_tunnel_req->sgw_addr[i], 2152,
create_tunnel_req->sgw_addr[i], dstport,
pdcp_data_req);
create_tunnel_resp->status=0;
create_tunnel_resp->rnti=create_tunnel_req->rnti;
......@@ -525,13 +533,13 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance,
create_tunnel_req->rnti,
create_tunnel_req->num_tunnels,
create_tunnel_req->upf_NGu_teid[0]);
tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport();
for (int i = 0; i < create_tunnel_req->num_tunnels; i++) {
teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti,
create_tunnel_req->incoming_rb_id[i],
create_tunnel_req->pdusession_id[i],
create_tunnel_req->upf_NGu_teid[i],
create_tunnel_req->upf_addr[i], 2152,
create_tunnel_req->upf_addr[i], dstport,
pdcp_data_req);
create_tunnel_resp->status=0;
create_tunnel_resp->rnti=create_tunnel_req->rnti;
......@@ -869,6 +877,7 @@ void *ocp_gtpv1uTask(void *args) {
// to be dev: should be removed, to use API
strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr);
strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr);
strcpy(addr.destinationService,addr.originService);
AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n");
break;
......@@ -876,6 +885,7 @@ void *ocp_gtpv1uTask(void *args) {
// to be dev: should be removed, to use API
strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr);
strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr);
strcpy(addr.destinationService,addr.originService);
AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n");
break;
......
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