From 5c85231782489483e1f6c9706f1c68e68c2c7ca6 Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Fri, 10 Aug 2018 11:06:21 +0200 Subject: [PATCH 01/16] GPS synchronization --- targets/RT/USER/lte-ru.c | 5 +++-- targets/RT/USER/lte-softmodem.c | 4 ++-- targets/RT/USER/lte-softmodem.h | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 891dd9e272..a0339e8f0f 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -121,7 +121,7 @@ extern int emulate_rf; extern int numerology; extern int fepw; extern int single_thread_flag; - +extern clock_source_t clock_source; extern void phy_init_RU(RU_t*); extern void phy_free_RU(RU_t*); @@ -1411,7 +1411,8 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->num_rb_dl=fp->N_RB_DL; cfg->tx_num_channels=ru->nb_tx; cfg->rx_num_channels=ru->nb_rx; - + cfg->clock_source=clock_source; + for (i=0; inb_tx; i++) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 7ff57fee3e..699bc7f56b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -130,7 +130,7 @@ volatile int start_UE = 0; #endif volatile int oai_exit = 0; -static clock_source_t clock_source = internal; +clock_source_t clock_source = internal; static int wait_for_sync = 0; unsigned int mmapped_dma=0; @@ -942,7 +942,7 @@ int main( int argc, char **argv ) printf("Reading in command-line options\n"); - get_options (); + get_options (); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 5590e3a931..2f8209f2d3 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -65,7 +65,7 @@ #define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" #define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" -#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n" +#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" #define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" #define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" #define CONFIG_HLP_TADV "Set timing_advance\n" @@ -161,7 +161,7 @@ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ -{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ +{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:0, TYPE_INT, 0}, \ {"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ From 44e444b3a24e299ce90216baafa01183f65329ce Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Aug 2018 14:38:32 +0200 Subject: [PATCH 02/16] Add missing break in switch statement in set_ul_DAI() --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 05498e4377..df52b83d72 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -386,6 +386,7 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; break; } + break; case 2: // if ((subframeP==3)||(subframeP==8)) From 53bb1fb091a11e19e0905cbf1390dbd69d3bf21b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 14 Aug 2018 15:54:34 +0200 Subject: [PATCH 03/16] minor bugfix Compilation of UE softmodem failed. --- targets/RT/USER/lte-uesoftmodem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 03283beb98..a2a12f9dd9 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -136,7 +136,7 @@ volatile int start_UE = 0; #endif volatile int oai_exit = 0; -static clock_source_t clock_source = internal; +clock_source_t clock_source = internal; static int wait_for_sync = 0; unsigned int mmapped_dma=0; From 79827d6bac33864b0bea23cf141d527e81a40a61 Mon Sep 17 00:00:00 2001 From: "Bi-Ruei, Chiu" Date: Thu, 16 Aug 2018 16:13:47 +0800 Subject: [PATCH 04/16] Add missing S1AP 15.2.0 ASN.1 S1AP-Containers module --- .../S1AP/MESSAGES/ASN1/R15/s1ap-15.2.0.asn1 | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/openair3/S1AP/MESSAGES/ASN1/R15/s1ap-15.2.0.asn1 b/openair3/S1AP/MESSAGES/ASN1/R15/s1ap-15.2.0.asn1 index db1f1b5915..97d0a6de87 100755 --- a/openair3/S1AP/MESSAGES/ASN1/R15/s1ap-15.2.0.asn1 +++ b/openair3/S1AP/MESSAGES/ASN1/R15/s1ap-15.2.0.asn1 @@ -6881,3 +6881,201 @@ id-EDT-Session ProtocolIE-ID ::= 281 id-CNTypeRestrictions ProtocolIE-ID ::= 282 END + +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +S1AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) s1ap (1) version1 (1) s1ap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + Presence, + PrivateIE-ID, + ProtocolExtensionID, + ProtocolIE-ID +FROM S1AP-CommonDataTypes + + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs +FROM S1AP-Constants; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +S1AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +S1AP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +S1AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolExtensionID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +S1AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container {S1AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-SingleContainer {S1AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field {S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id S1AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality S1AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value S1AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} + +ProtocolIE-FieldPair {S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { + id S1AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality S1AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue S1AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality S1AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue S1AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container Lists for Protocol IE Containers +-- +-- ************************************************************** + +ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, S1AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-SingleContainer {{IEsSetParam}} + +ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-ContainerPair {{IEsSetParam}} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id S1AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality S1AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue S1AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container {S1AP-PRIVATE-IES : IEsSetParam } ::= + SEQUENCE (SIZE (1.. maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field {S1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id S1AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality S1AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value S1AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END From 6562577e967c59ce5caad691064825c692595161 Mon Sep 17 00:00:00 2001 From: "Bi-Ruei, Chiu" Date: Thu, 16 Aug 2018 16:15:01 +0800 Subject: [PATCH 05/16] Update asn1c commit with two new fixes --- cmake_targets/tools/build_helper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 5ddce2340b..3363bd2e76 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -683,7 +683,7 @@ install_asn1c_from_source(){ # better to use a given commit than a branch in case the branch # is updated and requires modifications in the source of OAI #git checkout velichkov_s1ap_plus_option_group - git checkout ec830d70bbb014b769810355a2f321a91ccd8a58 + git checkout 73d6b23dcec9ab36605b4af884143824392134c1 autoreconf -iv ./configure make -j`nproc` From 55ba99ac623224ec2b9c39f22eb9094f8f56984d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Aug 2018 10:31:32 +0200 Subject: [PATCH 06/16] T: check consistency of T_messages.txt with VCD functions and variables traces Since VCD has now to go through the T tracer, we enforce the consistency of data found in common/utils/LOG/vcd_signal_dumper.[ch] with data found in common/utils/T/T_messages.txt. We might get completely rid of common/utils/LOG/vcd_signal_dumper.[ch] at some point. For the moment, let's keep it. This commit adds the program common/utils/T/check_vcd.c and necessary modifications to enforce its use at compilation time. If you modify common/utils/LOG/vcd_signal_dumper.[ch] but do not update common/utils/T/T_messages.txt an error will pop up when you compile the software. You have to keep both modules synchronized. --- cmake_targets/CMakeLists.txt | 7 +- common/utils/LOG/vcd_signal_dumper.h | 14 +- common/utils/T/Makefile | 9 +- common/utils/T/T_messages.txt | 27 +-- common/utils/T/check_vcd.c | 249 ++++++++++++++++++++++++ common/utils/itti/intertask_interface.c | 2 +- 6 files changed, 274 insertions(+), 34 deletions(-) create mode 100644 common/utils/T/check_vcd.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 17e2072d00..6987c3f06e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1880,9 +1880,13 @@ endif (${T_TRACER}) #This rule and the following deal with it. add_custom_command ( OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h + COMMAND make clean COMMAND make + COMMAND make check_vcd WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt + ${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c + ${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.h ) #This rule is specifically needed to generate T files @@ -2187,7 +2191,8 @@ if (${T_TRACER}) oai_eth_transpro FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL CN_UTILS - GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX) + GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX + coding) if (TARGET ${i}) add_dependencies(${i} generate_T) endif() diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 3c722ac49a..749978bb48 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -39,7 +39,7 @@ /* WARNING: if you edit the enums below, update also string definitions in vcd_signal_dumper.c */ typedef enum { - VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB = 0, + VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB=0, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB, VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB, @@ -91,12 +91,12 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, VCD_SIGNAL_DUMPER_VARIABLES_CNT, VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP, - VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG, - VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG, - VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, - VCD_SIGNAL_DUMPER_VARIABLE_ITTI_ALLOC_MSG, - VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC, - VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE, + VCD_SIGNAL_DUMPER_VARIABLES_ITTI_SEND_MSG, + VCD_SIGNAL_DUMPER_VARIABLES_ITTI_POLL_MSG, + VCD_SIGNAL_DUMPER_VARIABLES_ITTI_RECV_MSG, + VCD_SIGNAL_DUMPER_VARIABLES_ITTI_ALLOC_MSG, + VCD_SIGNAL_DUMPER_VARIABLES_MP_ALLOC, + VCD_SIGNAL_DUMPER_VARIABLES_MP_FREE, VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO, diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 5e1785ea91..a722c2cbf7 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -18,6 +18,13 @@ T_messages.txt.h: T_messages.txt T_IDs.h: $(GENIDS) T_messages.txt ./$(GENIDS) T_messages.txt T_IDs.h +check_vcd: + gcc -Wall -I. -I.. -I../itti -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread + ./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false) + rm -f ./_check_vcd + +.PHONY: check_vcd + clean: - rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h + rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h _check_vcd cd tracer && make clean diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 7ecf551cbf..676f329a0e 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -924,30 +924,9 @@ ID = buf_test #VCD variables and functions #be careful! this must be synchronized with the code! -#also keep up to date VCD_NUM_VARIABLES and VCD_NUM_FUNCTIONS in T_defs.h - -#to synchronize: copy/paste from openair2/UTIL/LOG/vcd_signal_dumper.h -#the variables and functions name, replace "SIGNAL_DUMPER_VARIABLES" by -#"VARIABLE" and "SIGNAL_DUMPER_FUNCTIONS" by "FUNCTION" (check that -#everything is fine! for example we have -#VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG that has VARIABLE without S) -#and then process with sed - -#to generate variables: -#sed -e "s/ VCD_VARIABLE_\(.*\)/ID = VCD_VARIABLE_\1\n DESC = VCD variable \1\n GROUP = ALL:VCD:ENB\n FORMAT = ulong,value/" < VCD >> T_messages.txt - -#to generate functions: -#sed -e "s/ VCD_FUNCTION_\(.*\)/ID = VCD_FUNCTION_\1\n DESC = VCD function \1\n GROUP = ALL:VCD:ENB\n FORMAT = int,value/" < VCD.functions >> T_messages.txt - -#you may want to manually edit groups for UE instead of eNB - -#then count functions and variables and update VCD_NUM_FUNCTIONS and -#VCD_NUM_VARIABLES in T_defs.h - -#also verify that VCD_FIRST_FUNCTION and VCD_FIRST_VARIABLE are correct -#in T_defs.h. They have to point to the first function and variable -#as defined below. Note also that the order of the VCD functions -#and variables must be the same as in the code. +#also keep up to date VCD_NUM_VARIABLES, VCD_NUM_FUNCTIONS, +#VCD_FIRST_FUNCTION and VCD_FIRST_VARIABLE in T_defs.h +#to check that everything is correct you can run: make _check_vcd #variables diff --git a/common/utils/T/check_vcd.c b/common/utils/T/check_vcd.c new file mode 100644 index 0000000000..1460d7e20a --- /dev/null +++ b/common/utils/T/check_vcd.c @@ -0,0 +1,249 @@ +/* + * To disable the checks done by this program, see below at the beginning + * of the function 'main'. + */ + +#include +#include +#include + +#include "database.h" + +#define T_TRACER 1 +#include "T.h" + +/* VCD specific defines and includes + * If the codebase changes, it may need to be updated + */ +#define ENB_MODE +#define ENABLE_USE_CPU_EXECUTION_TIME +#include "../LOG/vcd_signal_dumper.c" + +void err(char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +void err(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + printf("\x1b[31m"); + printf("error: "); + vprintf(fmt, ap); + printf("\n" +"\x1b[33m\n" +"You probably added a VCD trace (variable or function) but you did not\n" +"update T_messages.txt and/or T_defs.h in common/utils/T/\n" +"\n" +"Be sure to add the new trace to T_messages.txt, at the right place in the\n" +"file. Do not forget to define VCD_NAME with an identical value as found\n" +"in the array eurecomVariablesNames or eurecomFunctionsNames.\n" +"\n" +"Be sure to update VCD_NUM_FUNCTIONS, VCD_NUM_VARIABLES, VCD_FIRST_FUNCTION\n" +"and VCD_FIRST_VARIABLE in T_defs.h\n" +"\n" +"The same procedure has to be followed when you delete a VCD trace.\n" +"Delete it in T_messages.txt as well and update T_defs.h\n" +"\n" +"You can disable those VCD checks at development time.\n" +"To disable the VCD checks see the file common/utils/T/check_vcd.c\n" +"Do not push any modification that disables the VCD checks to the\n" +"main repository.\n"); + + printf("\x1b[m\n"); + + va_end(ap); + + exit(1); +} + +int main(void) +{ + /* to disable the checks done by this program, uncomment the following + * line, ie. remove the leading '//' + */ + //return 0; + + void *database = parse_database("T_messages.txt"); + int number_of_events; + int first_var = -1; + int last_var; + int first_fun = -1; + int last_fun; + char *prefix; + int prefix_len; + char *name; + char *vcd_name; + int i; + FILE *in; + char *l = NULL; + size_t lsize; + + if (database == NULL) err("something wrong with T_messages.txt"); + + /* check the value of VCD_NUM_FUNCTIONS */ + if (VCD_NUM_FUNCTIONS != sizeof(eurecomFunctionsNames) / sizeof(char *)) + err("VCD_NUM_FUNCTIONS (%d) must be equal to %zd", + VCD_NUM_FUNCTIONS, + sizeof(eurecomFunctionsNames) / sizeof(char *)); + + /* check the value of VCD_NUM_VARIABLES */ + if (VCD_NUM_VARIABLES != sizeof(eurecomVariablesNames) / sizeof(char *)) + err("VCD_NUM_VARIABLES (%d) must be equal to %zd", + VCD_NUM_VARIABLES, + sizeof(eurecomVariablesNames) / sizeof(char *)); + + number_of_events = number_of_ids(database); + if (number_of_events == 0) err("no event defined in T_messages.txt"); + + /* T_messages.txt ends with VCD VARIABLES followed by VCD FUNCTIONS + * followed by nothing. + * Let's check. + */ + + /* check VCD VARIABLES traces in T_messages.txt */ + prefix = "VCD_VARIABLE_"; + prefix_len = strlen(prefix); + + for (i = 0; i < number_of_events; i++) { + name = event_name_from_id(database, i); + if (strncmp(name, prefix, prefix_len)) continue; + first_var = i; + break; + } + if (first_var == -1) + err("no VCD_VARIABLE_ found in T_messages.txt"); + for (; i < number_of_events; i++) { + name = event_name_from_id(database, i); + if (strncmp(name, prefix, prefix_len)) break; + } + last_var = i-1; + + /* check VCD FUNCTIONS traces in T_messages.txt */ + if (i == number_of_events) + err("no VCD_FUNCTION_ found in T_messages.txt"); + + prefix = "VCD_FUNCTION_"; + prefix_len = strlen(prefix); + + first_fun = i; + + name = event_name_from_id(database, i); + if (strncmp(name, prefix, prefix_len)) + err("last VCD_VARIABLE_ not followed by a VCD_FUNCTION_ in T_messages.txt"); + + for (; i < number_of_events; i++) { + name = event_name_from_id(database, i); + if (strncmp(name, prefix, prefix_len)) break; + } + + if (i != number_of_events) + err("T_messages.txt does not end with a VCD_FUNCTION_ trace"); + + last_fun = i-1; + + if (first_var != (unsigned)VCD_FIRST_VARIABLE) + err("VCD_FIRST_VARIABLE is not correct in T_defs.h"); + if (first_fun != (unsigned)VCD_FIRST_FUNCTION) + err("VCD_FIRST_FUNCTION is not correct in T_defs.h"); + if (last_var-first_var+1 != VCD_NUM_VARIABLES) + err("VCD_NUM_VARIABLES is not correct in T_defs.h"); + if (last_fun-first_fun+1 != VCD_NUM_FUNCTIONS) + err("VCD_NUM_FUNCTIONS is not correct in T_defs.h"); + + /* check that VCD_NAME is identical to + * eurecomVariablesNames[x]/eurecomFunctionsNames[x] + */ + prefix = "VCD_VARIABLE_"; + prefix_len = strlen(prefix); + + for (i = 0; i < number_of_events; i++) { + name = event_name_from_id(database, i); + if (strncmp(name, prefix, prefix_len)) continue; + vcd_name = event_vcd_name_from_id(database, i); + if (vcd_name == NULL) + err("%s has no VCD_NAME in T_messages.txt", name); + if (strcmp(vcd_name, eurecomVariablesNames[i - first_var])) + err("%s has a wrong VCD_NAME in T_messages.txt", name); + } + + prefix = "VCD_FUNCTION_"; + prefix_len = strlen(prefix); + + for (i = 0; i < number_of_events; i++) { + name = event_name_from_id(database, i); + if (strncmp(name, prefix, prefix_len)) continue; + vcd_name = event_vcd_name_from_id(database, i); + if (vcd_name == NULL) + err("%s has no VCD_NAME in T_messages.txt", name); + if (strcmp(vcd_name, eurecomFunctionsNames[i - first_fun])) + err("%s has a wrong VCD_NAME in T_messages.txt", name); + } + + /* check IDs - these checks are difficult because we parse + * common/utils/LOG/vcd_signal_dumper.h which is expected to + * be formatted as is: + * - define vcd_signal_dump_variables then vcd_signal_dump_functions + * - one VCD_XXXX per line starting with two spaces + * followed by ',' or '=' with no space in between + * - no #ifdef / #if is taken into account + * - we require VCD_SIGNAL_DUMPER_VARIABLES_END and + * VCD_SIGNAL_DUMPER_FUNCTIONS_END at the end of each array, + * each on a line of its own with two spaces before and nothing after. + * + * If these checks fail, consider formatting + * common/utils/LOG/vcd_signal_dumper.h as expected here, if + * it makes sense of course. Otherwise, change the code below. + * + * In common/utils/LOG/vcd_signal_dumper.h a valid name is + * either VCD_SIGNAL_DUMPER_VARIABLES_ABC or + * VCD_SIGNAL_DUMPER_FUNCTIONS_XYZ + * and in T_messages.txt the corresponding name has to be + * VCD_VARIABLE_ABC or VCD_FUNCTION_XYZ + */ + i = first_var; + in = fopen("../LOG/vcd_signal_dumper.h", "r"); + if (in == NULL) err("could not open ../LOG/vcd_signal_dumper.h"); + while (1) { + char *x = " VCD_SIGNAL_DUMPER_VARIABLES_"; + ssize_t r; + free(l); + l = NULL; + lsize = 0; + r = getline(&l, &lsize, in); + if (r == -1) break; + if (!strcmp(l, " VCD_SIGNAL_DUMPER_VARIABLES_END\n")) break; + /* remove ',' or '=' if found */ + { char *s=l; while (*s) { if (*s==','||*s=='=') { *s=0; break; } s++; } } + if (strncmp(l, x, strlen(x))) continue; + if (!(i >= first_var && i <= last_var)) + err("T_messages.txt is not correct with respect to VCD VARIABLES"); + name = event_name_from_id(database, i); + if (strcmp(l+strlen(x), name+strlen("VCD_VARIABLE_"))) + err("%s is not correct in T_messages.txt", name); + i++; + } + if (i != last_var + 1) err("VCD VARIABLES wrong in T_messages.txt"); + while (1) { + char *x = " VCD_SIGNAL_DUMPER_FUNCTIONS_"; + ssize_t r; + free(l); + l = NULL; + lsize = 0; + r = getline(&l, &lsize, in); + if (r == -1) break; + if (!strcmp(l, " VCD_SIGNAL_DUMPER_FUNCTIONS_END\n")) break; + /* remove ',' or '=' if found */ + { char *s=l; while (*s) { if (*s==','||*s=='=') { *s=0; break; } s++; } } + if (strncmp(l, x, strlen(x))) continue; + if (!(i >= first_fun && i <= last_fun)) + err("T_messages.txt is not correct with respect to VCD FUNCTIONS"); + name = event_name_from_id(database, i); + if (strcmp(l+strlen(x), name+strlen("VCD_FUNCTION_"))) + err("%s is not correct in T_messages.txt", name); + i++; + } + fclose(in); + if (i != last_fun + 1) err("VCD FUNCTIONS wrong in T_messages.txt"); + + return 0; +} diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 2e38b660d7..d088b59c04 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -745,7 +745,7 @@ void itti_exit_task(void) #if defined(OAI_EMU) || defined(RTAI) if (task_id > TASK_UNKNOWN) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_ITTI_RECV_MSG, __sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id))); } #endif From 4054330191507290d6a826783c87e849990168c8 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Aug 2018 10:42:39 +0200 Subject: [PATCH 07/16] minor: remove TABs --- common/utils/T/T.c | 2 +- common/utils/T/T.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 40af79c1e1..1cda8b7504 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -164,7 +164,7 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) void T_Config_Init(void) { int T_port; /* by default we wait for the tracer */ - int T_nowait; /* default port to listen to to wait for the tracer */ + int T_nowait; /* default port to listen to to wait for the tracer */ int T_dont_fork; /* default is to fork, see 'T_init' to understand */ paramdef_t ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC; diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 755f5d4e39..f1aa6ecd1d 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -578,10 +578,10 @@ extern int *T_active; /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_TTRACEPARAMS_DESC { \ -{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:2021, TYPE_INT, 0}, \ -{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0}, \ -{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0}, \ -{"T_stdout", CONFIG_HLP_STDOUT, PARAMFLAG_BOOL, iptr:&T_stdout, defintval:1, TYPE_INT, 0}, \ +{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:2021, TYPE_INT, 0}, \ +{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0}, \ +{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0}, \ +{"T_stdout", CONFIG_HLP_STDOUT, PARAMFLAG_BOOL, iptr:&T_stdout, defintval:1, TYPE_INT, 0}, \ } From d4a8b5f35e4de2d31413dc3cc4f7ab1cfe9d5d81 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Aug 2018 12:37:17 +0200 Subject: [PATCH 08/16] compilation warning "jobserver unavailable" removal This commit removes the warning: make[4]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule. Basically, inside a Makefile we should use $(MAKE) instead of make. --- cmake_targets/CMakeLists.txt | 8 ++++---- common/utils/T/Makefile | 2 +- common/utils/T/tracer/Makefile | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6987c3f06e..5efb13594f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1880,9 +1880,9 @@ endif (${T_TRACER}) #This rule and the following deal with it. add_custom_command ( OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h - COMMAND make clean - COMMAND make - COMMAND make check_vcd + COMMAND $(MAKE) clean + COMMAND $(MAKE) + COMMAND $(MAKE) check_vcd WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt ${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c @@ -2235,7 +2235,7 @@ function(make_driver name dir) endforeach() CONFIGURE_FILE(${OPENAIR_CMAKE}/tools/Kbuild.cmake ${OPENAIR_BIN_DIR}/${name}/Kbuild) add_custom_command(OUTPUT ${name}.ko - COMMAND make -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name} + COMMAND $(MAKE) -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name} WORKING_DIRECTORY ${OPENAIR_BIN_DIR}/${name} COMMENT "building ${module}.ko" VERBATIM diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index a722c2cbf7..1f845ce4f8 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -27,4 +27,4 @@ check_vcd: clean: rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h _check_vcd - cd tracer && make clean + cd tracer && $(MAKE) clean diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 94902b094a..3da4aa13a1 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -63,16 +63,16 @@ multi: multi.o utils.o database.o config.o .PHONY: all gui/gui.a view/view.a logger/logger.a filter/filter.a gui/gui.a: - cd gui && make + cd gui && $(MAKE) view/view.a: - cd view && make + cd view && $(MAKE) logger/logger.a: - cd logger && make + cd logger && $(MAKE) filter/filter.a: - cd filter && make + cd filter && $(MAKE) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< @@ -81,8 +81,8 @@ clean: rm -f *.o core tracer_remote textlog enb ue vcd record replay rm -f extract_config macpdu2wireshark extract_input_subframe rm -f extract_output_subframe to_vcd extract multi - cd gui && make clean - cd view && make clean - cd logger && make clean - cd filter && make clean - cd hacks && make clean + cd gui && $(MAKE) clean + cd view && $(MAKE) clean + cd logger && $(MAKE) clean + cd filter && $(MAKE) clean + cd hacks && $(MAKE) clean From 475d5eb827c8a82b1450117cdcb903d62ba0b1f7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Aug 2018 12:16:58 +0200 Subject: [PATCH 09/16] T: bug fixes for the T cache - 'busy' has to be handled in a more atomic fashion to avoid crazy runtime race conditions - the basic simulator is too fast sometimes; rewrite the accesses to the T cache to avoid there again crazy behaviors Hopefully that's better... --- common/utils/T/T.c | 6 ++++++ common/utils/T/T.h | 39 ++++++++++++++++++++++++++++------- common/utils/T/T_defs.h | 4 ++++ common/utils/T/local_tracer.c | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 1cda8b7504..fbd3f75a0c 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -31,6 +31,12 @@ volatile int _T_freelist_head; volatile int *T_freelist_head = &_T_freelist_head; T_cache_t *T_cache; +#if BASIC_SIMULATOR +/* global variables used by T_GET_SLOT, see in T.h */ +volatile uint64_t T_next_id; +volatile uint64_t T_active_id; +#endif + static void get_message(int s) { char t; diff --git a/common/utils/T/T.h b/common/utils/T/T.h index f1aa6ecd1d..18e4a590d9 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -112,13 +112,37 @@ extern volatile int *T_freelist_head; extern T_cache_t *T_cache; extern int *T_active; /* When running the basic simulator, we may fill the T cache too fast. - * Let's not crash if it's full, just wait. + * Let's serialize write accesses to the T cache. For that, we use a + * 'ticket' mechanism. To acquire a T slot the caller needs to own the + * current active ticket. We also wait for the slot to be free if + * it is already in use. */ #if BASIC_SIMULATOR -# define T_BASIC_SIMULATOR_WAIT \ - while (T_cache[T_LOCAL_slot].busy) usleep(100) +# define T_GET_SLOT \ + do { \ + extern volatile uint64_t T_next_id; \ + extern volatile uint64_t T_active_id; \ + uint64_t id; \ + /* get a ticket */ \ + id = __sync_fetch_and_add(&T_next_id, 1); \ + /* wait for our turn */ \ + while (id != __sync_fetch_and_add(&T_active_id, 0)) /* busy wait */; \ + /* this is our turn, try to acquire the slot until it's free */ \ + do { \ + T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01); \ + if (T_LOCAL_busy & 0x01) usleep(100); \ + } while (T_LOCAL_busy & 0x01); \ + /* check that there are still some tickets */ \ + if (__sync_fetch_and_add(&T_active_id, 0) == 0xffffffffffffffff) { \ + printf("T: reached the end of times, bye...\n"); \ + abort(); \ + } \ + /* free our ticket, which signals the next waiter that it's its turn */ \ + (void)__sync_fetch_and_add(&T_active_id, 1); \ + } while (0) #else -# define T_BASIC_SIMULATOR_WAIT /* */ +# define T_GET_SLOT \ + T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01); #endif /* used at header of Tn, allocates buffer */ @@ -126,11 +150,12 @@ extern int *T_active; char *T_LOCAL_buf; \ int T_LOCAL_size = 0; \ int T_LOCAL_slot; \ + int T_LOCAL_busy; \ T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \ & (T_CACHE_SIZE - 1); \ (void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \ - T_BASIC_SIMULATOR_WAIT; \ - if (T_cache[T_LOCAL_slot].busy) { \ + T_GET_SLOT; \ + if (T_LOCAL_busy & 0x01) { \ printf("%s:%d:%s: T cache is full - consider increasing its size\n", \ __FILE__, __LINE__, __FUNCTION__); \ abort(); \ @@ -142,7 +167,7 @@ extern int *T_active; #define T_COMMIT() \ T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ __sync_synchronize(); \ - T_cache[T_LOCAL_slot].busy = 1; \ + (void)__sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x02); #define T_CHECK_SIZE(len, argnum) \ if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \ diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 6fe11bcfc3..83a380662d 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -31,6 +31,10 @@ #endif typedef struct { + /* 'busy' is a bit field + * bit 0: 1 means that slot is acquired by writer + * bit 1: 1 means that slot is ready for consumption + */ volatile int busy; char buffer[T_BUFFER_MAX]; int length; diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index 19d0a4d717..f8e92881a9 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -337,7 +337,7 @@ static void forward(void *_forwarder, char *buf, int size) static void wait_message(void) { - while (T_local_cache[T_busylist_head].busy == 0) usleep(1000); + while ((T_local_cache[T_busylist_head].busy & 0x02) == 0) usleep(1000); } void T_local_tracer_main(int remote_port, int wait_for_tracer, From 88724afdf363b97441e35c0bb74bcf55a6c49cb7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Aug 2018 15:36:45 +0200 Subject: [PATCH 10/16] T: minor: don't clean tracers on 'make clean' --- common/utils/T/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 1f845ce4f8..87a6e34c5d 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -27,4 +27,6 @@ check_vcd: clean: rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h _check_vcd + +cleanall: clean cd tracer && $(MAKE) clean From e74010220dfcbd4ca8b746ee4a6174437cf43df5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Aug 2018 15:45:38 +0200 Subject: [PATCH 11/16] bugfix: fix duplicated code As reported by Robert Schmidt. --- targets/RT/USER/lte-softmodem.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 699bc7f56b..e84f99e67f 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1131,13 +1131,6 @@ int main( int argc, char **argv ) rt_sleep_ns(10*100000000ULL); - if (nfapi_mode) { - - printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - } - if (nfapi_mode) { printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); From 69338c694b04cb2ad1a3c69d5b5a97fbc3a762c2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Aug 2018 15:55:04 +0200 Subject: [PATCH 12/16] bugfix: fix array index As reported by Konstantinos Alexandris and Robert Schmidt. --- openair2/ENB_APP/enb_config.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2b6931effa..737397d8d4 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2355,12 +2355,12 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { #endif } if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1; + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1; + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1; - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1; + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; } } From dc9c27a33093fc99f97bc6afb53623a7f1c3d570 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 14 Aug 2018 12:38:56 +0200 Subject: [PATCH 13/16] CI: improvements -- no more -x option at compilation time -- iperf server report crash better handled -- python executor retrieve iperf server files in case of failure to analyze -- comparison w/ requested bandwidth Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 185 ++++++++++++++++-- ci-scripts/xml_files/enb_usrp210_band7.xml | 2 +- .../xml_files/test_case_list_template.xml | 4 +- 3 files changed, 175 insertions(+), 16 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 372d4aef11..c3155c7699 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -154,6 +154,34 @@ class SSHConnection(): else: logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m') + def copy(self, ipaddress, username, password, source, destination): + logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) + scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5) + scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0: + scp_spawn.sendline('yes') + scp_spawn.expect('password:') + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0: + pass + else: + logging.debug('1 - scp_response = ' + str(scp_response)) + sys.exit('SCP failed') + elif scp_response == 1: + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0 or scp_response == 3: + pass + else: + logging.debug('2 - scp_response = ' + str(scp_response)) + sys.exit('SCP failed') + elif scp_response == 2: + pass + else: + logging.debug('3 - scp_response = ' + str(scp_response)) + sys.exit('SCP failed') + def BuildeNB(self): if self.eNBIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '': Usage() @@ -274,7 +302,7 @@ class SSHConnection(): loopCounter = loopCounter - 1 if (loopCounter == 0): doLoop = False - logging.debug('\u001B[1;37;43m eNB logging system did not show got sync! See with attach later \u001B[0m') + logging.debug('\u001B[1;30;43m eNB logging system did not show got sync! See with attach later \u001B[0m') self.CreateHtmlTestRow(config_file, 'eNB not showing got sync!', 0) # Not getting got sync is bypassed for the moment #sys.exit(1) @@ -672,18 +700,11 @@ class SSHConnection(): result = re.search('Server Report:', str(self.ssh.before)) if result is None: result = re.search('read failed: Connection refused', str(self.ssh.before)) - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) if result is not None: logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m') - statusQueue.put('Could not connect to iperf server!') else: logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') - statusQueue.put('Server Report and Connection refused Not Found!') - lock.release() - return + return -1 result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) (\((?P[0-9\.]+)%\))', str(self.ssh.before)) if result is not None: bitrate = result.group('bitrate') @@ -714,6 +735,121 @@ class SSHConnection(): statusQueue.put(UE_IPAddress) statusQueue.put(msg) lock.release() + return 0 + + def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): + if (not os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put('Could not analyze from server log') + lock.release() + return + # Computing the requested bandwidth in float + result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) + if result is None: + logging.debug('Iperf bandwidth Not Found!') + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put('Could not compute Iperf bandwidth!') + lock.release() + return + else: + req_bandwidth = result.group('iperf_bandwidth') + req_bw = float(req_bandwidth) + result = re.search('-b [0-9\.]+K', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Kbits/sec' % req_bw + req_bw = req_bw * 1000 + result = re.search('-b [0-9\.]+M', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Mbits/sec' % req_bw + req_bw = req_bw * 1000000 + result = re.search('-b [0-9\.]+G', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Gbits/sec' % req_bw + req_bw = req_bw * 1000000000 + + server_file = open('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', 'r') + br_sum = 0.0 + ji_sum = 0.0 + pl_sum = 0 + ps_sum = 0 + row_idx = 0 + for line in server_file.readlines(): + result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(?P[0-9]+)/ +(?P[0-9]+)', str(line)) + if result is not None: + bitrate = result.group('bitrate') + jitter = result.group('jitter') + packetlost = result.group('lostPack') + packetsent = result.group('sentPack') + br = bitrate.split(' ') + ji = jitter.split(' ') + row_idx = row_idx + 1 + curr_br = float(br[0]) + pl_sum = pl_sum + int(packetlost) + ps_sum = ps_sum + int(packetsent) + if (br[1] == 'Kbits/sec'): + curr_br = curr_br * 1000 + if (br[1] == 'Mbits/sec'): + curr_br = curr_br * 1000 * 1000 + br_sum = curr_br + br_sum + ji_sum = float(ji[0]) + ji_sum + if (row_idx > 0): + br_sum = br_sum / row_idx + ji_sum = ji_sum / row_idx + br_loss = 100 * br_sum / req_bw + if (br_sum > 1000): + br_sum = br_sum / 1000 + if (br_sum > 1000): + br_sum = br_sum / 1000 + bitrate = '%.2f Mbits/sec' % br_sum + else: + bitrate = '%.2f Kbits/sec' % br_sum + else: + bitrate = '%.2f bits/sec' % br_sum + bitperf = '%.2f ' % br_loss + bitperf += '%' + jitter = '%.2f ms' % (ji_sum) + if (ps_sum > 0): + pl = float(100 * pl_sum / ps_sum) + packetloss = '%2.1f ' % (pl) + packetloss += '%' + else: + packetloss = 'unknown' + lock.acquire() + if (br_loss < 90): + statusQueue.put(1) + else: + statusQueue.put(0) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + req_msg = 'Req Bitrate : ' + req_bandwidth + bir_msg = 'Bitrate : ' + bitrate + brl_msg = 'Bitrate Perf: ' + bitperf + jit_msg = 'Jitter : ' + jitter + pal_msg = 'Packet Loss : ' + packetloss + statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n') + logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m') + logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') + lock.release() + else: + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put('Could not analyze from server log') + lock.release() + + server_file.close() + def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue): result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', str(self.ssh.before)) @@ -780,12 +916,18 @@ class SSHConnection(): self.command('rm -f iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue) + clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue) # Launch iperf server on EPC side self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5) self.close() + if (clientStatus == -1): + time.sleep(1) + if (os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log') + self.copy(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') + self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): try: @@ -843,11 +985,12 @@ class SSHConnection(): if (useIperf3): self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + clientStatus = 0 self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) else: self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue) + clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue) self.close() self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) @@ -857,6 +1000,12 @@ class SSHConnection(): pid_iperf = result.group('pid') self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) self.close() + if (clientStatus == -1): + time.sleep(1) + if (os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log') + self.copy(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') + self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) except: os.kill(os.getppid(),signal.SIGUSR1) @@ -887,17 +1036,22 @@ class SSHConnection(): sys.exit(1) else: iperf_status = True + iperf_noperf = False html_queue = SimpleQueue() while (not status_queue.empty()): count = status_queue.get() if (count < 0): iperf_status = False + if (count > 0): + iperf_noperf = True device_id = status_queue.get() ip_addr = status_queue.get() message = status_queue.get() html_cell = "
UE (" + device_id + ")\nIP Address  : " + ip_addr + "\n" + message + "
" html_queue.put(html_cell) - if (iperf_status): + if (iperf_noperf and iperf_status): + self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + elif (iperf_status): self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) else: self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) @@ -1263,6 +1417,7 @@ class SSHConnection(): def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): + addOrangeBK = False self.htmlFile.write(' \n') self.htmlFile.write(' ' + SSH.testCase_id + '\n') self.htmlFile.write(' ' + SSH.desc + '\n') @@ -1272,12 +1427,16 @@ class SSHConnection(): elif (str(status) == 'KO'): self.htmlFile.write(' ' + str(status) + '\n') else: + addOrangeBK = True self.htmlFile.write(' ' + str(status) + '\n') i = 0 while (i < self.htmlUEConnected): if (i < ue_status): if (not ue_queue.empty()): - self.htmlFile.write(' ' + str(ue_queue.get()) + '\n') + if (addOrangeBK): + self.htmlFile.write(' ' + str(ue_queue.get()) + '\n') + else: + self.htmlFile.write(' ' + str(ue_queue.get()) + '\n') else: self.htmlFile.write(' -\n') else: diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index 7a56cf384c..0bb8d53fcb 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -27,7 +27,7 @@ Build_eNB Build eNB (USRP) - -w USRP -x -c --eNB + -w USRP -c --eNB diff --git a/ci-scripts/xml_files/test_case_list_template.xml b/ci-scripts/xml_files/test_case_list_template.xml index bc06dc75ce..25519dcd03 100644 --- a/ci-scripts/xml_files/test_case_list_template.xml +++ b/ci-scripts/xml_files/test_case_list_template.xml @@ -29,13 +29,13 @@ Build_eNB Build eNB (USRP) - -w USRP -x -c --eNB + -w USRP -c --eNB Build_eNB Build eNB (USRP) - -w BLADERF -x -c --eNB + -w BLADERF -c --eNB From ee143ac044860ec1376b4ddc762dc8adef2c68b3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 21 Aug 2018 15:04:40 +0200 Subject: [PATCH 14/16] CI: fixing and adding more testcases Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_usrp210_band7.xml | 28 ++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index 0bb8d53fcb..2871b00dee 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -21,7 +21,7 @@ --> - 010101 050101 060101 070101 040101 030101 040301 040501 040601 040602 040603 040604 040605 040641 040401 040201 030201 030111 040301 040511 040611 040612 040613 040614 040615 040651 040401 040201 030201 030121 040301 040521 040621 040622 040623 040661 040401 040201 030201 + 010101 050101 060101 070101 040101 030101 040301 040501 040601 040602 040603 040604 040605 040641 040642 040401 040201 030201 030111 040301 040511 040611 040612 040613 040614 040615 040651 040652 040401 040201 030201 030121 040301 040521 040621 040622 040623 040624 040625 040661 040662 040401 040201 030201 @@ -138,6 +138,14 @@ 50 + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(60 sec)(single-ue profile) + -u -b 9M -t 60 -i 1 -R + 50 + single-ue + + Iperf iperf (10MHz - DL/10Mbps/UDP)(60 sec) @@ -182,6 +190,14 @@ 50 + + Iperf + iperf (10MHz - UL/20Mbps/UDP)(60 sec)(single-ue profile) + -u -b 20M -t 60 -i 1 -R + 50 + single-ue + + Iperf iperf (20MHz - DL/20Mbps/UDP)(60 sec) @@ -211,7 +227,7 @@ single-ue - + Iperf iperf (20MHz - DL/70Mbps/UDP)(60 sec)(unbalanced profile) -u -b 70M -t 60 -i 1 @@ -226,6 +242,14 @@ 50 + + Iperf + iperf (20MHz - UL/20Mbps/UDP)(60 sec)(single-ue profile) + -u -b 20M -t 60 -i 1 -R + 50 + single-ue + + Initialize_HSS Initialize HSS From 4bf6f26d494dc620bfdd9dd294fb99f27071e385 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 22 Aug 2018 10:19:14 +0200 Subject: [PATCH 15/16] CI: inverted last iperf UL @20MHz fix main.py help message Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 4 ++-- ci-scripts/xml_files/enb_usrp210_band7.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index c3155c7699..83516d3358 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1455,8 +1455,8 @@ def Usage(): print(' --help Show this help.') print(' --mode=[Mode]') print(' TesteNB') - print(' TerminateeNB, TerminateEPC') - print(' LogCollectBuild, LogCollecteNB, LogCollectEPC, LogCollectADB') + print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW') + print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf') print(' --eNBIPAddress=[eNB\'s IP Address]') print(' --eNBRepository=[eNB\'s Repository URL]') print(' --eNBBranch=[eNB\'s Branch Name]') diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index 2871b00dee..444f91f094 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -21,7 +21,7 @@ --> - 010101 050101 060101 070101 040101 030101 040301 040501 040601 040602 040603 040604 040605 040641 040642 040401 040201 030201 030111 040301 040511 040611 040612 040613 040614 040615 040651 040652 040401 040201 030201 030121 040301 040521 040621 040622 040623 040624 040625 040661 040662 040401 040201 030201 + 010101 050101 060101 070101 040101 030101 040301 040501 040601 040602 040603 040604 040605 040641 040642 040401 040201 030201 030111 040301 040511 040611 040612 040613 040614 040615 040651 040652 040401 040201 030201 030121 040301 040521 040621 040622 040623 040624 040625 040662 040661 040401 040201 030201 From 0c83df3ff9939f508bea2bfab706b56bdb8f399c Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 22 Aug 2018 19:15:43 +0200 Subject: [PATCH 16/16] CI: added support for extra options to start eNB added more statistics on iperf server report analysis Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 53 +++++++++++++++++++--- ci-scripts/xml_files/enb_usrp210_band7.xml | 6 +-- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 83516d3358..c453558790 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -282,7 +282,13 @@ class SSHConnection(): self.command('cd ' + self.eNBSourceCodePath, '\$', 5) # Initialize_eNB_args usually start with -O and followed by the location in repository full_config_file = self.Initialize_eNB_args.replace('-O ','') - config_path, config_file = os.path.split(full_config_file) + extIdx = full_config_file.find('.conf') + if (extIdx > 0): + extra_options = full_config_file[extIdx + 5:] + full_config_file = full_config_file[:extIdx + 5] + config_path, config_file = os.path.split(full_config_file) + else: + sys.exit('Insufficient Parameter') ci_full_config_file = config_path + '/ci-' + config_file # Make a copy and adapt to EPC / eNB IP addresses self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) @@ -292,7 +298,7 @@ class SSHConnection(): # Launch eNB with the modified config file self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) - self.command('echo "./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + '" > ./my-lte-softmodem-run.sh ', '\$', 5) + self.command('echo "./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run.sh ', '\$', 5) self.command('chmod 775 ./my-lte-softmodem-run.sh ', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '.log ./my-lte-softmodem-run.sh', '\$', 5) time.sleep(6) @@ -696,7 +702,7 @@ class SSHConnection(): sys.exit(1) return result - def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue): + def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): result = re.search('Server Report:', str(self.ssh.before)) if result is None: result = re.search('read failed: Connection refused', str(self.ssh.before)) @@ -705,6 +711,24 @@ class SSHConnection(): else: logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') return -1 + # Computing the requested bandwidth in float + result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) + if result is not None: + req_bandwidth = result.group('iperf_bandwidth') + req_bw = float(req_bandwidth) + result = re.search('-b [0-9\.]+K', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Kbits/sec' % req_bw + req_bw = req_bw * 1000 + result = re.search('-b [0-9\.]+M', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Mbits/sec' % req_bw + req_bw = req_bw * 1000000 + result = re.search('-b [0-9\.]+G', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Gbits/sec' % req_bw + req_bw = req_bw * 1000000000 + result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) (\((?P[0-9\.]+)%\))', str(self.ssh.before)) if result is not None: bitrate = result.group('bitrate') @@ -713,10 +737,27 @@ class SSHConnection(): lock.acquire() logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') iperfStatus = True - msg = '' + msg = 'Req Bitrate : ' + req_bandwidth + '\n' + logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m') if bitrate is not None: msg += 'Bitrate : ' + bitrate + '\n' logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') + result = re.search('(?P[0-9\.]+) [KMG]bits/sec', str(bitrate)) + if result is not None: + actual_bw = float(str(result.group('real_bw'))) + result = re.search('[0-9\.]+ K', bitrate) + if result is not None: + actual_bw = actual_bw * 1000 + result = re.search('[0-9\.]+ M', bitrate) + if result is not None: + actual_bw = actual_bw * 1000000 + result = re.search('[0-9\.]+ G', bitrate) + if result is not None: + actual_bw = actual_bw * 1000000000 + br_loss = 100 * actual_bw / req_bw + bitperf = '%.2f ' % br_loss + msg += 'Bitrate Perf: ' + bitperf + '%\n' + logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m') if packetloss is not None: msg += 'Packet Loss : ' + packetloss + '%\n' logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') @@ -916,7 +957,7 @@ class SSHConnection(): self.command('rm -f iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue) + clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) # Launch iperf server on EPC side self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) @@ -990,7 +1031,7 @@ class SSHConnection(): else: self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue) + clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) self.close() self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index 444f91f094..b8a2439106 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -33,19 +33,19 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz) - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --codingw --fepw Initialize_eNB Initialize eNB (FDD/Band7/10MHz) - -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf + -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --codingw --fepw Initialize_eNB Initialize eNB (FDD/Band7/20MHz) - -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf + -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf --codingw --fepw