diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c23b0d1a91471d406910790e3c54dddb42dbc9d3..67cc6cfc3a33e7950d88c432817bae1927f526fe 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1518,7 +1518,7 @@ if (${RF_BOARD} STREQUAL "OAI_USRP") include_directories(${LIBBOOST_INCLUDE_DIR}) endif (${RF_BOARD} STREQUAL "OAI_USRP") -pkg_search_module(OPENPGM openpgm-5.1) +pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2) if(NOT ${OPENPGM_FOUND}) message("PACKAGE openpgm-5.1 is required by binaries such as oaisim: will fail later if this target is built") else() @@ -1625,7 +1625,7 @@ add_executable(lte-softmodem ${T_SOURCE} ) -target_link_libraries (lte-softmodem +target_link_libraries (lte-softmodem -ldl -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} -Wl,--end-group ) @@ -1652,8 +1652,8 @@ add_executable(lte-softmodem-nos1 ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - #${OPENAIR2_DIR}/RRC/NAS/nas_config.c # enable if you want rrc to mount ip interface - #${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${HW_SOURCE} ${TRANSPORT_SOURCE} @@ -1929,6 +1929,11 @@ foreach( d ${DirDefs} ) list(APPEND itti_compiler_options "-I${d}") endforeach() +# castxml doesn't work with c11 (gcc 5 default) +# force castxml and clang compilation with gnu89 standard +# we can't use cXX standard as pthread_rwlock_t is gnu standard +list(APPEND itti_compiler_options "-std=gnu89") + set (ITTI_H ${ITTI_DIR}/intertask_interface_types.h) add_custom_command ( OUTPUT ${OPENAIR_BIN_DIR}/messages.xml diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index d1306b804b3073f35c7b30a2bf8d15fbdc816793..04289a83fa0c1b23f233b1aac01e24295cb6e0b1 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -33,6 +33,7 @@ # brief OAI automated build tool that can be used to install, compile, run OAI. # author Navid Nikaein, Lionel GAUTHIER, Laurent Thomas +set -e ################################ # include helper functions @@ -59,6 +60,7 @@ RUN_GROUP=0 TEST_CASE_GROUP="" BUILD_DOXYGEN=0 T_TRACER="False" +DISABLE_HARDWARE_DEPENDENCY="False" trap handle_ctrl_c INT function print_help() { @@ -131,6 +133,8 @@ Options Disables CPU Affinity between UHD/TX/RX Threads (Valid only when deadline scheduler is disabled). By defaulT, CPU Affinity is enabled when not using deadline scheduler. It is enabled only with >2 CPUs. For eNB, CPU_0-> Device library (UHD), CPU_1->TX Threads, CPU_2...CPU_MAX->Rx Threads. For UE, CPU_0->Device Library(UHD), CPU_1..CPU_MAX -> All the UE threads --T-tracer Enables the T tracer. +--disable-hardware-dependency + Disable HW dependency during installation Usage (first build): oaisim (eNB + UE): ./build_oai -I -g --oaisim -x --install-system-files Eurecom EXMIMO + COTS UE : ./build_oai -I -g --eNB -x --install-system-files @@ -277,6 +281,10 @@ function main() { T_TRACER="True" echo_info "Enabling the T tracer" shift 1;; + --disable-hardware-dependency) + echo_info "Disabling hardware dependency for compiling software" + DISABLE_HARDWARE_DEPENDENCY="True" + shift 1;; -h | --help) print_help exit 1;; @@ -386,10 +394,16 @@ function main() { if [ "$HW" == "OAI_USRP" ] ; then echo_info "installing packages for USRP support" check_install_usrp_uhd_driver + if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then + install_usrp_uhd_driver + fi fi if [ "$HW" == "OAI_BLADERF" ] ; then echo_info "installing packages for BLADERF support" check_install_bladerf_driver + if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then + flash_firmware_bladerf + fi fi fi diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 673ed190f03c4368ff7dd445fe37e38954081593..ac8d9f34c1541b115adae88a66e022a1bb8a7eca 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -67,7 +67,45 @@ echo_warning() { cecho "$*" $yellow ;} echo_success() { cecho "$*" $green ;} echo_info() { cecho "$*" $blue ;} +######################## +# distribution helpers # +######################## + +# This function return a string to identify the distribution we are running +# If we can't check the distribution, it returns "Unknown" +# This function return always true as exit code by design +# Examples: +# Ubuntu16.04 +# Debian8.5 +get_distribution_release() { + local distributor + if distributor=$(lsb_release -si 2>/dev/null) ; then + echo $distributor$(lsb_release -sr) + else + echo Unknown + fi +} + +check_supported_distribution() { + local distribution=$(get_distribution_release) + case "$distribution" in + "Ubuntu16.04") return 0 ;; + "Ubuntu14.04") return 0 ;; + esac + return 1 +} +################## +# Error handlers # +################## + +handler_EXIT() { + local exit_code=$? + [ "$exit_code" -eq 0 ] || echo_error "build have failed" + exit $exit_code +} + +trap handler_EXIT EXIT ########################### # Cleaners @@ -109,6 +147,7 @@ clean_all_files() { compilations() { cd $OPENAIR_DIR/cmake_targets/$1/build + set +e { rm -f $3 if [ "$VERBOSE_COMPILE" == "1" ]; then @@ -118,12 +157,14 @@ compilations() { fi } > $dlog/$2.$REL.txt 2>&1 + set -e echo_info "Log file for compilation has been written to: $dlog/$2.$REL.txt" if [ -s $3 ] ; then cp $3 $4 echo_success "$2 compiled" else echo_error "$2 compilation failed" + exit 1 fi } @@ -186,23 +227,36 @@ install_gnutls_from_source(){ check_install_usrp_uhd_driver(){ #first we remove old installation - $SUDO apt-get remove uhd libuhd-dev libuhd003 uhd-host -y + $SUDO apt-get remove -y uhd || true + $SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y v=$(lsb_release -cs) $SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main" #The new USRP repository $SUDO add-apt-repository ppa:ettusresearch/uhd -y $SUDO apt-get update $SUDO apt-get -y install python python-tk libboost-all-dev libusb-1.0-0-dev - $SUDO apt-get -y install libuhd-dev libuhd003 uhd-host + $SUDO apt-get -y install libuhd-dev libuhd003 +} + +install_usrp_uhd_driver() { + # We move uhd-host apart because it depends on linux kernel version + # On newer kernels, it fails to install + $SUDO apt-get -y install uhd-host $SUDO uhd_images_downloader } + check_install_bladerf_driver(){ - $SUDO add-apt-repository -y ppa:bladerf/bladerf - $SUDO apt-get update + if [ "$(get_distribution_release)" == "Ubuntu14.04" ] ; then + $SUDO add-apt-repository -y ppa:bladerf/bladerf + $SUDO apt-get update + fi $SUDO apt-get install -y bladerf libbladerf-dev $SUDO apt-get install -y bladerf-firmware-fx3 $SUDO apt-get install -y bladerf-fpga-hostedx40 - $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img +} + +flash_firmware_bladerf() { + $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img } check_install_additional_tools (){ @@ -228,12 +282,15 @@ check_install_additional_tools (){ ctags \ ntpdate \ iperf3 \ - android-tools-adb + android-tools-adb \ + wvdial \ + python-numpy \ + sshpass $SUDO pip install paramiko $SUDO pip install pyroute2 $SUDO rm -fr /opt/ssh - $SUDO git clone https://gist.github.com/2190472.git /opt/ssh + $SUDO GIT_SSL_NO_VERIFY=true git clone https://gist.github.com/2190472.git /opt/ssh log_netiface=$OPENAIR_DIR/cmake_targets/log/netiface_install_log.txt echo_info "Installing Netinterfaces package. The logfile for installation is in $log_netiface" @@ -248,8 +305,26 @@ check_install_additional_tools (){ } check_install_oai_software() { + local specific_packages="" + if ! check_supported_distribution; then + echo_error "Your distribution $(get_distribution_release) is not supported by oai !" + exit 1 + fi $SUDO apt-get update + $SUDO apt install -y software-properties-common + case "$(get_distribution_release)" in + "Ubuntu14.04") + specific_packages="libtasn1-3-dev" + # For iperf3 + $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe" + $SUDO apt-get update + ;; + "Ubuntu16.04") + specific_packages="libtasn1-6-dev" + ;; + esac $SUDO apt-get install -y \ + $specific_packages \ autoconf \ automake \ bison \ @@ -273,9 +348,9 @@ check_install_oai_software() { iptables-dev \ libatlas-base-dev \ libatlas-dev \ - libblas3gf \ libblas-dev \ libconfig8-dev \ + libffi-dev \ libforms-bin \ libforms-dev \ libgcrypt11-dev \ @@ -285,16 +360,16 @@ check_install_oai_software() { libidn11-dev \ libmysqlclient-dev \ liboctave-dev \ - libpgm-5.1 \ libpgm-dev \ + libpython2.7-dev \ libsctp1 \ libsctp-dev \ libssl-dev \ - libtasn1-3-dev \ libtool \ libusb-1.0-0-dev \ libxml2 \ libxml2-dev \ + libxslt1-dev \ linux-headers-`uname -r` \ mscgen \ octave \ @@ -307,11 +382,7 @@ check_install_oai_software() { xmlstarlet \ python-pip \ pydb \ - wvdial \ - python-numpy \ - sshpass \ - libxslt1-dev \ - android-tools-adb + wget $SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so @@ -337,6 +408,7 @@ install_asn1c_from_source(){ ./configure make -j`nproc` $SUDO make install + cd - ) > $asn1_install_log 2>&1 } diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a52d9a36677c9d9d15f873b7f0f874248b55c86c --- /dev/null +++ b/common/utils/T/.gitignore @@ -0,0 +1,12 @@ +*.o +*.a +T_IDs.h +T_messages.txt.h +genids +tracer/enb +tracer/extract_config +tracer/record +tracer/replay +tracer/textlog +tracer/vcd +tracee/tracee diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 786b3722ed21c98b2734a126b077ed42a3f2295c..5d84afa6607f897329b0c71858014dca08f42f36 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -1,5 +1,4 @@ #include "T.h" -#include "T_messages.txt.h" #include <string.h> #include <stdlib.h> #include <unistd.h> @@ -108,19 +107,17 @@ static void monitor_and_kill(int child1, int child2) exit(0); } -void T_init(int remote_port, int wait_for_tracer) +void T_init(int remote_port, int wait_for_tracer, int dont_fork) { int socket_pair[2]; int s; int T_shm_fd; - unsigned char *buf; - int len; int child1, child2; if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) { perror("socketpair"); abort(); } - /* child1 runs the local tracer and child2 runs the tracee */ + /* child1 runs the local tracer and child2 (or main) runs the tracee */ child1 = fork(); if (child1 == -1) abort(); if (child1 == 0) { @@ -130,10 +127,12 @@ void T_init(int remote_port, int wait_for_tracer) } close(socket_pair[0]); - child2 = fork(); if (child2 == -1) abort(); - if (child2 != 0) { - close(socket_pair[1]); - monitor_and_kill(child1, child2); + if (dont_fork == 0) { + child2 = fork(); if (child2 == -1) abort(); + if (child2 != 0) { + close(socket_pair[1]); + monitor_and_kill(child1, child2); + } } s = socket_pair[1]; @@ -153,29 +152,4 @@ void T_init(int remote_port, int wait_for_tracer) close(T_shm_fd); new_thread(T_receive_thread, NULL); - - /* trace T_message.txt - * Send several messages -1 with content followed by message -2. - * We can't use the T macro directly, events -1 and -2 are special. - */ - buf = T_messages_txt; - len = T_messages_txt_len; - while (len) { - int send_size = len; - if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int)) - send_size = T_PAYLOAD_MAXSIZE - sizeof(int); - do { - T_LOCAL_DATA - T_HEADER(T_ID(-1)); - T_PUT_buffer(1, ((T_buffer){addr:(buf), length:(len)})); - T_COMMIT(); - } while (0); - buf += send_size; - len -= send_size; - } - do { - T_LOCAL_DATA - T_HEADER(T_ID(-2)); - T_COMMIT(); - } while (0); } diff --git a/common/utils/T/T.h b/common/utils/T/T.h index a5aacb4b4f8e7ba121eb29078992e9a890740829..819615131e77cc72cf36d1f060ad61b8d1f8e2d2 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -562,7 +562,7 @@ extern T_cache_t *T_cache; extern int *T_active; -void T_init(int remote_port, int wait_for_tracer); +void T_init(int remote_port, int wait_for_tracer, int dont_fork); #else /* T_TRACER */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 5678b588ba5c649f2e7d9c5ded9d76a466ce3868..05c08085c62558544725b4ad4580c663f17c9de0 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -52,7 +52,7 @@ ID = ENB_PHY_UL_CHANNEL_ESTIMATE ID = ENB_PHY_PUSCH_IQ DESC = eNodeB PUSCH received IQ data GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB - FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : buffer,pusch_comp + FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp ID = ENB_PHY_PUCCH_1AB_IQ DESC = eNodeB PUCCH received IQ data GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB @@ -79,10 +79,18 @@ ID = ENB_MAC_UE_UL_PDU DESC = MAC uplink UE received PDU GROUP = ALL:MAC:ENB FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,sdu_length : int,num_ce : int,num_sdu +ID = ENB_MAC_UE_UL_PDU_WITH_DATA + DESC = MAC uplink UE received PDU + GROUP = ALL:MAC:ENB:HEAVY + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,sdu_length : int,num_ce : int,num_sdu : buffer,data ID = ENB_MAC_UE_UL_SDU DESC = MAC uplink UE received SDU GROUP = ALL:MAC:ENB FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,lcid : int,length +ID = ENB_MAC_UE_UL_SDU_WITH_DATA + DESC = MAC uplink UE received SDU + GROUP = ALL:MAC:ENB:HEAVY + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,lcid : int,length : buffer,data ID = ENB_MAC_UE_UL_CE DESC = MAC uplink UE received control element GROUP = ALL:MAC:ENB diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index 93a56a9e3d41aa2ecd8f41aa617fe55c292c055e..68a937a6b56e80fe90d8a3ea27fc8cf3123af145 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -11,10 +11,12 @@ #include <inttypes.h> #include <signal.h> +#include "T.h" +#include "T_messages.txt.h" #include "T_defs.h" #include "T_IDs.h" -static T_cache_t *T_cache; +static T_cache_t *T_local_cache; static int T_busylist_head; typedef struct databuf { @@ -85,6 +87,38 @@ static int get_connection(char *addr, int port) return t; } +static void forward(void *_forwarder, char *buf, int size); + +void send_T_messages_txt(void *forwarder) +{ + char buf[T_BUFFER_MAX]; + char *T_LOCAL_buf = buf; + int T_LOCAL_size; + unsigned char *src; + int src_len; + + /* trace T_message.txt + * Send several messages -1 with content followed by message -2. + */ + src = T_messages_txt; + src_len = T_messages_txt_len; + while (src_len) { + int send_size = src_len; + if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int)) + send_size = T_PAYLOAD_MAXSIZE - sizeof(int); + /* TODO: be careful, we use internal T stuff, to rewrite? */ + T_LOCAL_size = 0; + T_HEADER(T_ID(-1)); + T_PUT_buffer(1, ((T_buffer){addr:(src), length:(send_size)})); + forward(forwarder, buf, T_LOCAL_size); + src += send_size; + src_len -= send_size; + } + T_LOCAL_size = 0; + T_HEADER(T_ID(-2)); + forward(forwarder, buf, T_LOCAL_size); +} + /****************************************************************************/ /* forward functions */ /****************************************************************************/ @@ -213,6 +247,7 @@ dead: close(f->socket_remote); f->socket_remote = get_connection("0.0.0.0", f->remote_port); + send_T_messages_txt(f); goto again; return NULL; @@ -237,6 +272,7 @@ static void *forwarder(int port, int s) f->remote_port = port; f->socket_remote = get_connection("0.0.0.0", port); + send_T_messages_txt(f); new_thread(data_sender, f); new_thread(forward_remote_messages, f); @@ -287,7 +323,7 @@ static void forward(void *_forwarder, char *buf, int size) static void wait_message(void) { - while (T_cache[T_busylist_head].busy == 0) usleep(1000); + while (T_local_cache[T_busylist_head].busy == 0) usleep(1000); } static void init_shm(void) @@ -297,17 +333,17 @@ static void init_shm(void) if (s == -1) { perror(T_SHM_FILENAME); abort(); } if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) { perror(T_SHM_FILENAME); abort(); } - T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), - PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); - if (T_cache == NULL) + T_local_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), + PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); + if (T_local_cache == NULL) { perror(T_SHM_FILENAME); abort(); } close(s); /* let's garbage the memory to catch some potential problems * (think multiprocessor sync issues, barriers, etc.) */ - memset(T_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t)); - for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0; + memset(T_local_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t)); + for (i = 0; i < T_CACHE_SIZE; i++) T_local_cache[i].busy = 0; } void T_local_tracer_main(int remote_port, int wait_for_tracer, @@ -335,9 +371,9 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer, while (1) { wait_message(); __sync_synchronize(); - forward(f, T_cache[T_busylist_head].buffer, - T_cache[T_busylist_head].length); - T_cache[T_busylist_head].busy = 0; + forward(f, T_local_cache[T_busylist_head].buffer, + T_local_cache[T_busylist_head].length); + T_local_cache[T_busylist_head].busy = 0; T_busylist_head++; T_busylist_head &= T_CACHE_SIZE - 1; } diff --git a/common/utils/T/tracee/Makefile b/common/utils/T/tracee/Makefile index 703d49d029ae914638b0c1fd2ba7e56dbc349216..10ea3bdca3c80b8256c9b0601c0ed7f5439e5e6d 100644 --- a/common/utils/T/tracee/Makefile +++ b/common/utils/T/tracee/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -DT_TRACER -I. PROG=tracee -OBJS=tracee.o ../T.o +OBJS=tracee.o ../T.o ../local_tracer.o $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) -lrt diff --git a/common/utils/T/tracee/tracee.c b/common/utils/T/tracee/tracee.c index b4b73b9e67fa036e92def856a7328d5c197d4cb4..5f820ee42eecf5eb60fdb9669bf66cfa867db5df 100644 --- a/common/utils/T/tracee/tracee.c +++ b/common/utils/T/tracee/tracee.c @@ -6,7 +6,7 @@ int main(void) { int frame = 0; - T_connect_to_tracer("127.0.0.1", 2020); + T_init(2021, 1, 0); while (1) { getchar(); T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(0), T_INT(0), T_INT(frame), T_INT(0), T_INT(0), T_INT(0)); diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index bf0f72710cd04b4c4cb4a170a1a89fa51be5f2d8..ee289aae59636c629934de82eddbedf0932d832d 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -5,7 +5,16 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. LIBS=-lX11 -lm -lpng -lXft -all: textlog enb vcd +all: record replay extract_config textlog enb vcd + +record: utils.o record.o database.o config.o + $(CC) $(CFLAGS) -o record $^ $(LIBS) + +replay: utils.o replay.o + $(CC) $(CFLAGS) -o replay $^ $(LIBS) + +extract_config: extract_config.o + $(CC) $(CFLAGS) -o extract_config $^ $(LIBS) textlog: utils.o textlog.o database.o event.o handler.o config.o \ event_selector.o view/view.a gui/gui.a logger/logger.a \ @@ -40,8 +49,10 @@ filter/filter.a: $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f *.o core tracer_remote textlog enb vcd + rm -f *.o core tracer_remote textlog enb vcd record replay + rm -f extract_config cd gui && make clean cd view && make clean cd logger && make clean cd filter && make clean + cd hacks && make clean diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index f43e1d67077a0e4237210e0256b87bba18a0c494..b0ae285f6d0948e5d4fdcccfa93a86d3843d7090 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -33,9 +33,6 @@ typedef struct { pthread_mutex_t lock; } enb_data; -#define DEFAULT_REMOTE_IP "127.0.0.1" -#define DEFAULT_REMOTE_PORT 2021 - void is_on_changed(void *_d) { enb_data *d = _d; @@ -116,8 +113,11 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) widget *text; view *textview; int i; + widget *w; + view *v; + logger *l; - main_window = new_toplevel_window(g, 800, 600, "eNB tracer"); + main_window = new_toplevel_window(g, 1200, 900, "eNB tracer"); top_container = new_container(g, VERTICAL); widget_add_child(g, main_window, top_container, -1); @@ -135,9 +135,39 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) */ framelog_set_skip(input_signal_log, 10); input_signal_view = new_view_xy(7680*10, 10, - g, input_signal_plot, new_color(g, "#0c0c72")); + g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE); logger_add_view(input_signal_log, input_signal_view); + /* UE 0 PUSCH IQ data */ + w = new_xy_plot(g, 55, 55, "PUSCH IQ", 50); + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, -1000, 1000, -1000, 1000); + l = new_iqlog(h, database, "ENB_PHY_PUSCH_IQ", "nb_rb", + "N_RB_UL", "symbols_per_tti", "pusch_comp"); + v = new_view_xy(100*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "ENB_PHY_PUSCH_IQ", "UE_ID"), + filter_int(0) + )); + + /* UE 0 estimated UL channel */ + w = new_xy_plot(g, 256*2, 55, "UL estimated channel", 50); + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, 0, 512*10, -10, 80); + l = new_framelog(h, database, + "ENB_PHY_UL_CHANNEL_ESTIMATE", "subframe", "chest_t"); + //framelog_set_skip(input_signal_log, 10); + framelog_set_update_only_at_sf9(l, 0); + v = new_view_xy(512*10, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "ENB_PHY_UL_CHANNEL_ESTIMATE", "UE_ID"), + filter_int(0) + )); + /* downlink/uplink UE DCIs */ widget_add_child(g, top_container, new_label(g,"DL/UL TICK/DCI/ACK/NACK "), -1); @@ -440,14 +470,16 @@ int main(int n, char **v) logger *textlog; char *name, *desc; database_get_generic_description(database, i, &name, &desc); - if (strncmp(name, "LEGACY_", 7) != 0) continue; - textlog = new_textlog(h, database, name, desc); - logger_add_view(textlog, eg.legacy); + if (!strncmp(name, "LEGACY_", 7)) { + textlog = new_textlog(h, database, name, desc); + logger_add_view(textlog, eg.legacy); + } free(name); free(desc); } on_off(database, "ENB_PHY_INPUT_SIGNAL", is_on, 1); + on_off(database, "ENB_PHY_UL_CHANNEL_ESTIMATE", is_on, 1); on_off(database, "ENB_PHY_DL_TICK", is_on, 1); on_off(database, "ENB_PHY_DLSCH_UE_DCI", is_on, 1); on_off(database, "ENB_PHY_DLSCH_UE_ACK", is_on, 1); @@ -458,6 +490,7 @@ int main(int n, char **v) on_off(database, "ENB_PHY_ULSCH_UE_ACK", is_on, 1); on_off(database, "ENB_PHY_ULSCH_UE_NACK", is_on, 1); on_off(database, "ENB_MASTER_TICK", is_on, 1); + on_off(database, "ENB_PHY_PUSCH_IQ", is_on, 1); on_off(database, "LEGACY_RRC_INFO", is_on, 1); on_off(database, "LEGACY_RRC_ERROR", is_on, 1); @@ -477,7 +510,9 @@ int main(int n, char **v) view_add_log(eg.macview, "ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION", h, database, is_on); view_add_log(eg.macview, "ENB_MAC_UE_UL_PDU", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_PDU_WITH_DATA", h, database, is_on); view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU_WITH_DATA", h, database, is_on); view_add_log(eg.macview, "ENB_MAC_UE_UL_CE", h, database, is_on); view_add_log(eg.rlcview, "ENB_RLC_DL", h, database, is_on); @@ -545,6 +580,10 @@ int main(int n, char **v) view_add_log(eg.rrcview, "ENB_RRC_UNKNOW_MESSAGE", h, database, is_on); + /* deactivate those two by default, they are a bit heavy */ + on_off(database, "ENB_MAC_UE_UL_SDU_WITH_DATA", is_on, 0); + on_off(database, "ENB_MAC_UE_UL_PDU_WITH_DATA", is_on, 0); + for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/common/utils/T/tracer/extract_config.c b/common/utils/T/tracer/extract_config.c new file mode 100644 index 0000000000000000000000000000000000000000..f35d765cec5b3366b88eca9bd9bc85d2697a18e4 --- /dev/null +++ b/common/utils/T/tracer/extract_config.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../T_defs.h" + +void usage(void) +{ + printf( +"options:\n" +" -i <input file> this option is mandatory\n" + ); + exit(1); +} + +#define ERR printf("ERROR: read file %s failed\n", input_filename) + +int main(int n, char **v) +{ + char *input_filename = NULL; + int i; + FILE *in; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-i")) + { if (i > n-2) usage(); input_filename = v[++i]; continue; } + usage(); + } + + if (input_filename == NULL) { + printf("ERROR: provide an input file (-i)\n"); + exit(1); + } + + in = fopen(input_filename, "r"); + if (in == NULL) { perror(input_filename); abort(); } + + while (1) { + int type; + int32_t length; + char v[T_BUFFER_MAX]; + int vpos = 0; + + /* read event from file */ + if (fread(&length, 4, 1, in) != 1) break; + memcpy(v+vpos, &length, 4); + vpos += 4; +#ifdef T_SEND_TIME + if (length < sizeof(struct timespec)) { ERR; break; } + if (fread(v+vpos, sizeof(struct timespec), 1, in) != 1) { ERR; break; } + vpos += sizeof(struct timespec); + length -= sizeof(struct timespec); +#endif + if (length < sizeof(int)) { ERR; break; } + if (fread(&type, sizeof(int), 1, in) != 1) { ERR; break; } + memcpy(v+vpos, &type, sizeof(int)); + vpos += sizeof(int); + length -= sizeof(int); + if (length) if (fread(v+vpos, length, 1, in) != 1) { ERR; break; } + vpos += length; + + if (type == -1) { + if (length < sizeof(int)) { ERR; break; } + length -= sizeof(int); + if (fwrite(v+vpos-length, length, 1, stdout) != 1) { ERR; break; } + } + + /* TODO: parse all file? */ + if (type == -2) break; + } + + fclose(in); + + return 0; +} diff --git a/common/utils/T/tracer/hacks/Makefile b/common/utils/T/tracer/hacks/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ab10305c0b356c7085695c9099d1fc93492330e9 --- /dev/null +++ b/common/utils/T/tracer/hacks/Makefile @@ -0,0 +1,18 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I.. + +LIBS=-lX11 -lm -lpng -lXft + +all: dump_nack_signal + +dump_nack_signal: ../utils.o ../database.o ../config.o ../event.o \ + dump_nack_signal.o + $(CC) $(CFLAGS) -o dump_nack_signal $^ $(LIBS) + +.PHONY: all + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f *.o core dump_nack_signal diff --git a/common/utils/T/tracer/hacks/dump_nack_signal.c b/common/utils/T/tracer/hacks/dump_nack_signal.c new file mode 100644 index 0000000000000000000000000000000000000000..1627bdd14e925ad68797d16614be9e57bc23447e --- /dev/null +++ b/common/utils/T/tracer/hacks/dump_nack_signal.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "utils.h" +#include "event.h" +#include "database.h" +#include "config.h" +#include "../T_defs.h" + +void usage(void) +{ + printf( +"options:\n" +" -d <database file> this option is mandatory\n" +" -ip <host> connect to given IP address (default %s)\n" +" -p <port> connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + int i; + char t; + int number_of_events; + int socket; + int *is_on; + int ev_input, ev_nack; + int ev_ack; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + on_off(database, "ENB_PHY_INPUT_SIGNAL", is_on, 1); + on_off(database, "ENB_PHY_ULSCH_UE_NACK", is_on, 1); + on_off(database, "ENB_PHY_ULSCH_UE_ACK", is_on, 1); + + ev_input = event_id_from_name(database, "ENB_PHY_INPUT_SIGNAL"); + ev_nack = event_id_from_name(database, "ENB_PHY_ULSCH_UE_NACK"); + ev_ack = event_id_from_name(database, "ENB_PHY_ULSCH_UE_ACK"); + + socket = connect_to(ip, port); + + t = 1; + if (socket_send(socket, &t, 1) == -1 || + socket_send(socket, &number_of_events, sizeof(int)) == -1 || + socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) + abort(); + + char dump[10][T_BUFFER_MAX]; + event dump_ev[10]; +FILE *z = fopen("/tmp/dd", "w"); if (z == NULL) abort(); + while (1) { + char v[T_BUFFER_MAX]; + event e; + e = get_event(socket, v, database); + if (e.type == -1) break; + if (e.type == ev_input) { + int sf = e.e[2].i; + memcpy(dump[sf], v, T_BUFFER_MAX); + dump_ev[sf] = e; + printf("input %d/%d\n", e.e[1].i, sf); +if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort(); +fflush(z); + } + if (e.type == ev_nack) { + int sf = e.e[2].i; + printf("nack %d/%d\n", e.e[1].i, sf); + FILE *f = fopen("/tmp/dump.raw", "w"); if (f == NULL) abort(); + if (fwrite(dump[sf] + ((char *)dump_ev[sf].e[4].b - v), + dump_ev[sf].e[4].bsize, 1, f) != 1) abort(); + if (fclose(f)) abort(); + printf("dumped... press enter (delta %d)\n", (int)((char *)dump_ev[sf].e[4].b - v)); +// getchar(); + } + if (e.type == ev_ack) { + int sf = e.e[2].i; + printf("ack %d/%d\n", e.e[1].i, sf); + FILE *f = fopen("/tmp/dump.raw", "w"); if (f == NULL) abort(); + if (fwrite(dump[sf] + ((char *)dump_ev[sf].e[4].b - v), + dump_ev[sf].e[4].bsize, 1, f) != 1) abort(); + if (fclose(f)) abort(); + printf("dumped... press enter (delta %d)\n", (int)((char *)dump_ev[sf].e[4].b - v)); +// getchar(); + } + } + + return 0; +} diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile index e5391008380ccb32410dcc92a3a0788bd3ad8a45..8d23717a1329ba42cd5a156e47df673246ef13c3 100644 --- a/common/utils/T/tracer/logger/Makefile +++ b/common/utils/T/tracer/logger/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=logger.o textlog.o framelog.o ttilog.o timelog.o ticklog.o +OBJS=logger.o textlog.o framelog.o ttilog.o timelog.o ticklog.o iqlog.o logger.a: $(OBJS) ar cr logger.a $(OBJS) diff --git a/common/utils/T/tracer/logger/framelog.c b/common/utils/T/tracer/logger/framelog.c index 057960c38246b98b0e4c7be1225ec02dc9238495..45ae3e399f98dd4e1e091cf39606ad3b7ad3a88f 100644 --- a/common/utils/T/tracer/logger/framelog.c +++ b/common/utils/T/tracer/logger/framelog.c @@ -21,6 +21,7 @@ struct framelog { */ int skip_current; /* internal data for the skip mechanism */ int skip_on; /* internal data for the skip mechanism */ + int update_only_at_sf9; }; static void _event(void *p, event e) @@ -76,7 +77,7 @@ static void _event(void *p, event e) l->buffer[subframe * nsamples + i] = 10*log10(1.0+(float)(I*I+Q*Q)); } - if (subframe == 9) + if (l->update_only_at_sf9 == 0 || subframe == 9) for (i = 0; i < l->common.vsize; i++) l->common.v[i]->append(l->common.v[i], l->x, l->buffer, l->blength); } @@ -91,6 +92,8 @@ logger *new_framelog(event_handler *h, void *database, ret = calloc(1, sizeof(struct framelog)); if (ret == NULL) abort(); + ret->update_only_at_sf9 = 1; + ret->common.event_name = strdup(event_name); if (ret->common.event_name == NULL) abort(); ret->database = database; @@ -144,3 +147,9 @@ void framelog_set_skip(logger *_this, int skip_delay) l->skip_current = 0; l->skip_on = 0; } + +void framelog_set_update_only_at_sf9(logger *_this, int update_only_at_sf9) +{ + struct framelog *l = _this; + l->update_only_at_sf9 = update_only_at_sf9; +} diff --git a/common/utils/T/tracer/logger/iqlog.c b/common/utils/T/tracer/logger/iqlog.c new file mode 100644 index 0000000000000000000000000000000000000000..3d303607ac9f2faf9c0ddf91971495b1300c4e5c --- /dev/null +++ b/common/utils/T/tracer/logger/iqlog.c @@ -0,0 +1,187 @@ +#include "logger.h" +#include "logger_defs.h" +#include "handler.h" +#include "database.h" +#include "filter/filter.h" +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +struct iqlog { + struct logger common; + void *database; + int nb_rb_arg; + int N_RB_UL_arg; + int symbols_per_tti_arg; + int buffer_arg; + float *i; + float *q; + int max_length; +}; + +#if 0 +/* this function passes all received IQ samples to the views */ +static void _event(void *p, event e) +{ + struct iqlog *l = p; + int i; + void *buffer; + int bsize; + int nsamples; + + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + + buffer = e.e[l->buffer_arg].b; + bsize = e.e[l->buffer_arg].bsize; + + nsamples = bsize / (2*sizeof(int16_t)); + + if (nsamples > l->max_length) { + l->i = realloc(l->i, nsamples * sizeof(float)); + if (l->i == NULL) abort(); + l->q = realloc(l->q, nsamples * sizeof(float)); + if (l->q == NULL) abort(); + l->max_length = nsamples; + } + + for (i = 0; i < nsamples; i++) { + l->i[i] = ((int16_t *)buffer)[i*2]; + l->q[i] = ((int16_t *)buffer)[i*2+1]; + } + + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], l->i, l->q, nsamples); +} +#endif + +static void _event(void *p, event e) +{ + struct iqlog *l = p; + int i, j; + void *buffer; + int bsize; + int nb_rb; + int N_RB_UL; + int symbols_per_tti; + int max_nsamples; + float *idst, *qdst; + int count; + + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + + nb_rb = e.e[l->nb_rb_arg].i; + N_RB_UL = e.e[l->N_RB_UL_arg].i; + symbols_per_tti = e.e[l->symbols_per_tti_arg].i; + + buffer = e.e[l->buffer_arg].b; + bsize = e.e[l->buffer_arg].bsize; + + if (bsize != N_RB_UL * symbols_per_tti * 12 * 4) { + printf("%s:%d:%s: bad buffer size\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } + + max_nsamples = bsize / 4; + + if (max_nsamples > l->max_length) { + l->i = realloc(l->i, max_nsamples * sizeof(float)); + if (l->i == NULL) abort(); + l->q = realloc(l->q, max_nsamples * sizeof(float)); + if (l->q == NULL) abort(); + l->max_length = max_nsamples; + } + + idst = l->i; + qdst = l->q; + count = 0; + for (i = 0; i < symbols_per_tti; i++) + for (j = 0; j < 12 * nb_rb; j++) { + *idst = ((int16_t *)buffer)[(i*N_RB_UL*12 + j) * 2]; + *qdst = ((int16_t *)buffer)[(i*N_RB_UL*12 + j) * 2 + 1]; + idst++; + qdst++; + count++; + } + + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], l->i, l->q, count); +} + +logger *new_iqlog(event_handler *h, void *database, + char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti, + char *buffer_varname) +{ + struct iqlog *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct iqlog)); if (ret == NULL) abort(); + + ret->common.event_name = strdup(event_name); + if (ret->common.event_name == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->common.handler_id = register_handler_function(h,event_id,_event,ret); + + f = get_format(database, event_id); + + /* look for args */ + ret->nb_rb_arg = -1; + ret->N_RB_UL_arg = -1; + ret->symbols_per_tti_arg = -1; + ret->buffer_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], nb_rb)) ret->nb_rb_arg = i; + if (!strcmp(f.name[i], N_RB_UL)) ret->N_RB_UL_arg = i; + if (!strcmp(f.name[i], symbols_per_tti)) ret->symbols_per_tti_arg = i; + if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i; + } + if (ret->nb_rb_arg == -1) { + printf("%s:%d: argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, nb_rb, event_name); + abort(); + } + if (ret->N_RB_UL_arg == -1) { + printf("%s:%d: argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, N_RB_UL, event_name); + abort(); + } + if (ret->symbols_per_tti_arg == -1) { + printf("%s:%d: argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, symbols_per_tti, event_name); + abort(); + } + if (ret->buffer_arg == -1) { + printf("%s:%d: buffer argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, buffer_varname, event_name); + abort(); + } + if (strcmp(f.type[ret->nb_rb_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, nb_rb); + abort(); + } + if (strcmp(f.type[ret->N_RB_UL_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, nb_rb); + abort(); + } + if (strcmp(f.type[ret->symbols_per_tti_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, symbols_per_tti); + abort(); + } + if (strcmp(f.type[ret->buffer_arg], "buffer") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'buffer')\n", + __FILE__, __LINE__, buffer_varname); + abort(); + } + + return ret; +} diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index e3e4b97aa5e4e85844376c61663036d3f7a78b5b..a777581db91e513509a5abb0ebed9cfa359cc4e5 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -13,8 +13,14 @@ logger *new_ttilog(void *event_handler, void *database, logger *new_timelog(void *event_handler, void *database, char *event_name); logger *new_ticklog(void *event_handler, void *database, char *event_name, char *frame_name, char *subframe_name); +logger *new_iqlog(void *event_handler, void *database, + char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti, + char *buffer_varname); void framelog_set_skip(logger *_this, int skip_delay); +void framelog_set_update_only_at_sf9(logger *_this, int update_only_at_sf9); + +void textlog_dump_buffer(logger *_this, int dump_buffer); #include "view/view.h" diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index e80af7813e014c5174a01b83853a58d55179cd7c..9eb6fd02d8fbbec5d63702c4b89d80df2327fe92 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -32,12 +32,13 @@ struct textlog { int fsize; /* local output buffer */ OBUF o; + int dump_buffer; }; static void _event(void *p, event e) { struct textlog *l = p; - int i; + int i, j; #ifdef T_SEND_TIME struct tm *t; char tt[64]; @@ -65,6 +66,14 @@ static void _event(void *p, event e) case BUFFER: PUTS(&l->o, "{buffer size:"); PUTI(&l->o, e.e[l->f[i].event_arg].bsize); + if (l->dump_buffer) { + PUTS(&l->o, " ["); + for (j = 0; j < e.e[l->f[i].event_arg].bsize; j++) { + PUTX2(&l->o, ((unsigned char *)e.e[l->f[i].event_arg].b)[j]); + PUTC(&l->o, ' '); + } + PUTS(&l->o, "]"); + } PUTS(&l->o, "}"); break; } @@ -196,3 +205,13 @@ error: printf("%s:%d: bad format '%s'\n", __FILE__, __LINE__, format); abort(); } + +/****************************************************************************/ +/* public functions */ +/****************************************************************************/ + +void textlog_dump_buffer(logger *_this, int dump_buffer) +{ + struct textlog *l = _this; + l->dump_buffer = dump_buffer; +} diff --git a/common/utils/T/tracer/record.c b/common/utils/T/tracer/record.c new file mode 100644 index 0000000000000000000000000000000000000000..c81b93e7d73b89c176462bd2cbde58d150ad2371 --- /dev/null +++ b/common/utils/T/tracer/record.c @@ -0,0 +1,161 @@ +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include "database.h" +#include "utils.h" +#include "../T_defs.h" +#include "config.h" + +void usage(void) +{ + printf( +"options:\n" +" -d <database file> this option is mandatory\n" +" -o <output file> this option is mandatory\n" +" -on <GROUP or ID> turn log ON for given GROUP or ID\n" +" -off <GROUP or ID> turn log OFF for given GROUP or ID\n" +" -ON turn all logs ON\n" +" -OFF turn all logs OFF\n" +" note: you may pass several -on/-off/-ON/-OFF,\n" +" they will be processed in order\n" +" by default, all is off\n" +" -ip <host> connect to given IP address (default %s)\n" +" -p <port> connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +volatile int run = 1; + +static int socket = -1; + +void force_stop(int x) +{ + printf("\ngently quit...\n"); + close(socket); + socket = -1; + run = 0; +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + char *output_filename = NULL; + FILE *out; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int i; + char mt; + + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); + + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); + on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-o")) + { if (i > n-2) usage(); output_filename = v[++i]; continue; } + if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-ON")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-OFF")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + if (output_filename == NULL) { + printf("ERROR: provide an output file (-o)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); + + socket = connect_to(ip, port); + + /* activate selected traces */ + mt = 1; + if (socket_send(socket, &mt, 1) == -1 || + socket_send(socket, &number_of_events, sizeof(int)) == -1 || + socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) + abort(); + + out = fopen(output_filename, "w"); + if (out == NULL) { + perror(output_filename); + exit(1); + } + + /* exit on ctrl+c and ctrl+z */ + if (signal(SIGQUIT, force_stop) == SIG_ERR) abort(); + if (signal(SIGINT, force_stop) == SIG_ERR) abort(); + if (signal(SIGTSTP, force_stop) == SIG_ERR) abort(); + + /* read messages */ + while (run) { + int type; + int32_t length; + char v[T_BUFFER_MAX]; + int vpos = 0; + + if (fullread(socket, &length, 4) == -1) goto read_error; + memcpy(v+vpos, &length, 4); + vpos += 4; +#ifdef T_SEND_TIME + if (fullread(socket,v+vpos,sizeof(struct timespec))==-1) goto read_error; + vpos += sizeof(struct timespec); + length -= sizeof(struct timespec); +#endif + if (fullread(socket, &type, sizeof(int)) == -1) goto read_error; + memcpy(v+vpos, &type, sizeof(int)); + vpos += sizeof(int); + length -= sizeof(int); + if (fullread(socket, v+vpos, length) == -1) goto read_error; + vpos += length; + + if (type == -1) append_received_config_chunk(v+vpos-length, length); + if (type == -2) verify_config(); + + if (fwrite(v, vpos, 1, out) != 1) { + printf("error saving data to file %s\n", output_filename); + fclose(out); + exit(1); + } + } + +read_error: + fclose(out); + + return 0; +} diff --git a/common/utils/T/tracer/replay.c b/common/utils/T/tracer/replay.c new file mode 100644 index 0000000000000000000000000000000000000000..be7e8d60c69fefcdd562ec79c5dea01c384b92c0 --- /dev/null +++ b/common/utils/T/tracer/replay.c @@ -0,0 +1,183 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include "utils.h" +#include "../T_defs.h" + +#define DEFAULT_REMOTE_PORT 2021 + +/* replay.c does not know anything about events - it just has the array + * is_on that grows each time replay.c sees a type that does not fit in + * there (the idea is to isolate replay.c as maximum by not using unneeded + * information) + */ +int *is_on; +int is_on_size; + +/* this lock is used to protect access to is_on/is_on_size */ +pthread_mutex_t biglock = PTHREAD_MUTEX_INITIALIZER; + +void set_is_on_size(int size) +{ + is_on = realloc(is_on, size * sizeof(int)); if (is_on == NULL) abort(); + memset(is_on + is_on_size, 0, (size - is_on_size) * sizeof(int)); + is_on_size = size; +} + +void lock(void) +{ + if (pthread_mutex_lock(&biglock)) abort(); +} + +void unlock(void) +{ + if (pthread_mutex_unlock(&biglock)) abort(); +} + +#define QUIT(x) do { printf("%s\n", x); exit(1); } while(0) + +void get_message(int s) +{ + char t; + int l; + int id; + int on; + + if (read(s, &t, 1) != 1) QUIT("get_message fails"); + lock(); + switch (t) { + case 0: + /* toggle all those IDs */ + if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails"); + while (l) { + if (read(s, &id, sizeof(int)) != sizeof(int)) QUIT("get_message fails"); + if (id > is_on_size - 1) set_is_on_size(id + 1); + is_on[id] = 1 - is_on[id]; + l--; + } + break; + case 1: + /* set IDs as given */ + /* optimize? */ + if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails"); + if (l > is_on_size) set_is_on_size(l); + id = 0; + while (l) { + if (read(s, &on, sizeof(int)) != sizeof(int)) + QUIT("get_message fails"); + is_on[id] = on; + id++; + l--; + } + break; + case 2: break; /* do nothing, this message is to wait for local tracer */ + default: abort(); + } + unlock(); +} + +void *get_message_thread(void *_socket) +{ + int socket = *(int *)_socket; + + while (1) get_message(socket); + + return NULL; +} + +void usage(void) +{ + printf( +"options:\n" +" -i <input file> this option is mandatory\n" +" -p <port> wait connection on given port (default %d)\n" +" -w user must press a key after each sent event\n", + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +#define ERR printf("ERROR: read file %s failed\n", input_filename) + +int main(int n, char **v) +{ + int port = DEFAULT_REMOTE_PORT; + char *input_filename = NULL; + int i; + int socket; + FILE *in; + int do_send; + int do_wait = 0; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-i")) + { if (i > n-2) usage(); input_filename = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-w")) { do_wait = 1; continue; } + usage(); + } + + if (input_filename == NULL) { + printf("ERROR: provide an input file (-i)\n"); + exit(1); + } + + in = fopen(input_filename, "r"); + if (in == NULL) { perror(input_filename); abort(); } + + socket = get_connection("0.0.0.0", port); + + /* get first message to activate selected traces */ + get_message(socket); + + new_thread(get_message_thread, &socket); + + while (1) { + int type; + int32_t length; + char v[T_BUFFER_MAX]; + int vpos = 0; + + /* read event from file */ + if (fread(&length, 4, 1, in) != 1) break; + memcpy(v+vpos, &length, 4); + vpos += 4; +#ifdef T_SEND_TIME + if (length < sizeof(struct timespec)) { ERR; break; } + if (fread(v+vpos, sizeof(struct timespec), 1, in) != 1) { ERR; break; } + vpos += sizeof(struct timespec); + length -= sizeof(struct timespec); +#endif + if (length < sizeof(int)) { ERR; break; } + if (fread(&type, sizeof(int), 1, in) != 1) { ERR; break; } + memcpy(v+vpos, &type, sizeof(int)); + vpos += sizeof(int); + length -= sizeof(int); + if (length) if (fread(v+vpos, length, 1, in) != 1) { ERR; break; } + vpos += length; + + /* only send if configured to do so */ + lock(); + if (type < 0) do_send = 1; + else { + if (type > is_on_size - 1) set_is_on_size(type+1); + do_send = is_on[type]; + } + unlock(); + + if (do_send) + if (socket_send(socket, v, vpos) != 0) + { printf("ERROR: socket writing failed\n"); abort(); } + + if (do_send && do_wait) getchar(); + } + + fclose(in); + close(socket); + + return 0; +} diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index f11ca96bd9ea10fa29f573aac6395d94150322f4..32bf1ed791ce10060fb48b62d7f4b69c94b23ba9 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -14,9 +14,6 @@ #include "event_selector.h" #include "config.h" -#define DEFAULT_REMOTE_IP "127.0.0.1" -#define DEFAULT_REMOTE_PORT 2021 - typedef struct { int socket; int *is_on; @@ -55,6 +52,7 @@ void usage(void) " note: you may pass several -on/-off/-ON/-OFF,\n" " they will be processed in order\n" " by default, all is off\n" +" -full also dump buffers' content\n" " -ip <host> connect to given IP address (default %s)\n" " -p <port> connect to given port (default %d)\n" " -x GUI output\n" @@ -93,6 +91,7 @@ int main(int n, char **v) view *out; int gui_active = 1; textlog_data textlog_data; + int full = 0; /* write on a socket fails if the other end is closed and we get SIGPIPE */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); @@ -118,6 +117,7 @@ int main(int n, char **v) if (!strcmp(v[i], "-x")) { gui_mode = 1; continue; } if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } if (!strcmp(v[i], "-no-gui")) { gui_active = 0; continue; } + if (!strcmp(v[i], "-full")) { full = 1; continue; } usage(); } @@ -162,6 +162,7 @@ int main(int n, char **v) // "ENB_PHY_UL_CHANNEL_ESTIMATE", // "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); logger_add_view(textlog, out); + if (full) textlog_dump_buffer(textlog, 1); free(name); free(desc); } diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index 3ebc000c671b62799c330775e0804e9ba8279d95..a22e0a0565dabecfa928d2bd6d4c7c5df6c72553 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -190,6 +190,13 @@ void PUTI(OBUF *o, int i) PUTS(o, s); } +void PUTX2(OBUF *o, int i) +{ + char s[64]; + sprintf(s, "%2.2x", i); + PUTS(o, s); +} + void PUTUL(OBUF *o, unsigned long l) { char s[128]; diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index e15a8d2fbad5c6e910e3ba3e21c6b0cc219a9952..086e92b5dcb4cb0e2fd6476132a815b3b018ba6a 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -20,6 +20,9 @@ list *list_append(list *l, void *data); /* socket */ /****************************************************************************/ +#define DEFAULT_REMOTE_IP "127.0.0.1" +#define DEFAULT_REMOTE_PORT 2021 + /* socket_send: return 0 if okay, -1 on error */ int socket_send(int socket, void *buffer, int size); int get_connection(char *addr, int port); @@ -41,6 +44,7 @@ void PUTC(OBUF *o, char c); void PUTS(OBUF *o, char *s); void PUTS_CLEAN(OBUF *o, char *s); void PUTI(OBUF *o, int i); +void PUTX2(OBUF *o, int i); void PUTUL(OBUF *o, unsigned long i); #endif /* _UTILS_H_ */ diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index 45aa4e26e2ae332586a143c1ebf680fcd34c9d1d..0ad2756c2a49d218314aa4b586ba6a7bac0765ab 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -40,9 +40,6 @@ no_connection: if (pthread_mutex_unlock(&d->lock)) abort(); } -#define DEFAULT_REMOTE_IP "127.0.0.1" -#define DEFAULT_REMOTE_PORT 2021 - void usage(void) { printf( diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index cbc5e21b73d95fb3b15524977663a6054846fc5f..2173c842ce956929945ef1e38662f64e90e0dcc2 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -11,10 +11,12 @@ typedef struct view { void (*set)(struct view *this, char *name, ...); } view; +enum xy_mode { XY_LOOP_MODE, XY_FORCED_MODE }; + view *new_view_stdout(void); view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w); view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, - int color); + int color, enum xy_mode mode); view *new_view_tti(float refresh_rate, gui *g, widget *w, int color); view *new_view_time(int number_of_seconds, float refresh_rate, diff --git a/common/utils/T/tracer/view/xy.c b/common/utils/T/tracer/view/xy.c index 1407a16a0e44614c8e86b05569712d738439cfc2..96a44cf5129e41f044cdbf559df32709fb5a8ff2 100644 --- a/common/utils/T/tracer/view/xy.c +++ b/common/utils/T/tracer/view/xy.c @@ -14,6 +14,7 @@ struct xy { float refresh_rate; pthread_mutex_t lock; int length; + int max_length; /* used in XY_FORCED_MODE */ float *x; float *y; int insert_point; @@ -39,7 +40,7 @@ static void clear(view *this) /* TODO */ } -static void append(view *_this, float *x, float *y, int length) +static void append_loop(view *_this, float *x, float *y, int length) { struct xy *this = (struct xy *)_this; int i; @@ -61,6 +62,25 @@ static void append(view *_this, float *x, float *y, int length) if (pthread_mutex_unlock(&this->lock)) abort(); } +static void append_forced(view *_this, float *x, float *y, int length) +{ + struct xy *this = (struct xy *)_this; + + if (length > this->max_length) { + printf("%s:%d:%s: bad length (%d), max allowed is %d\n", + __FILE__, __LINE__, __FUNCTION__, length, this->max_length); + abort(); + } + + if (pthread_mutex_lock(&this->lock)) abort(); + + memcpy(this->x, x, length * sizeof(float)); + memcpy(this->y, y, length * sizeof(float)); + this->length = length; + + if (pthread_mutex_unlock(&this->lock)) abort(); +} + static void set(view *_this, char *name, ...) { struct xy *this = (struct xy *)_this; @@ -89,24 +109,35 @@ static void set(view *_this, char *name, ...) } view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, - int color) + int color, enum xy_mode mode) { struct xy *ret = calloc(1, sizeof(struct xy)); if (ret == NULL) abort(); ret->common.clear = clear; - ret->common.append = (void (*)(view *, ...))append; - ret->common.set = set; + + switch (mode) { + case XY_LOOP_MODE: + ret->common.append = (void (*)(view *, ...))append_loop; + ret->common.set = set; + ret->length = length; + ret->insert_point = 0; + break; + case XY_FORCED_MODE: + ret->common.append = (void (*)(view *, ...))append_forced; + ret->common.set = NULL; + ret->length = 0; + ret->max_length = length; + break; + } ret->refresh_rate = refresh_rate; ret->g = g; ret->w = w; ret->plot = xy_plot_new_plot(g, w, color); - ret->length = length; ret->x = calloc(length, sizeof(float)); if (ret->x == NULL) abort(); ret->y = calloc(length, sizeof(float)); if (ret->y == NULL) abort(); - ret->insert_point = 0; if (pthread_mutex_init(&ret->lock, NULL)) abort(); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 48ab4c5ca76503ee8fe62cb5203eeaa9a7424729..010dd36f3192334b1df919ed2b6219c506246166 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1842,6 +1842,7 @@ void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB, T(T_ENB_PHY_PUSCH_IQ, T_INT(eNB_id), T_INT(UE_id), T_INT(phy_vars_eNB->proc[sched_subframe].frame_rx), T_INT(subframe), T_INT(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb), + T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti), T_BUFFER(eNB_pusch_vars->rxdataF_comp[eNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2)); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 837706de232975139113c507a3c374c227410121..1f488687a335e99172f44fc3b9f3d3d4ae7b42d9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -130,6 +130,8 @@ void rx_sdu( T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); + T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP)); eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP; eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP; @@ -313,6 +315,8 @@ void rx_sdu( T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); + T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i])); switch (rx_lcids[i]) { case CCCH : diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/dataTypes.h b/targets/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/dataTypes.h index cba2b7341e2ad89ccdb8047d5fbb9628674e629e..c97ac7857df021918df23abbddee645ed18e35e1 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/dataTypes.h +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/dataTypes.h @@ -14,14 +14,15 @@ typedef struct int16_t q; } complex16_t; -typedef struct +class SamplesPacket { + public: uint64_t timestamp; //timestamp of the packet uint16_t first; //index of first unused sample in samples[] uint16_t last; //end index of samples static const uint16_t samplesCount = 1024; //maximum number of samples in packet complex16_t samples[samplesCount]; //must be power of two -} SamplesPacket; +}; complex16_t operator &=(complex16_t & other1, const complex16_t & other) // copy assignment { @@ -30,4 +31,4 @@ complex16_t operator &=(complex16_t & other1, const complex16_t & other) // copy return other1; } -#endif \ No newline at end of file +#endif diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index ca97ad0e225acc5ca7f4205d30a3c7e7209dbf09..3f419ed49ca8cfe3dc98cbd9df33a69d38e08b55 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -490,6 +490,7 @@ void help (void) { #if T_TRACER printf(" --T_port [port] use given port\n"); printf(" --T_nowait don't wait for tracer, start immediately\n"); + printf(" --T_dont_fork to ease debugging with gdb\n"); #endif printf(RESET); fflush(stdout); @@ -2332,6 +2333,7 @@ static void get_options (int argc, char **argv) #if T_TRACER LONG_OPTION_T_PORT, LONG_OPTION_T_NOWAIT, + LONG_OPTION_T_DONT_FORK, #endif }; @@ -2355,6 +2357,7 @@ static void get_options (int argc, char **argv) #if T_TRACER {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, {"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT}, + {"T_dont_fork", no_argument, 0, LONG_OPTION_T_DONT_FORK}, #endif {NULL, 0, NULL, 0} @@ -2457,6 +2460,12 @@ static void get_options (int argc, char **argv) T_wait = 0; break; } + + case LONG_OPTION_T_DONT_FORK: { + extern int T_dont_fork; + T_dont_fork = 1; + break; + } #endif case 'A': @@ -2822,6 +2831,7 @@ static void get_options (int argc, char **argv) #if T_TRACER int T_wait = 1; /* by default we wait for the tracer */ int T_port = 2021; /* default port to listen to to wait for the tracer */ +int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ #endif int main( int argc, char **argv ) @@ -2894,7 +2904,7 @@ int main( int argc, char **argv ) openair0_cfg[0].configFilename = rf_config_file; #if T_TRACER - T_init(T_port, T_wait); + T_init(T_port, T_wait, T_dont_fork); #endif // initialize the log (see log.h for details) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index dfbf8f9676c6db683c6312ef150041ea288ea791..744952b5d0d23d4affe9cea28653a4d959404c7d 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -250,6 +250,7 @@ help (void) #if T_TRACER printf ("--T_port [port] use given port\n"); printf ("--T_nowait don't wait for tracer, start immediately\n"); + printf ("--T_dont_fork to ease debugging with gdb\n"); #endif } @@ -1258,6 +1259,7 @@ l2l1_task (void *args_p) #if T_TRACER int T_wait = 1; /* by default we wait for the tracer */ int T_port = 2021; /* default port to listen to to wait for the tracer */ +int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ #endif /*------------------------------------------------------------------------------*/ @@ -1294,7 +1296,7 @@ main (int argc, char **argv) get_simulation_options (argc, argv); //Command-line options #if T_TRACER - T_init(T_port, T_wait); + T_init(T_port, T_wait, T_dont_fork); #endif // Initialize VCD LOG module diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index f8043b2cfd710c11f5a41cea72ae73387ef37721..a5acb2616a81054ad9dbea9f9d39248fd5d11d03 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -216,6 +216,7 @@ void get_simulation_options(int argc, char *argv[]) #if T_TRACER LONG_OPTION_T_PORT, LONG_OPTION_T_NOWAIT, + LONG_OPTION_T_DONT_FORK, #endif }; @@ -254,6 +255,7 @@ void get_simulation_options(int argc, char *argv[]) #if T_TRACER {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, {"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT}, + {"T_dont_fork", no_argument, 0, LONG_OPTION_T_DONT_FORK}, #endif {NULL, 0, NULL, 0} @@ -436,6 +438,12 @@ void get_simulation_options(int argc, char *argv[]) T_wait = 0; break; } + + case LONG_OPTION_T_DONT_FORK: { + extern int T_dont_fork; + T_dont_fork = 1; + break; + } #endif case 'a':