diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e4d3acf4b1c976540a95e6cbd033bfa26b9d9ecd..81ea1980dc7f2fe7bd4cb2064d6c09a3b185d86b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1664,18 +1664,6 @@ endif() message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h index df8251d10541cfd06a402172c8aa4087e5fd40b6..a411bd539728b93cb563ad39843f5eefbf5bd88e 100644 --- a/common/utils/itti/assertions.h +++ b/common/utils/itti/assertions.h @@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX " (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3) #define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \ -_Assert_(cOND, _Assert_Exit_, #vALUE1": %"PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX"\n\n", \ +_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \ (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4) #define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index b9f421204e64a1adb5b464f818f7d612ec4d5e4f..90f8242cc87c9af6a507b0b0850114c125189a3e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -40,6 +40,8 @@ #include "SCHED/defs.h" #include "defs.h" #include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/LOG/log.h" +#include <syscall.h> //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 @@ -347,6 +349,8 @@ int dlsch_encoding_2threads0(te_params *tep) { extern int oai_exit; void *te_thread(void *param) { + pthread_setname_np( pthread_self(),"te processing"); + LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid)); eNB_proc_t *proc = &((te_params *)param)->eNB->proc; while (!oai_exit) { diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index bcc9a77fb016f043e061a762e058eabf330e9247..ca67ccdb3c9c34dbf01b7752201ebce456b34017 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -418,6 +418,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { extern int oai_exit; void *td_thread(void *param) { + pthread_setname_np( pthread_self(), "td processing"); PHY_VARS_eNB *eNB = ((td_params*)param)->eNB; eNB_proc_t *proc = &eNB->proc; diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 2ccf791703f106d5f929b62e67d780ce02827d6b..d70bfb3f722df0bcf526266d633b932bb534057b 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -32,6 +32,7 @@ #ifndef __PHY_DEFS__H__ #define __PHY_DEFS__H__ +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <malloc.h> @@ -391,6 +392,9 @@ typedef struct { pthread_mutex_t mutex_rxtx; /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; + int sub_frame_start; + int sub_frame_step; + unsigned long long gotIQs; } UE_rxtx_proc_t; /// Context data structure for eNB subframe processing diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 6409917c67598cad5cb6129078df23c7cdf4c8f7..acf8f08bcdc4dd2e28077d3d446ab3e0555649de 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2603,6 +2603,7 @@ extern int oai_exit; static void *fep_thread(void *param) { + pthread_setname_np( pthread_self(), "UEfep"); PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param; eNB_proc_t *proc = &eNB->proc; while (!oai_exit) { diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index b17e7d772424eb18612e9f5796ab27f817bd12f2..45d7774afad0bf382481a644c4fbb4536f243a2a 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -264,7 +264,7 @@ typedef struct protocol_ctxt_s { (Ctxt_Pp)->subframe = sUBfRAME; \ PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp) -#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"PRIx16"]" +#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]" #define PROTOCOL_CTXT_ARGS(CTXT_Pp) \ (CTXT_Pp)->frame, \ ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \ diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 6a6569c1a585499bb314574cb70a0d26a35d4e36..b31efbcf74908e43dbe7e77bf129f5a94bf58dcd 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -43,6 +43,13 @@ #include <sys/stat.h> #include <fcntl.h> #include <stdarg.h> +#include <time.h> +#include <stdint.h> +#include <inttypes.h> +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <pthread.h> #else #include "rtai_fifos.h" #endif @@ -76,41 +83,197 @@ extern "C" { * @ingroup _macro * @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8 * @{*/ -#ifndef LOG_EMERG # define LOG_EMERG 0 /*!< \brief system is unusable */ -#endif -#ifndef LOG_ALERT # define LOG_ALERT 1 /*!< \brief action must be taken immediately */ -#endif -#ifndef LOG_CRIT # define LOG_CRIT 2 /*!< \brief critical conditions */ -#endif -#ifndef LOG_ERR # define LOG_ERR 3 /*!< \brief error conditions */ -#endif -#ifndef LOG_WARNING # define LOG_WARNING 4 /*!< \brief warning conditions */ -#endif -#ifndef LOG_NOTICE # define LOG_NOTICE 5 /*!< \brief normal but significant condition */ -#endif -#ifndef LOG_INFO # define LOG_INFO 6 /*!< \brief informational */ -#endif -#ifndef LOG_DEBUG # define LOG_DEBUG 7 /*!< \brief debug-level messages */ -#endif -#ifndef LOG_FILE # define LOG_FILE 8 /*!< \brief message sequence chart -level */ -#endif -#ifndef LOG_TRACE # define LOG_TRACE 9 /*!< \brief trace-level messages */ -#endif - #define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */ /* @}*/ +/** @defgroup _log_format Defined log format + * @ingroup _macro + * @brief Macro of log formats defined by LOG + * @{*/ + +/* .log_format = 0x13 uncolored standard messages + * .log_format = 0x93 colored standard messages */ + +#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ +#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ +#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ +#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ +#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ +#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ +/* @}*/ + + +/** @defgroup _syslog_conf Macros for write in syslog.conf + * @ingroup _macro + * @brief Macros used to write lines (local/remote) in syslog.conf + * @{*/ +#define LOG_LOCAL 0x01 +#define LOG_REMOTE 0x02 + +#define FLAG_COLOR 0x001 /*!< \brief defaults */ +#define FLAG_PID 0x002 /*!< \brief defaults */ +#define FLAG_COMP 0x004 +#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */ +#define FLAG_LEVEL 0x010 +#define FLAG_FUNCT 0x020 +#define FLAG_FILE_LINE 0x040 +#define FLAG_TIME 0x100 + +#define LOG_NONE 0x00 +#define LOG_LOW 0x5 +#define LOG_MED 0x15 +#define LOG_HIGH 0x35 +#define LOG_FULL 0x75 + +#define OAI_OK 0 /*!< \brief all ok */ +#define OAI_ERR 1 /*!< \brief generic error */ +#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */ +#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */ +/* @}*/ + + +//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */ + +//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ + +typedef enum { + MIN_LOG_COMPONENTS = 0, + PHY = MIN_LOG_COMPONENTS, + MAC, + EMU, + OCG, + OMG, + OPT, + OTG, + OTG_LATENCY, + OTG_LATENCY_BG, + OTG_GP, + OTG_GP_BG, + OTG_JITTER, + RLC, + PDCP, + RRC, + NAS, + PERF, + OIP, + CLI, + MSC, + OCM, + UDP_, + GTPU, + SPGW, + S1AP, + SCTP, + HW, + OSA, + RAL_ENB, + RAL_UE, + ENB_APP, + FLEXRAN_AGENT, + TMR, + USIM, + LOCALIZE, + RRH, + X2AP, + MAX_LOG_COMPONENTS, +} +comp_name_t; + +//#define msg printf + +typedef struct { + char *name; /*!< \brief string name of item */ + int value; /*!< \brief integer value of mapping */ +} mapping; + + +typedef struct { + const char *name; + int level; + int flag; + int interval; + int fd; + int filelog; + char *filelog_name; + + /* SR: make the log buffer component relative */ + char log_buffer[MAX_LOG_TOTAL]; +} log_component_t; + +typedef struct { + unsigned int remote_ip; + unsigned int audit_ip; + int remote_level; + int facility; + int audit_facility; + int format; +} log_config_t; + + +typedef struct { + log_component_t log_component[MAX_LOG_COMPONENTS]; + log_config_t config; + char* level2string[NUM_LOG_LEVEL]; + int level; + int onlinelog; + int flag; + int syslog; + int filelog; + char* filelog_name; +} log_t; + +typedef struct LOG_params { + const char *file; + const char *func; + int line; + int comp; + int level; + const char *format; + char l_buff_info [MAX_LOG_INFO]; + int len; +} LOG_params; + +#if defined(ENABLE_ITTI) +typedef enum log_instance_type_e { + LOG_INSTANCE_UNKNOWN, + LOG_INSTANCE_ENB, + LOG_INSTANCE_UE, +} log_instance_type_t; + +void log_set_instance_type (log_instance_type_t instance); +#endif + + +/*--- INCLUDES ---------------------------------------------------------------*/ +# include "log_if.h" +/*----------------------------------------------------------------------------*/ +int logInit (void); +void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +int set_comp_log(int component, int level, int verbosity, int interval); +int set_log(int component, int level, int interval); +void set_glog(int level, int verbosity); +void set_log_syslog(int enable); +void set_log_onlinelog(int enable); +void set_log_filelog(int enable); +void set_component_filelog(int comp); +int map_str_to_int(mapping *map, const char *str); +char *map_int_to_str(mapping *map, int val); +void logClean (void); +int is_newline( char *str, int size); +void *log_thread_function(void * list); + /** @defgroup _logIt logIt function * @ingroup _macro * @brief Macro used to call tr_log_full_ex with file, function and line information @@ -186,169 +349,107 @@ extern "C" { #define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ /* @}*/ - -/** @defgroup _log_format Defined log format - * @ingroup _macro - * @brief Macro of log formats defined by LOG - * @{*/ - -/* .log_format = 0x13 uncolored standard messages - * .log_format = 0x93 colored standard messages */ - -#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ -#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ -#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ -#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ -#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ -#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ -/* @}*/ - - -/** @defgroup _syslog_conf Macros for write in syslog.conf - * @ingroup _macro - * @brief Macros used to write lines (local/remote) in syslog.conf - * @{*/ -#define LOG_LOCAL 0x01 -#define LOG_REMOTE 0x02 - -#define FLAG_COLOR 0x001 /*!< \brief defaults */ -#define FLAG_PID 0x002 /*!< \brief defaults */ -#define FLAG_COMP 0x004 -#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */ -#define FLAG_LEVEL 0x010 -#define FLAG_FUNCT 0x020 -#define FLAG_FILE_LINE 0x040 -#define FLAG_TIME 0x100 - -#define LOG_NONE 0x00 -#define LOG_LOW 0x5 -#define LOG_MED 0x15 -#define LOG_HIGH 0x35 -#define LOG_FULL 0x75 - -#define OAI_OK 0 /*!< \brief all ok */ -#define OAI_ERR 1 /*!< \brief generic error */ -#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */ -#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */ -/* @}*/ - - -//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */ - -//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ - -typedef enum { - MIN_LOG_COMPONENTS = 0, - PHY = MIN_LOG_COMPONENTS, - MAC, - EMU, - OCG, - OMG, - OPT, - OTG, - OTG_LATENCY, - OTG_LATENCY_BG, - OTG_GP, - OTG_GP_BG, - OTG_JITTER, - RLC, - PDCP, - RRC, - NAS, - PERF, - OIP, - CLI, - MSC, - OCM, - UDP_, - GTPU, - SPGW, - S1AP, - SCTP, - HW, - OSA, - RAL_ENB, - RAL_UE, - ENB_APP, - FLEXRAN_AGENT, - TMR, - USIM, - LOCALIZE, - RRH, - X2AP, - MAX_LOG_COMPONENTS, +static __inline__ uint64_t rdtsc(void) { + uint64_t a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; } -comp_name_t; - -//#define msg printf - -typedef struct { - char *name; /*!< \brief string name of item */ - int value; /*!< \brief integer value of mapping */ -} mapping; - -typedef struct { - const char *name; - int level; - int flag; - int interval; - int fd; - int filelog; - char *filelog_name; - - /* SR: make the log buffer component relative */ - char log_buffer[MAX_LOG_TOTAL]; -} log_component_t; - -typedef struct { - unsigned int remote_ip; - unsigned int audit_ip; - int remote_level; - int facility; - int audit_facility; - int format; -} log_config_t; +#define DEBUG_REALTIME 1 +#if DEBUG_REALTIME + +extern double cpuf; + +static inline uint64_t checkTCPU(int timeout, char * file, int line) { + static uint64_t __thread lastCPUTime=0; + static uint64_t __thread last=0; + uint64_t cur=rdtsc(); + struct timespec CPUt; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt); + uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000; + double microCycles=(double)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) { + //struct timespec ts; + //clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line, + duration, timeout, (long long)CPUTime-lastCPUTime ); + } + last=cur; + lastCPUTime=CPUTime; + return cur; +} +static inline unsigned long long checkT(int timeout, char * file, int line) { + static unsigned long long __thread last=0; + unsigned long long cur=rdtsc(); + int microCycles=(int)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) + printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, + duration, timeout); + last=cur; + return cur; +} -typedef struct { - log_component_t log_component[MAX_LOG_COMPONENTS]; - log_config_t config; - char* level2string[NUM_LOG_LEVEL]; - int level; - int onlinelog; - int flag; - int syslog; - int filelog; - char* filelog_name; -} log_t; +typedef struct m { + uint64_t iterations; + uint64_t sum; + uint64_t maxArray[11]; +} Meas; + +static inline void printMeas(char * txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" + PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", + txt, + M->sum/M->iterations, + M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], + M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + LOG_W(PHY,txt2); + } +} -typedef struct LOG_params { - const char *file; - const char *func; - int line; - int comp; - int level; - const char *format; - char l_buff_info [MAX_LOG_INFO]; - int len; -} LOG_params; +static inline int cmpint(const void* a, const void* b) { + uint64_t* aa=(uint64_t*)a; + uint64_t* bb=(uint64_t*)b; + return (int)(*aa-*bb); +} +static inline void updateTimes(uint64_t start, Meas *M, int period, char * txt) { + if (start!=0) { + uint64_t end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); + printMeas(txt,M,period); + } +} -#if defined(ENABLE_ITTI) -typedef enum log_instance_type_e { - LOG_INSTANCE_UNKNOWN, - LOG_INSTANCE_ENB, - LOG_INSTANCE_UE, -} log_instance_type_t; +#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0) +#define checkcpu(a) do { checkTCPU(a,__FILE__,__LINE__); } while (0) +#define initRefTimes(a) static __thread Meas a= {0} +#define pickTime(a) uint64_t a=rdtsc() +#define readTime(a) a +#define initStaticTime(a) static __thread uint64_t a={0} +#define pickStaticTime(a) do { a=rdtsc(); } while (0) -void log_set_instance_type (log_instance_type_t instance); +#else +#define check(a) do {} while (0) +#define checkcpu(a) do {} while (0) +#define initRefTimes(a) do {} while (0) +#define initStaticTime(a) do {} while (0) +#define pickTime(a) do {} while (0) +#define readTime(a) 0 +#define pickStaticTime(a) do {} while (0) +#define updateTimes(a,b,c,d) do {} while (0) +#define printMeas(a,b,c) do {} while (0) #endif -int logInit (void); -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log_if.h" -/*----------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif diff --git a/openair2/UTIL/LOG/log_if.h b/openair2/UTIL/LOG/log_if.h index 3dd25ff365350008105946824804991f8982095f..6338fab829cad69385f9471cc331594b65a05cc4 100644 --- a/openair2/UTIL/LOG/log_if.h +++ b/openair2/UTIL/LOG/log_if.h @@ -27,59 +27,8 @@ * \warning This component can be runned only in user-space * @ingroup routing */ -#ifndef __LOG_IF_H__ -# define __LOG_IF_H__ - - -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log.h" -/*----------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef COMPONENT_LOG -# ifdef COMPONENT_LOG_IF -# define private_log_if(x) x -# define friend_log_if(x) x -# define public_log_if(x) x -# else -# define private_log_if(x) -# define friend_log_if(x) extern x -# define public_log_if(x) extern x -# endif -# else -# define private_log_if(x) -# define friend_log_if(x) -# define public_log_if(x) extern x -# endif - -/** @defgroup _log_if Interfaces of LOG - * @{*/ - -//public_log_if( log_t *g_log;) - -public_log_if( int logInit (void);) -public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));) -public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));) -public_log_if( int set_comp_log(int component, int level, int verbosity, int interval);) -public_log_if( int set_log(int component, int level, int interval);) -public_log_if( void set_glog(int level, int verbosity);) -public_log_if( void set_log_syslog(int enable);) -public_log_if( void set_log_onlinelog(int enable);) -public_log_if( void set_log_filelog(int enable);) -public_log_if( void set_component_filelog(int comp);) -public_log_if( int map_str_to_int(mapping *map, const char *str);) -public_log_if( char *map_int_to_str(mapping *map, int val);) -public_log_if( void logClean (void); ) -public_log_if( int is_newline( char *str, int size);) -public_log_if( void *log_thread_function(void * list);) - -/* @}*/ - -#ifdef __cplusplus -} -#endif - -#endif +// LTS: kept this file for compatibility +// this file was probably a trial to separate internal functions and external ones +// but it has never been finished, most source code include directly log.h (not log_if.h) +#include "log.h" diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c index 6aef6d2588ad26d22d15f44da7dbe7ab29dd7935..9e8a3a88b3777f5a0a8fd95ee06f82009883097d 100644 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ b/openair2/UTIL/OSA/osa_stream_eea.c @@ -27,6 +27,7 @@ #include <nettle/nettle-meta.h> #include <nettle/aes.h> #include <nettle/ctr.h> +#include <nettle/bignum.h> #include "UTIL/LOG/log.h" @@ -191,7 +192,7 @@ int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) } #endif -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 72035da6c8c0fb687a4381a1ef332807463b05d5..35d1b864898638bf469c29344e210952faa7bdba 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -224,6 +224,7 @@ static void *_nas_user_mngr(void *args) { LOG_FUNC_IN; + pthread_setname_np( pthread_self(), "nas_user_mngr"); int exit_loop = FALSE; int *fd = (int *) args; diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 37f2e298fb2ff710ea515af1df434b8c45db6de0..e9f2e7c41a650e3767bb4f8ba4b022cc9110c036 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -27,6 +27,7 @@ #include <nettle/nettle-meta.h> #include <nettle/aes.h> #include <nettle/ctr.h> +#include <nettle/bignum.h> #include "assertions.h" #include "conversions.h" @@ -78,7 +79,7 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) } #endif -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/TEST/test_aes128_ctr_decrypt.c b/openair3/TEST/test_aes128_ctr_decrypt.c index a30dc6c2f21c0d775cdf23775d4df44002265e01..98987a8d97bb88e423c73c972247bb077ed8f15f 100644 --- a/openair3/TEST/test_aes128_ctr_decrypt.c +++ b/openair3/TEST/test_aes128_ctr_decrypt.c @@ -31,6 +31,7 @@ #include <nettle/nettle-meta.h> #include <nettle/aes.h> #include <nettle/ctr.h> +#include <nettle/bignum.h> static void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, @@ -41,7 +42,7 @@ void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, uint8_t *data = malloc(length); uint8_t *ctr = malloc(cipher->block_size); -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 cipher->set_encrypt_key(ctx, key_length, key); #else cipher->set_encrypt_key(ctx, key); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 2a2e09f40cbe800e7cd7fb654d059f88b1ff3113..dc2589de44dcea18be20583e209f305acc6613fd 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -40,10 +40,12 @@ #include <time.h> #include "UTIL/LOG/log_extern.h" #include "common_lib.h" +#include "assertions.h" + #ifdef __SSE4_1__ # include <smmintrin.h> #endif - + #ifdef __AVX2__ # include <immintrin.h> #endif @@ -56,180 +58,133 @@ * @{ */ -/*! \brief USRP Configuration */ -typedef struct -{ - - // -------------------------------- - // variables for USRP configuration - // -------------------------------- - //! USRP device pointer - uhd::usrp::multi_usrp::sptr usrp; - //uhd::usrp::multi_usrp::sptr rx_usrp; - - //create a send streamer and a receive streamer - //! USRP TX Stream - uhd::tx_streamer::sptr tx_stream; - //! USRP RX Stream - uhd::rx_streamer::sptr rx_stream; - - //! USRP TX Metadata - uhd::tx_metadata_t tx_md; - //! USRP RX Metadata - uhd::rx_metadata_t rx_md; - - //! USRP Timestamp Information - uhd::time_spec_t tm_spec; - - //setup variables and allocate buffer - //! USRP Metadata - uhd::async_metadata_t async_md; - - //! Sampling rate - double sample_rate; - - //! time offset between transmiter timestamp and receiver timestamp; - double tdiff; - - //! TX forward samples. We use usrp_time_offset to get this value - int tx_forward_nsamps; //166 for 20Mhz - - - // -------------------------------- - // Debug and output control - // -------------------------------- - //! Number of underflows - int num_underflows; - //! Number of overflows - int num_overflows; - - //! Number of sequential errors - int num_seq_errors; - //! tx count - int64_t tx_count; - //! rx count - int64_t rx_count; - //! timestamp of RX packet - openair0_timestamp rx_timestamp; +/*! \brief USRP Configuration */ +typedef struct { + + // -------------------------------- + // variables for USRP configuration + // -------------------------------- + //! USRP device pointer + uhd::usrp::multi_usrp::sptr usrp; + + //create a send streamer and a receive streamer + //! USRP TX Stream + uhd::tx_streamer::sptr tx_stream; + //! USRP RX Stream + uhd::rx_streamer::sptr rx_stream; + + //! USRP TX Metadata + uhd::tx_metadata_t tx_md; + //! USRP RX Metadata + uhd::rx_metadata_t rx_md; + + //! Sampling rate + double sample_rate; + + //! TX forward samples. We use usrp_time_offset to get this value + int tx_forward_nsamps; //166 for 20Mhz + + // -------------------------------- + // Debug and output control + // -------------------------------- + int num_underflows; + int num_overflows; + int num_seq_errors; + int64_t tx_count; + int64_t rx_count; + //! timestamp of RX packet + openair0_timestamp rx_timestamp; } usrp_state_t; + + /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ -static int trx_usrp_start(openair0_device *device) -{ - usrp_state_t *s = (usrp_state_t*)device->priv; - - // init recv and send streaming - uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); - cmd.stream_now = false; // start at constant delay - s->rx_stream->issue_stream_cmd(cmd); +static int trx_usrp_start(openair0_device *device) { - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; + usrp_state_t *s = (usrp_state_t*)device->priv; + // init recv and send streaming + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); + cmd.stream_now = false; // start at constant delay + s->rx_stream->issue_stream_cmd(cmd); - s->rx_count = 0; - s->tx_count = 0; - s->rx_timestamp = 0; + s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; - return 0; + s->rx_count = 0; + s->tx_count = 0; + s->rx_timestamp = 0; + return 0; } -/*! \brief Terminate operation of the USRP transceiver -- free all associated resources +/*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ -static void trx_usrp_end(openair0_device *device) -{ - usrp_state_t *s = (usrp_state_t*)device->priv; +static void trx_usrp_end(openair0_device *device) { + usrp_state_t *s = (usrp_state_t*)device->priv; - s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + //send a mini EOB packet + s->tx_md.end_of_burst = true; + s->tx_stream->send("", 0, s->tx_md); + s->tx_md.end_of_burst = false; - //send a mini EOB packet - s->tx_md.end_of_burst = true; - s->tx_stream->send("", 0, s->tx_md); - s->tx_md.end_of_burst = false; - } /*! \brief Called to send samples to the USRP RF target @param device pointer to the device structure specific to the RF hardware target - @param timestamp The timestamp at whicch the first sample MUST be sent + @param timestamp The timestamp at whicch the first sample MUST be sent @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to TRUE if timestamp parameter needs to be applied -*/ -static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) -{ - static long long int loop=0; - static long time_min=0, time_max=0, time_avg=0; - struct timespec tp_start, tp_end; - long time_diff; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); - - int ret=0, ret_i=0; - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - - - if(flags>0) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; +*/ +static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + int ret=0; + usrp_state_t *s = (usrp_state_t*)device->priv; - if (flags == 2) { // start of burst - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; - } - else if (flags == 3) { // end of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; - } - else if (flags == 4) { // start and end - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = true; - } - else if (flags==1) { // middle of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = false; - } - - if (cc>1) { - std::vector<void *> buff_ptrs; - for (int i=0;i<cc;i++) buff_ptrs.push_back(buff[i]); - ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); - } - else - ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); - - - - if (ret != nsamps) { - printf("[xmit] tx samples %d != %d\n",ret,nsamps); - } - - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_end); - time_diff = (tp_end.tv_sec - tp_start.tv_sec) *1E09 + (tp_end.tv_nsec - tp_start.tv_nsec); - if (time_min==0 ||loop==1 || time_min > time_diff) - time_min=time_diff; - if (time_max==0 ||loop==1 || time_max < time_diff) - time_max=time_diff; - if (time_avg ==0 ||loop==1) - time_avg= time_diff; - else - time_avg=(time_diff+time_avg) /2.0; - - /* //prints statics of uhd every 10 seconds - if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0) - LOG_I(HW,"usrp_write: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg); - */ - loop++; - return ret; + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_md.has_time_spec = flags; + + + if(flags>0) + s->tx_md.has_time_spec = true; + else + s->tx_md.has_time_spec = false; + + if (flags == 2) { // start of burst + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; + } else if (flags == 3) { // end of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = true; + } else if (flags == 4) { // start and end + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = true; + } else if (flags==1) { // middle of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = false; + } + + if (cc>1) { + std::vector<void *> buff_ptrs; + for (int i=0; i<cc; i++) + buff_ptrs.push_back(buff[i]); + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + } else + ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); + + + + if (ret != nsamps) + LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); + + return ret; } /*! \brief Receive samples from hardware. @@ -243,621 +198,535 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \param antenna_id Index of antenna for which to receive samples * \returns the number of sample read */ -static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) -{ - static long long int loop=0; - static long time_min=0, time_max=0, time_avg=0; - struct timespec tp_start, tp_end; - long time_diff; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); - usrp_state_t *s = (usrp_state_t*)device->priv; - int samples_received=0,i,j; - int nsamps2; // aligned to upper 32 or 16 byte boundary +static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + usrp_state_t *s = (usrp_state_t*)device->priv; + int samples_received=0,i,j; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+7)>>3; + __m256i buff_tmp[2][nsamps2]; #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + __m128i buff_tmp[2][nsamps2]; #endif #elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tmp[2][nsamps2]; #endif - - if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; - - for (int i=0;i<cc;i++) buff_ptrs.push_back(buff_tmp[i]); - samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff_tmp[0], nsamps, s->rx_md); - } - - // bring RX data into 12 LSBs for softmodem RX - for (int i=0;i<cc;i++) { - for (int j=0; j<nsamps2; j++) { + if (device->type == USRP_B200_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received=0; + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); + if (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE) + break; + } + } + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); + ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); #else - ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); + ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); #endif #elif defined(__arm__) - ((int16x8_t*)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); + ((int16x8_t*)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); #endif - } + } + } + } else if (device->type == USRP_X300_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; + + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); + } } - } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; - - for (int i=0;i<cc;i++) buff_ptrs.push_back(buff[i]); - samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); - } - } - - if (samples_received < nsamps) { - printf("[recv] received %d samples out of %d\n",samples_received,nsamps); - - } - - //handle the error code - switch(s->rx_md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - break; - case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: - printf("[recv] USRP RX OVERFLOW!\n"); - s->num_overflows++; - break; - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - printf("[recv] USRP RX TIMEOUT!\n"); - break; - default: - printf("[recv] Unexpected error on RX, Error code: 0x%x\n",s->rx_md.error_code); - break; - } - s->rx_count += nsamps; - s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); - *ptimestamp = s->rx_timestamp; - - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_end); - time_diff = (tp_end.tv_sec - tp_start.tv_sec) *1E09 + (tp_end.tv_nsec - tp_start.tv_nsec); - if (time_min==0 ||loop==1 || time_min > time_diff) - time_min=time_diff; - if (time_max==0 ||loop==1 || time_max < time_diff) - time_max=time_diff; - if (time_avg ==0 ||loop==1) - time_avg= time_diff; - else - time_avg=(time_diff+time_avg) /2.0; - /* - //prints statics of uhd every 10 seconds - if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0) - LOG_I(HW,"usrp_read: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg); - - loop++;*/ - return samples_received; -} + if (samples_received < nsamps) + LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); -/*! \brief Get current timestamp of USRP - * \param device the hardware to use -*/ -openair0_timestamp get_usrp_time(openair0_device *device) -{ - - usrp_state_t *s = (usrp_state_t*)device->priv; - - return s->usrp->get_time_now().to_ticks(s->sample_rate); -} + if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) + LOG_E(PHY,s->rx_md.to_pp_string(true).c_str()); + + s->rx_count += nsamps; + s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); + *ptimestamp = s->rx_timestamp; + return samples_received; +} /*! \brief Compares two variables within precision * \param a first variable * \param b second variable */ -static bool is_equal(double a, double b) -{ - return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); +static bool is_equal(double a, double b) { + return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); } void *freq_thread(void *arg) { - - openair0_device *device=(openair0_device *)arg; - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + + openair0_device *device=(openair0_device *)arg; + usrp_state_t *s = (usrp_state_t*)device->priv; + + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } /*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application * \param dummy dummy variable not used - * \returns 0 in success + * \returns 0 in success */ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { - usrp_state_t *s = (usrp_state_t*)device->priv; - pthread_t f_thread; + usrp_state_t *s = (usrp_state_t*)device->priv; + pthread_t f_thread; - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); + printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - // spawn a thread to handle the frequency change to not block the calling thread - if (dont_block == 1) - pthread_create(&f_thread,NULL,freq_thread,(void*)device); - else { - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); - } + // spawn a thread to handle the frequency change to not block the calling thread + if (dont_block == 1) + pthread_create(&f_thread,NULL,freq_thread,(void*)device); + else { + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + } + + return(0); - return(0); - } -/*! \brief Set RX frequencies +/*! \brief Set RX frequencies * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) { - usrp_state_t *s = (usrp_state_t*)device->priv; - static int first_call=1; - static double rf_freq,diff; + usrp_state_t *s = (usrp_state_t*)device->priv; + static int first_call=1; + static double rf_freq,diff; + + uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); - uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); + rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; + rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; + rf_freq=openair0_cfg[0].rx_freq[0]; + s->usrp->set_rx_freq(rx_tune_req); - rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; - rf_freq=openair0_cfg[0].rx_freq[0]; - s->usrp->set_rx_freq(rx_tune_req); + return(0); - return(0); - } /*! \brief Set Gains (TX/RX) * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ -int trx_usrp_set_gains(openair0_device* device, - openair0_config_t *openair0_cfg) { - - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[0]); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { - - printf("RX Gain 0 too high, reduce by %f dB\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); - printf("Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0],openair0_cfg[0].rx_gain[0],gain_range.stop()); - - return(0); +int trx_usrp_set_gains(openair0_device* device, + openair0_config_t *openair0_cfg) { + + usrp_state_t *s = (usrp_state_t*)device->priv; + + s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[0]); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); + // limit to maximum gain + if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { + LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); + exit(-1); + } + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); + LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], + openair0_cfg[0].rx_gain[0],gain_range.stop()); + + return(0); } /*! \brief Stop USRP * \param card refers to the hardware index to use */ int trx_usrp_stop(openair0_device* device) { - return(0); + return(0); } /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210[] = { - {3500000000.0,44.0}, - {2660000000.0,49.0}, - {2300000000.0,50.0}, - {1880000000.0,53.0}, - {816000000.0,58.0}, - {-1,0}}; + {3500000000.0,44.0}, + {2660000000.0,49.0}, + {2300000000.0,50.0}, + {1880000000.0,53.0}, + {816000000.0,58.0}, + {-1,0} +}; /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210_38[] = { - {3500000000.0,44.0}, - {2660000000.0,49.8}, - {2300000000.0,51.0}, - {1880000000.0,53.0}, - {816000000.0,57.0}, - {-1,0}}; + {3500000000.0,44.0}, + {2660000000.0,49.8}, + {2300000000.0,51.0}, + {1880000000.0,53.0}, + {816000000.0,57.0}, + {-1,0} +}; /*! \brief USRPx310 RX calibration table */ rx_gain_calib_table_t calib_table_x310[] = { - {3500000000.0,77.0}, - {2660000000.0,81.0}, - {2300000000.0,81.0}, - {1880000000.0,82.0}, - {816000000.0,85.0}, - {-1,0}}; - -/*! \brief Set RX gain offset + {3500000000.0,77.0}, + {2660000000.0,81.0}, + {2300000000.0,81.0}, + {1880000000.0,82.0}, + {816000000.0,85.0}, + {-1,0} +}; + +/*! \brief Set RX gain offset * \param openair0_cfg RF frontend parameters set by application * \param chain_index RF chain to apply settings to - * \returns 0 in success + * \returns 0 in success */ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff,gain_adj=0.0; - if (bw_gain_adjust==1) { - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - break; - case 23040000: - gain_adj=1.25; - break; - case 15360000: - gain_adj=3.0; - break; - case 7680000: - gain_adj=6.0; - break; - case 3840000: - gain_adj=9.0; - break; - case 1920000: - gain_adj=12.0; - break; - default: - printf("unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); - exit(-1); - break; + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff,gain_adj=0.0; + if (bw_gain_adjust==1) { + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + break; + case 23040000: + gain_adj=1.25; + break; + case 15360000: + gain_adj=3.0; + break; + case 7680000: + gain_adj=6.0; + break; + case 3840000: + gain_adj=9.0; + break; + case 1920000: + gain_adj=12.0; + break; + default: + LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); + exit(-1); + break; + } } - } - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - printf("cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, + openair0_cfg->rx_gain_calib_table[i].offset,diff); + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; + } + i++; } - i++; - } - } -/*! \brief print the USRP statistics +/*! \brief print the USRP statistics * \param device the hardware to use * \returns 0 on success */ int trx_usrp_get_stats(openair0_device* device) { - - return(0); - + return(0); } -/*! \brief Reset the USRP statistics -* \param device the hardware to use -* \returns 0 on success -*/ +/*! \brief Reset the USRP statistics + * \param device the hardware to use + * \returns 0 on success + */ int trx_usrp_reset_stats(openair0_device* device) { - - return(0); - + return(0); } - - extern "C" { -/*! \brief Initialize Openair USRP target. It returns 0 if OK -* \param device the hardware to use -* \param openair0_cfg RF frontend parameters set by application -*/ - int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { - - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t)); - memset(s, 0, sizeof(usrp_state_t)); - - // Initialize USRP device - - device->openair0_cfg = openair0_cfg; - - std::string args = "type=b200"; - - - uhd::device_addrs_t device_adds = uhd::device::find(args); - size_t i; - - int vers=0,subvers=0,subsubvers=0; - int bw_gain_adjust=0; - - sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); - - printf("Checking for USRPs : UHD %s (%d.%d.%d)\n",uhd::get_version_string().c_str(),vers,subvers,subsubvers); - - if(device_adds.size() == 0) - { - double usrp_master_clock = 184.32e6; - - std::string args = "type=x300"; - - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate - args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - -// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - - uhd::device_addrs_t device_adds = uhd::device::find(args); - - if(device_adds.size() == 0) - { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - - } - + /*! \brief Initialize Openair USRP target. It returns 0 if OK + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + */ + int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { + uhd::set_thread_priority_safe(1.0); + usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); + // Initialize USRP device + device->openair0_cfg = openair0_cfg; - printf("Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); + std::string args = "type=b200"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; - - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); - - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + int vers=0,subvers=0,subsubvers=0; + int bw_gain_adjust=0; - } else { - printf("Found USRP B200"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); - - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming - - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); + sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); + LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", + uhd::get_version_string().c_str(),vers,subvers,subsubvers); - device->type = USRP_B200_DEV; + if(device_adds.size() == 0) { + double usrp_master_clock = 184.32e6; + std::string args = "type=x300"; + // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate + args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } - else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } +// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } - - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - - for(i=0;i<s->usrp->get_rx_num_channels();i++) { - if (i<openair0_cfg[0].rx_num_channels) { - s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - //printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); - - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] > gain_range.stop()) { + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; + uhd::device_addrs_t device_adds = uhd::device::find(args); + + if(device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } + LOG_I(PHY,"Found USRP X300\n"); + s->usrp = uhd::usrp::multi_usrp::make(args); + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); + + //Setting device type to USRP X300/X310 + device->type=USRP_X300_DEV; + + // this is not working yet, master clock has to be set via constructor + // set master clock rate and sample rate for tx & rx for streaming + //s->usrp->set_master_clock_rate(usrp_master_clock); + + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + case 7680000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + case 1920000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + + } else { + LOG_I(PHY,"Found USRP B200\n"); + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + s->usrp = uhd::usrp::multi_usrp::make(args); + + // s->usrp->set_rx_subdev_spec(rx_subdev); + // s->usrp->set_tx_subdev_spec(tx_subdev); + + // do not explicitly set the clock to "internal", because this will disable the gpsdo + // // lock mboard clocks + // s->usrp->set_clock_source("internal"); + // set master clock rate and sample rate for tx & rx for streaming + + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); + + device->type = USRP_B200_DEV; + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + } + + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + + for(int i=0; i<s->usrp->get_rx_num_channels(); i++) { + if (i<openair0_cfg[0].rx_num_channels) { + s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); + set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); + // limit to maximum gain + AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), + "RX Gain too high, lower by %f dB\n", + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); + LOG_I(PHY,"RX Gain %d %f (%f) => %f (max %f)\n",i, + openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); + } + } + for(int i=0; i<s->usrp->get_tx_num_channels(); i++) { + if (i<openair0_cfg[0].tx_num_channels) { + s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); + s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); + } + } + + //s->usrp->set_clock_source("external"); + //s->usrp->set_time_source("external"); + + // display USRP settings + LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); + sleep(1); + + // create tx & rx streamer + uhd::stream_args_t stream_args_rx("sc16", "sc16"); + int samples=openair0_cfg[0].sample_rate; + int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); + samples/=10000; + LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); + if ( samples < max ) + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + LOG_I(PHY,"rx_max_num_samps %u\n", + s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + + for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) + stream_args_rx.channels.push_back(i); + s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); - printf("RX Gain %lu too high, lower by %f dB\n",i,openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - printf("RX Gain %lu %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } - } - for(i=0;i<s->usrp->get_tx_num_channels();i++) { - if (i<openair0_cfg[0].tx_num_channels) { - s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - //printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); - } - } - - - // display USRP settings - std::cout << boost::format("Actual master clock: %fMHz...") % (s->usrp->get_master_clock_rate()/1e6) << std::endl; - - sleep(1); - - // create tx & rx streamer - uhd::stream_args_t stream_args_rx("sc16", "sc16"); - int samples=openair0_cfg[0].sample_rate; - samples/=24000; - // stream_args_rx.args["spp"] = str(boost::format("%d") % samples); - - for (i = 0; i<openair0_cfg[0].rx_num_channels; i++) - stream_args_rx.channels.push_back(i); - s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); - std::cout << boost::format("rx_max_num_samps %u") % (s->rx_stream->get_max_num_samps()) << std::endl; - //openair0_cfg[0].samples_per_packet = s->rx_stream->get_max_num_samps(); - - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - //stream_args_tx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].tx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; i<openair0_cfg[0].tx_num_channels; i++) - stream_args_tx.channels.push_back(i); - s->tx_stream = s->usrp->get_tx_stream(stream_args_tx); - std::cout << boost::format("tx_max_num_samps %u") % (s->tx_stream->get_max_num_samps()) << std::endl; - - - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(i=0;i<s->usrp->get_tx_num_channels();i++) { - if (i<openair0_cfg[0].tx_num_channels) { - s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - } - } - for(i=0;i<s->usrp->get_rx_num_channels();i++) { - if (i<openair0_cfg[0].rx_num_channels) { - s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - } - } - - s->usrp->set_time_now(uhd::time_spec_t(0.0)); - - - for (i=0;i<openair0_cfg[0].rx_num_channels;i++) { - if (i<openair0_cfg[0].rx_num_channels) { - printf("RX Channel %lu\n",i); - std::cout << boost::format("Actual RX sample rate: %fMSps...") % (s->usrp->get_rx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX frequency: %fGHz...") % (s->usrp->get_rx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual RX gain: %f...") % (s->usrp->get_rx_gain(i)) << std::endl; - std::cout << boost::format("Actual RX bandwidth: %fM...") % (s->usrp->get_rx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX antenna: %s...") % (s->usrp->get_rx_antenna(i)) << std::endl; - } - } - - for (i=0;i<openair0_cfg[0].tx_num_channels;i++) { - - if (i<openair0_cfg[0].tx_num_channels) { - printf("TX Channel %lu\n",i); - std::cout << std::endl<<boost::format("Actual TX sample rate: %fMSps...") % (s->usrp->get_tx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX frequency: %fGHz...") % (s->usrp->get_tx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual TX gain: %f...") % (s->usrp->get_tx_gain(i)) << std::endl; - std::cout << boost::format("Actual TX bandwidth: %fM...") % (s->usrp->get_tx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX antenna: %s...") % (s->usrp->get_tx_antenna(i)) << std::endl; + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++) + stream_args_tx.channels.push_back(i); + s->tx_stream = s->usrp->get_tx_stream(stream_args_tx); + + /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ + for(int i=0; i<s->usrp->get_tx_num_channels() && i<openair0_cfg[0].tx_num_channels; i++) + s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + + for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++) + s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); + + s->usrp->set_time_now(uhd::time_spec_t(0.0)); + + for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) { + LOG_I(PHY,"RX Channel %d\n",i); + LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6); + LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); + LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); + LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); + LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + } + + for (int i=0; i<openair0_cfg[0].tx_num_channels; i++) { + LOG_I(PHY,"TX Channel %d\n",i); + LOG_I(PHY," Actual TX sample rate: %fMSps...\n", s->usrp->get_tx_rate(i)/1e6); + LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); + LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); + LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); + LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); + } + + LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); + + device->priv = s; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; + + s->sample_rate = openair0_cfg[0].sample_rate; + // TODO: + // init tx_forward_nsamps based usrp_time_offset ex + if(is_equal(s->sample_rate, (double)30.72e6)) + s->tx_forward_nsamps = 176; + if(is_equal(s->sample_rate, (double)15.36e6)) + s->tx_forward_nsamps = 90; + if(is_equal(s->sample_rate, (double)7.68e6)) + s->tx_forward_nsamps = 50; + return 0; } - } - - std::cout << boost::format("Device timestamp: %f...") % (s->usrp->get_time_now().get_real_secs()) << std::endl; - - device->priv = s; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - - s->sample_rate = openair0_cfg[0].sample_rate; - // TODO: - // init tx_forward_nsamps based usrp_time_offset ex - if(is_equal(s->sample_rate, (double)30.72e6)) - s->tx_forward_nsamps = 176; - if(is_equal(s->sample_rate, (double)15.36e6)) - s->tx_forward_nsamps = 90; - if(is_equal(s->sample_rate, (double)7.68e6)) - s->tx_forward_nsamps = 50; - return 0; - } } /*@}*/ diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index b70a9122ff0d5c6d8cc92ee3fc2085b31a91372b..3b673b8eaeb7b36247c3613428faea4f0b0c9c07 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -31,16 +31,16 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2630000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; - N_RB_DL = 25; + N_RB_DL = 50; Nid_cell_mbsfn = 0; nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 110; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 68b8050735e842e92165287656d675b6aea126ae..ed9d955e8a435889bc7bca129989c71c261339bc 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -29,37 +29,13 @@ * \note * \warning */ -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <sched.h> -#include <linux/sched.h> -#include <signal.h> -#include <execinfo.h> -#include <getopt.h> -#include <sys/sysinfo.h> + +#include "lte-softmodem.h" #include "T.h" #include "rt_wrapper.h" -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "assertions.h" -#include "msc.h" - -#include "PHY/types.h" - -#include "PHY/defs.h" -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "../../ARCH/COMMON/common_lib.h" #include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -94,34 +70,13 @@ unsigned short config_frames[4] = {2,9,11,13}; #endif #if defined(ENABLE_ITTI) -# include "intertask_interface_init.h" -# include "create_tasks.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -# include "SIMULATION/ETH_TRANSPORT/proto.h" -extern int netlink_init(void); -#endif -# endif +#include "intertask_interface_init.h" +#include "create_tasks.h" #endif #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #include "stats.h" -#endif - -// In lte-enb.c -extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg); -extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int,int); -extern void stop_eNB(int); -extern void kill_eNB_proc(void); - -// In lte-ue.c -extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg); -extern void fill_ue_band_info(void); -extern void init_UE(int); - -#ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; @@ -129,40 +84,24 @@ FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; char title[255]; unsigned char scope_enb_num_ue = 2; +static pthread_t forms_thread; //xforms #endif //XFORMS - - - - - pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. - - - - -#ifdef XFORMS -static pthread_t forms_thread; //xforms -#endif - uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] - #if defined(ENABLE_ITTI) volatile int start_eNB = 0; volatile int start_UE = 0; #endif volatile int oai_exit = 0; - - static clock_source_t clock_source = internal; - -static wait_for_sync = 0; +static int wait_for_sync = 0; static char UE_flag=0; unsigned int mmapped_dma=0; @@ -225,7 +164,6 @@ int otg_enabled; #endif //int number_of_cards = 1; - static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; eNB_func_t node_function[MAX_NUM_CCs]; eNB_timing_t node_timing[MAX_NUM_CCs]; @@ -237,9 +175,6 @@ uint32_t timing_advance = 0; uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots - -extern void reset_opp_meas(void); -extern void print_opp_meas(void); int transmission_mode=1; int16_t glog_level = LOG_INFO; @@ -270,12 +205,9 @@ int16_t osa_log_level = LOG_INFO; int16_t osa_log_verbosity = LOG_MED; #endif - - char *rrh_UE_ip = "127.0.0.1"; int rrh_UE_port = 51000; - /* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */ uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD; /* struct for ethernet specific parameters given in eNB conf file */ @@ -288,6 +220,7 @@ double cpuf; char uecap_xer[1024],uecap_xer_in=0; int oaisim_flag=0; +threads_t threads= {-1,-1,-1}; /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution @@ -299,69 +232,69 @@ uint8_t abstraction_flag=0; struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; -struct timespec clock_difftime(struct timespec start, struct timespec end) -{ - struct timespec temp; - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - return temp; +struct timespec clock_difftime(struct timespec start, struct timespec end) { + struct timespec temp; + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + return temp; } -void print_difftimes(void) -{ +void print_difftimes(void) { #ifdef DEBUG - printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); + printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); #else - LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); + LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); #endif } -void update_difftimes(struct timespec start, struct timespec end) -{ - struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - int changed = 0; - diff_time = clock_difftime(start, end); - if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; } - if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; } +void update_difftimes(struct timespec start, struct timespec end) { + struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + int changed = 0; + diff_time = clock_difftime(start, end); + if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { + min_diff_time.tv_nsec = diff_time.tv_nsec; + changed = 1; + } + if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { + max_diff_time.tv_nsec = diff_time.tv_nsec; + changed = 1; + } #if 1 - if (changed) print_difftimes(); + if (changed) print_difftimes(); #endif } /*------------------------------------------------------------------------*/ -unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) -{ - return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); +unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) { + return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); } -unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) -{ - return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); +unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { + return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); } #if !defined(ENABLE_ITTI) -void signal_handler(int sig) -{ - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - printf("trying to exit gracefully...\n"); - oai_exit = 1; - } +void signal_handler(int sig) { + void *array[10]; + size_t size; + + if (sig==SIGSEGV) { + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(-1); + } else { + printf("trying to exit gracefully...\n"); + oai_exit = 1; + } } #endif #define KNRM "\x1B[0m" @@ -413,40 +346,38 @@ void help (void) { printf(" -x Set the transmission mode, valid options: 1 \n"); printf(" -E Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"); #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"); + 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); + printf(RESET); + fflush(stdout); } -void exit_fun(const char* s) -{ - int CC_id; +void exit_fun(const char* s) { + int CC_id; - if (s != NULL) { - printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); - } - - oai_exit = 1; - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (UE_flag == 0) { - if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func) - PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); - if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func) - PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + if (s != NULL) { + printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); } - else { - if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) - PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + + oai_exit = 1; + + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (UE_flag == 0) { + if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func) + PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); + if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func) + PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + } else { + if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } } - } #if defined(ENABLE_ITTI) - sleep(1); //allow lte-softmodem threads to exit first - itti_terminate_tasks (TASK_UNKNOWN); + sleep(1); //allow lte-softmodem threads to exit first + itti_terminate_tasks (TASK_UNKNOWN); #endif } @@ -454,131 +385,129 @@ void exit_fun(const char* s) #ifdef XFORMS -void reset_stats(FL_OBJECT *button, long arg) -{ - int i,j,k; - PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0]; - - for (i=0; i<NUMBER_OF_UE_MAX; i++) { - for (k=0; k<8; k++) { //harq_processes - for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) { - phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; - phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; - phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; - } - - phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; - phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; - phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; +void reset_stats(FL_OBJECT *button, long arg) { + int i,j,k; + PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0]; + + for (i=0; i<NUMBER_OF_UE_MAX; i++) { + for (k=0; k<8; k++) { //harq_processes + for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; + } + + phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; + + for (j=0; j<phy_vars_eNB->ulsch[i]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0; + phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; + phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0; + phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0; + } + } - for (j=0; j<phy_vars_eNB->ulsch[i]->Mlimit; j++) { - phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0; - } + phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; + phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; + phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; } - - phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; - phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; - phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; - } } -static void *scope_thread(void *arg) -{ - char stats_buffer[16384]; +static void *scope_thread(void *arg) { + char stats_buffer[16384]; # ifdef ENABLE_XFORMS_WRITE_STATS - FILE *UE_stats, *eNB_stats; + FILE *UE_stats, *eNB_stats; # endif - int len = 0; - struct sched_param sched_param; - int UE_id, CC_id; - int ue_cnt=0; + int len = 0; + struct sched_param sched_param; + int UE_id, CC_id; + int ue_cnt=0; - sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; - sched_setscheduler(0, SCHED_FIFO,&sched_param); + sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; + sched_setscheduler(0, SCHED_FIFO,&sched_param); - printf("Scope thread has priority %d\n",sched_param.sched_priority); + printf("Scope thread has priority %d\n",sched_param.sched_priority); # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) - UE_stats = fopen("UE_stats.txt", "w"); - else - eNB_stats = fopen("eNB_stats.txt", "w"); + if (UE_flag==1) + UE_stats = fopen("UE_stats.txt", "w"); + else + eNB_stats = fopen("eNB_stats.txt", "w"); #endif - while (!oai_exit) { - if (UE_flag==1) { - len = dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); + while (!oai_exit) { + if (UE_flag==1) { + len = dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); + //fl_set_object_label(form_stats->stats_text, stats_buffer); + fl_clear_browser(form_stats->stats_text); + fl_add_browser_line(form_stats->stats_text, stats_buffer); - phy_scope_UE(form_ue[0], - PHY_vars_UE_g[0][0], - 0, - 0,7); + phy_scope_UE(form_ue[0], + PHY_vars_UE_g[0][0], + 0, + 0,7); - } else { - if (PHY_vars_eNB_g[0][0]->mac_enabled==1) { - len = dump_eNB_l2_stats (stats_buffer, 0); - //fl_set_object_label(form_stats_l2->stats_text, stats_buffer); - fl_clear_browser(form_stats_l2->stats_text); - fl_add_browser_line(form_stats_l2->stats_text, stats_buffer); - } - len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0); - - if (MAX_NUM_CCs>1) - len += dump_eNB_stats (PHY_vars_eNB_g[0][1], &stats_buffer[len], 0); - - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - - ue_cnt=0; - for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - // if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) { - if ((ue_cnt<scope_enb_num_ue)) { - phy_scope_eNB(form_enb[CC_id][ue_cnt], - PHY_vars_eNB_g[0][CC_id], - UE_id); - ue_cnt++; - } - } - } + } else { + if (PHY_vars_eNB_g[0][0]->mac_enabled==1) { + len = dump_eNB_l2_stats (stats_buffer, 0); + //fl_set_object_label(form_stats_l2->stats_text, stats_buffer); + fl_clear_browser(form_stats_l2->stats_text); + fl_add_browser_line(form_stats_l2->stats_text, stats_buffer); + } + len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0); + + if (MAX_NUM_CCs>1) + len += dump_eNB_stats (PHY_vars_eNB_g[0][1], &stats_buffer[len], 0); + + //fl_set_object_label(form_stats->stats_text, stats_buffer); + fl_clear_browser(form_stats->stats_text); + fl_add_browser_line(form_stats->stats_text, stats_buffer); + + ue_cnt=0; + for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + // if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) { + if ((ue_cnt<scope_enb_num_ue)) { + phy_scope_eNB(form_enb[CC_id][ue_cnt], + PHY_vars_eNB_g[0][CC_id], + UE_id); + ue_cnt++; + } + } + } - } + } - //printf("doing forms\n"); - //usleep(100000); // 100 ms - sleep(1); - } + //printf("doing forms\n"); + //usleep(100000); // 100 ms + sleep(1); + } - // printf("%s",stats_buffer); + // printf("%s",stats_buffer); # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) { - if (UE_stats) { - rewind (UE_stats); - fwrite (stats_buffer, 1, len, UE_stats); - fclose (UE_stats); - } - } else { - if (eNB_stats) { - rewind (eNB_stats); - fwrite (stats_buffer, 1, len, eNB_stats); - fclose (eNB_stats); + if (UE_flag==1) { + if (UE_stats) { + rewind (UE_stats); + fwrite (stats_buffer, 1, len, UE_stats); + fclose (UE_stats); + } + } else { + if (eNB_stats) { + rewind (eNB_stats); + fwrite (stats_buffer, 1, len, eNB_stats); + fclose (eNB_stats); + } } - } # endif - pthread_exit((void*)arg); + pthread_exit((void*)arg); } #endif @@ -586,161 +515,165 @@ static void *scope_thread(void *arg) #if defined(ENABLE_ITTI) -void *l2l1_task(void *arg) -{ - MessageDef *message_p = NULL; - int result; +void *l2l1_task(void *arg) { + MessageDef *message_p = NULL; + int result; - itti_set_task_real_time(TASK_L2L1); - itti_mark_task_ready(TASK_L2L1); + itti_set_task_real_time(TASK_L2L1); + itti_mark_task_ready(TASK_L2L1); + + if (UE_flag == 0) { + /* Wait for the initialize message */ + printf("Wait for the ITTI initialize message\n"); + do { + if (message_p != NULL) { + result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + + itti_receive_msg (TASK_L2L1, &message_p); + + switch (ITTI_MSG_ID(message_p)) { + case INITIALIZE_MESSAGE: + /* Start eNB thread */ + LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); + start_eNB = 1; + break; + + case TERMINATE_MESSAGE: + printf("received terminate message\n"); + oai_exit=1; + itti_exit_task (); + break; + + default: + LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + break; + } + } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE); - if (UE_flag == 0) { - /* Wait for the initialize message */ - printf("Wait for the ITTI initialize message\n"); - do { - if (message_p != NULL) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - - itti_receive_msg (TASK_L2L1, &message_p); - - switch (ITTI_MSG_ID(message_p)) { - case INITIALIZE_MESSAGE: - /* Start eNB thread */ - LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); - start_eNB = 1; - break; - - case TERMINATE_MESSAGE: - printf("received terminate message\n"); - oai_exit=1; - itti_exit_task (); - break; - - default: - LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } - } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE); - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } + } - do { - // Wait for a message - itti_receive_msg (TASK_L2L1, &message_p); + do { + // Wait for a message + itti_receive_msg (TASK_L2L1, &message_p); - switch (ITTI_MSG_ID(message_p)) { - case TERMINATE_MESSAGE: - oai_exit=1; - itti_exit_task (); - break; + switch (ITTI_MSG_ID(message_p)) { + case TERMINATE_MESSAGE: + oai_exit=1; + itti_exit_task (); + break; - case ACTIVATE_MESSAGE: - start_UE = 1; - break; + case ACTIVATE_MESSAGE: + start_UE = 1; + break; - case DEACTIVATE_MESSAGE: - start_UE = 0; - break; + case DEACTIVATE_MESSAGE: + start_UE = 0; + break; - case MESSAGE_TEST: - LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); - break; + case MESSAGE_TEST: + LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); + break; - default: - LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } + default: + LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + break; + } - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } while(!oai_exit); + result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while(!oai_exit); - return NULL; + return NULL; } #endif - -static void get_options (int argc, char **argv) -{ - int c; - // char line[1000]; - // int l; - int k,i;//,j,k; + +static void get_options (int argc, char **argv) { + int c; + // char line[1000]; + // int l; + int k,i;//,j,k; #if defined(OAI_USRP) || defined(CPRIGW) - int clock_src; + int clock_src; #endif - int CC_id; - + int CC_id; const Enb_properties_array_t *enb_properties; - enum long_option_e { - LONG_OPTION_START = 0x100, /* Start after regular single char options */ - LONG_OPTION_RF_CONFIG_FILE, - LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS, - LONG_OPTION_CALIB_UE_RX, - LONG_OPTION_CALIB_UE_RX_MED, - LONG_OPTION_CALIB_UE_RX_BYP, - LONG_OPTION_DEBUG_UE_PRACH, - LONG_OPTION_NO_L2_CONNECT, - LONG_OPTION_CALIB_PRACH_TX, - LONG_OPTION_RXGAIN, - LONG_OPTION_RXGAINOFF, - LONG_OPTION_TXGAIN, + enum long_option_e { + LONG_OPTION_START = 0x100, /* Start after regular single char options */ + LONG_OPTION_RF_CONFIG_FILE, + LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS, + LONG_OPTION_CALIB_UE_RX, + LONG_OPTION_CALIB_UE_RX_MED, + LONG_OPTION_CALIB_UE_RX_BYP, + LONG_OPTION_DEBUG_UE_PRACH, + LONG_OPTION_NO_L2_CONNECT, + LONG_OPTION_CALIB_PRACH_TX, + LONG_OPTION_RXGAIN, + LONG_OPTION_RXGAINOFF, + LONG_OPTION_TXGAIN, LONG_OPTION_NBRXANT, LONG_OPTION_NBTXANT, - LONG_OPTION_SCANCARRIER, - LONG_OPTION_MAXPOWER, - LONG_OPTION_DUMP_FRAME, - LONG_OPTION_LOOPMEMORY, - LONG_OPTION_PHYTEST, - LONG_OPTION_USIMTEST, - LONG_OPTION_MMAPPED_DMA, - LONG_OPTION_EXTERNAL_CLOCK, - LONG_OPTION_WAIT_FOR_SYNC, - LONG_OPTION_SINGLE_THREAD_DISABLE, + LONG_OPTION_SCANCARRIER, + LONG_OPTION_MAXPOWER, + LONG_OPTION_DUMP_FRAME, + LONG_OPTION_LOOPMEMORY, + LONG_OPTION_PHYTEST, + LONG_OPTION_USIMTEST, + LONG_OPTION_MMAPPED_DMA, + LONG_OPTION_EXTERNAL_CLOCK, + LONG_OPTION_WAIT_FOR_SYNC, + LONG_OPTION_SINGLE_THREAD_DISABLE, + LONG_OPTION_THREADIQ, + LONG_OPTION_THREADODDSUBFRAME, + LONG_OPTION_THREADEVENSUBFRAME, #if T_TRACER - LONG_OPTION_T_PORT, - LONG_OPTION_T_NOWAIT, - LONG_OPTION_T_DONT_FORK, + LONG_OPTION_T_PORT, + LONG_OPTION_T_NOWAIT, + LONG_OPTION_T_DONT_FORK, #endif - }; - static const struct option long_options[] = { - {"rf-config-file",required_argument, NULL, LONG_OPTION_RF_CONFIG_FILE}, - {"ulsch-max-errors",required_argument, NULL, LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS}, - {"calib-ue-rx", required_argument, NULL, LONG_OPTION_CALIB_UE_RX}, - {"calib-ue-rx-med", required_argument, NULL, LONG_OPTION_CALIB_UE_RX_MED}, - {"calib-ue-rx-byp", required_argument, NULL, LONG_OPTION_CALIB_UE_RX_BYP}, - {"debug-ue-prach", no_argument, NULL, LONG_OPTION_DEBUG_UE_PRACH}, - {"no-L2-connect", no_argument, NULL, LONG_OPTION_NO_L2_CONNECT}, - {"calib-prach-tx", no_argument, NULL, LONG_OPTION_CALIB_PRACH_TX}, - {"ue-rxgain", required_argument, NULL, LONG_OPTION_RXGAIN}, - {"ue-rxgain-off", required_argument, NULL, LONG_OPTION_RXGAINOFF}, - {"ue-txgain", required_argument, NULL, LONG_OPTION_TXGAIN}, - {"ue-nb-ant-rx", required_argument, NULL, LONG_OPTION_NBRXANT}, - {"ue-nb-ant-tx", required_argument, NULL, LONG_OPTION_NBTXANT}, - {"ue-scan-carrier", no_argument, NULL, LONG_OPTION_SCANCARRIER}, - {"ue-max-power", required_argument, NULL, LONG_OPTION_MAXPOWER}, - {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME}, - {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY}, - {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, - {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST}, - {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA}, - {"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK}, - {"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC}, - {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE}, + }; + + static const struct option long_options[] = { + {"rf-config-file",required_argument, NULL, LONG_OPTION_RF_CONFIG_FILE}, + {"ulsch-max-errors",required_argument, NULL, LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS}, + {"calib-ue-rx", required_argument, NULL, LONG_OPTION_CALIB_UE_RX}, + {"calib-ue-rx-med", required_argument, NULL, LONG_OPTION_CALIB_UE_RX_MED}, + {"calib-ue-rx-byp", required_argument, NULL, LONG_OPTION_CALIB_UE_RX_BYP}, + {"debug-ue-prach", no_argument, NULL, LONG_OPTION_DEBUG_UE_PRACH}, + {"no-L2-connect", no_argument, NULL, LONG_OPTION_NO_L2_CONNECT}, + {"calib-prach-tx", no_argument, NULL, LONG_OPTION_CALIB_PRACH_TX}, + {"ue-rxgain", required_argument, NULL, LONG_OPTION_RXGAIN}, + {"ue-rxgain-off", required_argument, NULL, LONG_OPTION_RXGAINOFF}, + {"ue-txgain", required_argument, NULL, LONG_OPTION_TXGAIN}, + {"ue-nb-ant-rx", required_argument, NULL, LONG_OPTION_NBRXANT}, + {"ue-nb-ant-tx", required_argument, NULL, LONG_OPTION_NBTXANT}, + {"ue-scan-carrier", no_argument, NULL, LONG_OPTION_SCANCARRIER}, + {"ue-max-power", required_argument, NULL, LONG_OPTION_MAXPOWER}, + {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME}, + {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY}, + {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, + {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST}, + {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA}, + {"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK}, + {"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC}, + {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE}, + {"threadIQ", required_argument, NULL, LONG_OPTION_THREADIQ}, + {"threadOddSubframe", required_argument, NULL, LONG_OPTION_THREADODDSUBFRAME}, + {"threadEvenSubframe", required_argument, NULL, LONG_OPTION_THREADEVENSUBFRAME}, #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}, + {"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} }; @@ -858,393 +791,403 @@ static void get_options (int argc, char **argv) wait_for_sync = 1; break; + case LONG_OPTION_THREADIQ: + threads.iq=atoi(optarg); + break; + case LONG_OPTION_THREADODDSUBFRAME: + threads.odd=atoi(optarg); + break; + case LONG_OPTION_THREADEVENSUBFRAME: + threads.even=atoi(optarg); + break; + #if T_TRACER - case LONG_OPTION_T_PORT: { - extern int T_port; - if (optarg == NULL) abort(); /* should not happen */ - T_port = atoi(optarg); - break; - } + case LONG_OPTION_T_PORT: { + extern int T_port; + if (optarg == NULL) abort(); /* should not happen */ + T_port = atoi(optarg); + break; + } - case LONG_OPTION_T_NOWAIT: { - extern int T_wait; - T_wait = 0; - break; - } + case LONG_OPTION_T_NOWAIT: { + extern int T_wait; + T_wait = 0; + break; + } - case LONG_OPTION_T_DONT_FORK: { - extern int T_dont_fork; - T_dont_fork = 1; - break; - } + case LONG_OPTION_T_DONT_FORK: { + extern int T_dont_fork; + T_dont_fork = 1; + break; + } #endif - case 'A': - timing_advance = atoi (optarg); - break; + case 'A': + timing_advance = atoi (optarg); + break; - case 'C': - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - downlink_frequency[CC_id][0] = atof(optarg); // Use float to avoid issue with frequency over 2^31. - downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; - downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; - downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; - printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]); - } + case 'C': + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + downlink_frequency[CC_id][0] = atof(optarg); // Use float to avoid issue with frequency over 2^31. + downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; + printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]); + } - UE_scan=0; + UE_scan=0; - break; + break; - case 'a': - chain_offset = atoi(optarg); - break; + case 'a': + chain_offset = atoi(optarg); + break; - case 'd': + case 'd': #ifdef XFORMS - do_forms=1; - printf("Running with XFORMS!\n"); + do_forms=1; + printf("Running with XFORMS!\n"); #endif - break; - - case 'E': - threequarter_fs=1; - break; + break; + + case 'E': + threequarter_fs=1; + break; - case 'K': + case 'K': #if defined(ENABLE_ITTI) - itti_dump_file = strdup(optarg); + itti_dump_file = strdup(optarg); #else - printf("-K option is disabled when ENABLE_ITTI is not defined\n"); + printf("-K option is disabled when ENABLE_ITTI is not defined\n"); #endif - break; - - case 'O': - conf_config_file_name = optarg; - break; - - case 'U': - UE_flag = 1; - break; - - case 'm': - target_dl_mcs = atoi (optarg); - break; - - case 't': - target_ul_mcs = atoi (optarg); - break; - - case 'W': - opt_enabled=1; - opt_type = OPT_WIRESHARK; - strncpy(in_ip, "127.0.0.1", sizeof(in_ip)); - in_ip[sizeof(in_ip) - 1] = 0; // terminate string - printf("Enabling OPT for wireshark for local interface"); - /* - if (optarg == NULL){ - in_ip[0] =NULL; - printf("Enabling OPT for wireshark for local interface"); - } else { - strncpy(in_ip, optarg, sizeof(in_ip)); - in_ip[sizeof(in_ip) - 1] = 0; // terminate string - printf("Enabling OPT for wireshark with %s \n",in_ip); - } - */ - break; - - case 'P': - opt_type = OPT_PCAP; - opt_enabled=1; - - if (optarg == NULL) { - strncpy(in_path, "/tmp/oai_opt.pcap", sizeof(in_path)); - in_path[sizeof(in_path) - 1] = 0; // terminate string - printf("Enabling OPT for PCAP with the following path /tmp/oai_opt.pcap"); - } else { - strncpy(in_path, optarg, sizeof(in_path)); - in_path[sizeof(in_path) - 1] = 0; // terminate string - printf("Enabling OPT for PCAP with the following file %s \n",in_path); - } - - break; - - case 'V': - ouput_vcd = 1; - break; - - case 'q': - opp_enabled = 1; - break; - - case 'R' : - online_log_messages =1; - break; - - case 'r': - UE_scan = 0; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - switch(atoi(optarg)) { - case 6: - frame_parms[CC_id]->N_RB_DL=6; - frame_parms[CC_id]->N_RB_UL=6; - break; - - case 25: - frame_parms[CC_id]->N_RB_DL=25; - frame_parms[CC_id]->N_RB_UL=25; - break; - - case 50: - frame_parms[CC_id]->N_RB_DL=50; - frame_parms[CC_id]->N_RB_UL=50; - break; - - case 100: - frame_parms[CC_id]->N_RB_DL=100; - frame_parms[CC_id]->N_RB_UL=100; - break; - - default: - printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg)); - break; - } - } - - break; - - case 's': + break; + + case 'O': + conf_config_file_name = optarg; + break; + + case 'U': + UE_flag = 1; + break; + + case 'm': + target_dl_mcs = atoi (optarg); + break; + + case 't': + target_ul_mcs = atoi (optarg); + break; + + case 'W': + opt_enabled=1; + opt_type = OPT_WIRESHARK; + strncpy(in_ip, "127.0.0.1", sizeof(in_ip)); + in_ip[sizeof(in_ip) - 1] = 0; // terminate string + printf("Enabling OPT for wireshark for local interface"); + /* + if (optarg == NULL){ + in_ip[0] =NULL; + printf("Enabling OPT for wireshark for local interface"); + } else { + strncpy(in_ip, optarg, sizeof(in_ip)); + in_ip[sizeof(in_ip) - 1] = 0; // terminate string + printf("Enabling OPT for wireshark with %s \n",in_ip); + } + */ + break; + + case 'P': + opt_type = OPT_PCAP; + opt_enabled=1; + + if (optarg == NULL) { + strncpy(in_path, "/tmp/oai_opt.pcap", sizeof(in_path)); + in_path[sizeof(in_path) - 1] = 0; // terminate string + printf("Enabling OPT for PCAP with the following path /tmp/oai_opt.pcap"); + } else { + strncpy(in_path, optarg, sizeof(in_path)); + in_path[sizeof(in_path) - 1] = 0; // terminate string + printf("Enabling OPT for PCAP with the following file %s \n",in_path); + } + + break; + + case 'V': + ouput_vcd = 1; + break; + + case 'q': + opp_enabled = 1; + break; + + case 'R' : + online_log_messages =1; + break; + + case 'r': + UE_scan = 0; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + switch(atoi(optarg)) { + case 6: + frame_parms[CC_id]->N_RB_DL=6; + frame_parms[CC_id]->N_RB_UL=6; + break; + + case 25: + frame_parms[CC_id]->N_RB_DL=25; + frame_parms[CC_id]->N_RB_UL=25; + break; + + case 50: + frame_parms[CC_id]->N_RB_DL=50; + frame_parms[CC_id]->N_RB_UL=50; + break; + + case 100: + frame_parms[CC_id]->N_RB_DL=100; + frame_parms[CC_id]->N_RB_UL=100; + break; + + default: + printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg)); + break; + } + } + + break; + + case 's': #if defined(OAI_USRP) || defined(CPRIGW) - clock_src = atoi(optarg); + clock_src = atoi(optarg); - if (clock_src == 0) { - // char ref[128] = "internal"; - //strncpy(uhd_ref, ref, strlen(ref)+1); - } else if (clock_src == 1) { - //char ref[128] = "external"; - //strncpy(uhd_ref, ref, strlen(ref)+1); - } + if (clock_src == 0) { + // char ref[128] = "internal"; + //strncpy(uhd_ref, ref, strlen(ref)+1); + } else if (clock_src == 1) { + //char ref[128] = "external"; + //strncpy(uhd_ref, ref, strlen(ref)+1); + } #else - printf("Note: -s not defined for ExpressMIMO2\n"); + printf("Note: -s not defined for ExpressMIMO2\n"); #endif - break; - - case 'S': - exit_missed_slots=0; - printf("Skip exit for missed slots\n"); - break; - - case 'g': - glog_level=atoi(optarg); // value between 1 - 9 - break; + break; + + case 'S': + exit_missed_slots=0; + printf("Skip exit for missed slots\n"); + break; + + case 'g': + glog_level=atoi(optarg); // value between 1 - 9 + break; + + case 'F': + break; + + case 'G': + glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75 + break; + + case 'x': + printf("Transmission mode should be set in config file now\n"); + exit(-1); + /* + transmission_mode = atoi(optarg); + + if (transmission_mode > 7) { + printf("Transmission mode %d not supported for the moment\n",transmission_mode); + exit(-1); + } + */ + break; + + case 'T': + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) + frame_parms[CC_id]->frame_type = TDD; + break; + + case 'h': + help (); + exit (-1); - case 'F': - break; - - case 'G': - glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75 - break; - - case 'x': - printf("Transmission mode should be set in config file now\n"); - exit(-1); - /* - transmission_mode = atoi(optarg); - - if (transmission_mode > 7) { - printf("Transmission mode %d not supported for the moment\n",transmission_mode); - exit(-1); - } - */ - break; - - case 'T': - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) - frame_parms[CC_id]->frame_type = TDD; - break; - - case 'h': - help (); - exit (-1); - - default: - help (); - exit (-1); - break; - } - } - - if (UE_flag == 0) - AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n"); - - if ((UE_flag == 0) && (conf_config_file_name != NULL)) { - int i,j; - - NB_eNB_INST = 1; - - /* Read eNB configuration file */ - enb_properties = enb_config_init(conf_config_file_name); - - AssertFatal (NB_eNB_INST <= enb_properties->number, - "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!", - conf_config_file_name, NB_eNB_INST, enb_properties->number); - - /* Update some simulation parameters */ - for (i=0; i < enb_properties->number; i++) { - AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc, - "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!", - MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i); - eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); - memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); - - for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) { - - if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) { - local_remote_radio = BBU_REMOTE_RADIO_HEAD; - (eth_params+j)->local_if_name = enb_properties->properties[i]->rrh_gw_config[j].rrh_gw_if_name; - (eth_params+j)->my_addr = enb_properties->properties[i]->rrh_gw_config[j].local_address; - (eth_params+j)->my_port = enb_properties->properties[i]->rrh_gw_config[j].local_port; - (eth_params+j)->remote_addr = enb_properties->properties[i]->rrh_gw_config[j].remote_address; - (eth_params+j)->remote_port = enb_properties->properties[i]->rrh_gw_config[j].remote_port; - - if (enb_properties->properties[i]->rrh_gw_config[j].raw == 1) { - (eth_params+j)->transp_preference = ETH_RAW_MODE; - } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) { - (eth_params+j)->transp_preference = ETH_RAW_IF4p5_MODE; - } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) { - (eth_params+j)->transp_preference = ETH_UDP_IF4p5_MODE; - } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) { - (eth_params+j)->transp_preference = ETH_RAW_IF5_MOBIPASS; - } else { - (eth_params+j)->transp_preference = ETH_UDP_MODE; - } - - (eth_params+j)->iq_txshift = enb_properties->properties[i]->rrh_gw_config[j].iq_txshift; - (eth_params+j)->tx_sample_advance = enb_properties->properties[i]->rrh_gw_config[j].tx_sample_advance; - (eth_params+j)->tx_scheduling_advance = enb_properties->properties[i]->rrh_gw_config[j].tx_scheduling_advance; - if (enb_properties->properties[i]->rrh_gw_config[j].exmimo == 1) { - (eth_params+j)->rf_preference = EXMIMO_DEV; - } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_b200 == 1) { - (eth_params+j)->rf_preference = USRP_B200_DEV; - } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_x300 == 1) { - (eth_params+j)->rf_preference = USRP_X300_DEV; - } else if (enb_properties->properties[i]->rrh_gw_config[j].bladerf == 1) { - (eth_params+j)->rf_preference = BLADERF_DEV; - } else if (enb_properties->properties[i]->rrh_gw_config[j].lmssdr == 1) { - //(eth_params+j)->rf_preference = LMSSDR_DEV; - } else { - (eth_params+j)->rf_preference = 0; - } - } else { - local_remote_radio = BBU_LOCAL_RADIO_HEAD; + default: + help (); + exit (-1); + break; } - - } - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - - node_function[CC_id] = enb_properties->properties[i]->cc_node_function[CC_id]; - node_timing[CC_id] = enb_properties->properties[i]->cc_node_timing[CC_id]; - node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id]; - - frame_parms[CC_id]->frame_type = enb_properties->properties[i]->frame_type[CC_id]; - frame_parms[CC_id]->tdd_config = enb_properties->properties[i]->tdd_config[CC_id]; - frame_parms[CC_id]->tdd_config_S = enb_properties->properties[i]->tdd_config_s[CC_id]; - frame_parms[CC_id]->Ncp = enb_properties->properties[i]->prefix_type[CC_id]; - - //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){ - frame_parms[CC_id]->Nid_cell = enb_properties->properties[i]->Nid_cell[CC_id]; - frame_parms[CC_id]->N_RB_DL = enb_properties->properties[i]->N_RB_DL[CC_id]; - frame_parms[CC_id]->N_RB_UL = enb_properties->properties[i]->N_RB_DL[CC_id]; - frame_parms[CC_id]->nb_antennas_tx = enb_properties->properties[i]->nb_antennas_tx[CC_id]; - frame_parms[CC_id]->nb_antenna_ports_eNB = enb_properties->properties[i]->nb_antenna_ports[CC_id]; - frame_parms[CC_id]->nb_antennas_rx = enb_properties->properties[i]->nb_antennas_rx[CC_id]; - - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id]; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset = enb_properties->properties[i]->prach_freq_offset[CC_id]; - - frame_parms[CC_id]->mode1_flag = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0; - frame_parms[CC_id]->threequarter_fs = threequarter_fs; - - //} // j - } - - - init_all_otg(0); - g_otg->seed = 0; - init_seeds(g_otg->seed); - - for (k=0; k<enb_properties->properties[i]->num_otg_elements; k++) { - j=enb_properties->properties[i]->otg_ue_id[k]; // ue_id - g_otg->application_idx[i][j] = 1; - //g_otg->packet_gen_type=SUBSTRACT_STRING; - g_otg->background[i][j][0] =enb_properties->properties[i]->otg_bg_traffic[k]; - g_otg->application_type[i][j][0] =enb_properties->properties[i]->otg_app_type[k];// BCBR; //MCBR, BCBR - - printf("[OTG] configuring traffic type %d for eNB %d UE %d (Background traffic is %s)\n", - g_otg->application_type[i][j][0], i, j,(g_otg->background[i][j][0]==1)?"Enabled":"Disabled"); - } + } - init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1); - - - glog_level = enb_properties->properties[i]->glog_level; - glog_verbosity = enb_properties->properties[i]->glog_verbosity; - hw_log_level = enb_properties->properties[i]->hw_log_level; - hw_log_verbosity = enb_properties->properties[i]->hw_log_verbosity ; - phy_log_level = enb_properties->properties[i]->phy_log_level; - phy_log_verbosity = enb_properties->properties[i]->phy_log_verbosity; - mac_log_level = enb_properties->properties[i]->mac_log_level; - mac_log_verbosity = enb_properties->properties[i]->mac_log_verbosity; - rlc_log_level = enb_properties->properties[i]->rlc_log_level; - rlc_log_verbosity = enb_properties->properties[i]->rlc_log_verbosity; - pdcp_log_level = enb_properties->properties[i]->pdcp_log_level; - pdcp_log_verbosity = enb_properties->properties[i]->pdcp_log_verbosity; - rrc_log_level = enb_properties->properties[i]->rrc_log_level; - rrc_log_verbosity = enb_properties->properties[i]->rrc_log_verbosity; + if (UE_flag == 0) + AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n"); + + if ((UE_flag == 0) && (conf_config_file_name != NULL)) { + int i,j; + + NB_eNB_INST = 1; + + /* Read eNB configuration file */ + enb_properties = enb_config_init(conf_config_file_name); + + AssertFatal (NB_eNB_INST <= enb_properties->number, + "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!", + conf_config_file_name, NB_eNB_INST, enb_properties->number); + + /* Update some simulation parameters */ + for (i=0; i < enb_properties->number; i++) { + AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc, + "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!", + MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i); + eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); + memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); + + for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) { + + if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) { + local_remote_radio = BBU_REMOTE_RADIO_HEAD; + (eth_params+j)->local_if_name = enb_properties->properties[i]->rrh_gw_config[j].rrh_gw_if_name; + (eth_params+j)->my_addr = enb_properties->properties[i]->rrh_gw_config[j].local_address; + (eth_params+j)->my_port = enb_properties->properties[i]->rrh_gw_config[j].local_port; + (eth_params+j)->remote_addr = enb_properties->properties[i]->rrh_gw_config[j].remote_address; + (eth_params+j)->remote_port = enb_properties->properties[i]->rrh_gw_config[j].remote_port; + + if (enb_properties->properties[i]->rrh_gw_config[j].raw == 1) { + (eth_params+j)->transp_preference = ETH_RAW_MODE; + } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) { + (eth_params+j)->transp_preference = ETH_RAW_IF4p5_MODE; + } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) { + (eth_params+j)->transp_preference = ETH_UDP_IF4p5_MODE; + } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) { + (eth_params+j)->transp_preference = ETH_RAW_IF5_MOBIPASS; + } else { + (eth_params+j)->transp_preference = ETH_UDP_MODE; + } + + (eth_params+j)->iq_txshift = enb_properties->properties[i]->rrh_gw_config[j].iq_txshift; + (eth_params+j)->tx_sample_advance = enb_properties->properties[i]->rrh_gw_config[j].tx_sample_advance; + (eth_params+j)->tx_scheduling_advance = enb_properties->properties[i]->rrh_gw_config[j].tx_scheduling_advance; + if (enb_properties->properties[i]->rrh_gw_config[j].exmimo == 1) { + (eth_params+j)->rf_preference = EXMIMO_DEV; + } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_b200 == 1) { + (eth_params+j)->rf_preference = USRP_B200_DEV; + } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_x300 == 1) { + (eth_params+j)->rf_preference = USRP_X300_DEV; + } else if (enb_properties->properties[i]->rrh_gw_config[j].bladerf == 1) { + (eth_params+j)->rf_preference = BLADERF_DEV; + } else if (enb_properties->properties[i]->rrh_gw_config[j].lmssdr == 1) { + //(eth_params+j)->rf_preference = LMSSDR_DEV; + } else { + (eth_params+j)->rf_preference = 0; + } + } else { + local_remote_radio = BBU_LOCAL_RADIO_HEAD; + } + + } + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + + node_function[CC_id] = enb_properties->properties[i]->cc_node_function[CC_id]; + node_timing[CC_id] = enb_properties->properties[i]->cc_node_timing[CC_id]; + node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id]; + + frame_parms[CC_id]->frame_type = enb_properties->properties[i]->frame_type[CC_id]; + frame_parms[CC_id]->tdd_config = enb_properties->properties[i]->tdd_config[CC_id]; + frame_parms[CC_id]->tdd_config_S = enb_properties->properties[i]->tdd_config_s[CC_id]; + frame_parms[CC_id]->Ncp = enb_properties->properties[i]->prefix_type[CC_id]; + + //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){ + frame_parms[CC_id]->Nid_cell = enb_properties->properties[i]->Nid_cell[CC_id]; + frame_parms[CC_id]->N_RB_DL = enb_properties->properties[i]->N_RB_DL[CC_id]; + frame_parms[CC_id]->N_RB_UL = enb_properties->properties[i]->N_RB_DL[CC_id]; + frame_parms[CC_id]->nb_antennas_tx = enb_properties->properties[i]->nb_antennas_tx[CC_id]; + frame_parms[CC_id]->nb_antenna_ports_eNB = enb_properties->properties[i]->nb_antenna_ports[CC_id]; + frame_parms[CC_id]->nb_antennas_rx = enb_properties->properties[i]->nb_antennas_rx[CC_id]; + + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id]; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset = enb_properties->properties[i]->prach_freq_offset[CC_id]; + + frame_parms[CC_id]->mode1_flag = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0; + frame_parms[CC_id]->threequarter_fs = threequarter_fs; + + //} // j + } + + + init_all_otg(0); + g_otg->seed = 0; + init_seeds(g_otg->seed); + + for (k=0; k<enb_properties->properties[i]->num_otg_elements; k++) { + j=enb_properties->properties[i]->otg_ue_id[k]; // ue_id + g_otg->application_idx[i][j] = 1; + //g_otg->packet_gen_type=SUBSTRACT_STRING; + g_otg->background[i][j][0] =enb_properties->properties[i]->otg_bg_traffic[k]; + g_otg->application_type[i][j][0] =enb_properties->properties[i]->otg_app_type[k];// BCBR; //MCBR, BCBR + + printf("[OTG] configuring traffic type %d for eNB %d UE %d (Background traffic is %s)\n", + g_otg->application_type[i][j][0], i, j,(g_otg->background[i][j][0]==1)?"Enabled":"Disabled"); + } + + init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1); + + + glog_level = enb_properties->properties[i]->glog_level; + glog_verbosity = enb_properties->properties[i]->glog_verbosity; + hw_log_level = enb_properties->properties[i]->hw_log_level; + hw_log_verbosity = enb_properties->properties[i]->hw_log_verbosity ; + phy_log_level = enb_properties->properties[i]->phy_log_level; + phy_log_verbosity = enb_properties->properties[i]->phy_log_verbosity; + mac_log_level = enb_properties->properties[i]->mac_log_level; + mac_log_verbosity = enb_properties->properties[i]->mac_log_verbosity; + rlc_log_level = enb_properties->properties[i]->rlc_log_level; + rlc_log_verbosity = enb_properties->properties[i]->rlc_log_verbosity; + pdcp_log_level = enb_properties->properties[i]->pdcp_log_level; + pdcp_log_verbosity = enb_properties->properties[i]->pdcp_log_verbosity; + rrc_log_level = enb_properties->properties[i]->rrc_log_level; + rrc_log_verbosity = enb_properties->properties[i]->rrc_log_verbosity; # if defined(ENABLE_USE_MME) - gtpu_log_level = enb_properties->properties[i]->gtpu_log_level; - gtpu_log_verbosity = enb_properties->properties[i]->gtpu_log_verbosity; - udp_log_level = enb_properties->properties[i]->udp_log_level; - udp_log_verbosity = enb_properties->properties[i]->udp_log_verbosity; + gtpu_log_level = enb_properties->properties[i]->gtpu_log_level; + gtpu_log_verbosity = enb_properties->properties[i]->gtpu_log_verbosity; + udp_log_level = enb_properties->properties[i]->udp_log_level; + udp_log_verbosity = enb_properties->properties[i]->udp_log_verbosity; #endif #if defined (ENABLE_SECURITY) - osa_log_level = enb_properties->properties[i]->osa_log_level; - osa_log_verbosity = enb_properties->properties[i]->osa_log_verbosity; + osa_log_level = enb_properties->properties[i]->osa_log_level; + osa_log_verbosity = enb_properties->properties[i]->osa_log_verbosity; #endif - // adjust the log - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - for (k = 0 ; k < 4; k++) { - downlink_frequency[CC_id][k] = enb_properties->properties[i]->downlink_frequency[CC_id]; - uplink_frequency_offset[CC_id][k] = enb_properties->properties[i]->uplink_frequency_offset[CC_id]; - rx_gain[CC_id][k] = (double)enb_properties->properties[i]->rx_gain[CC_id]; - tx_gain[CC_id][k] = (double)enb_properties->properties[i]->tx_gain[CC_id]; - } + // adjust the log + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + for (k = 0 ; k < 4; k++) { + downlink_frequency[CC_id][k] = enb_properties->properties[i]->downlink_frequency[CC_id]; + uplink_frequency_offset[CC_id][k] = enb_properties->properties[i]->uplink_frequency_offset[CC_id]; + rx_gain[CC_id][k] = (double)enb_properties->properties[i]->rx_gain[CC_id]; + tx_gain[CC_id][k] = (double)enb_properties->properties[i]->tx_gain[CC_id]; + } - printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id, - enb_properties->properties[i]->downlink_frequency[CC_id], - enb_properties->properties[i]->uplink_frequency_offset[CC_id]); + printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id, + enb_properties->properties[i]->downlink_frequency[CC_id], + enb_properties->properties[i]->uplink_frequency_offset[CC_id]); - } // CC_id - }// i + } // CC_id + }// i - //this is needed for phy-test option - transmission_mode = enb_properties->properties[0]->ue_TransmissionMode[0]+1; + //this is needed for phy-test option + transmission_mode = enb_properties->properties[0]->ue_TransmissionMode[0]+1; - } else if (UE_flag == 1) { - if (conf_config_file_name != NULL) { - - // Here the configuration file is the XER encoded UE capabilities - // Read it in and store in asn1c data structures - strcpy(uecap_xer,conf_config_file_name); - uecap_xer_in=1; + } else if (UE_flag == 1) { + if (conf_config_file_name != NULL) { + + // Here the configuration file is the XER encoded UE capabilities + // Read it in and store in asn1c data structures + strcpy(uecap_xer,conf_config_file_name); + uecap_xer_in=1; + } } - } } #if T_TRACER @@ -1256,47 +1199,47 @@ int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { - int CC_id; + int CC_id; - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); - /* Set some default values that may be overwritten while reading options */ - frame_parms[CC_id]->frame_type = FDD; - frame_parms[CC_id]->tdd_config = 3; - frame_parms[CC_id]->tdd_config_S = 0; - frame_parms[CC_id]->N_RB_DL = 100; - frame_parms[CC_id]->N_RB_UL = 100; - frame_parms[CC_id]->Ncp = NORMAL; - frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms[CC_id]->Nid_cell = 0; - frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms[CC_id]->nb_antenna_ports_eNB = 1; - frame_parms[CC_id]->nb_antennas_tx = 1; - frame_parms[CC_id]->nb_antennas_rx = 1; - - frame_parms[CC_id]->nushift = 0; - - frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; - frame_parms[CC_id]->phich_config_common.phich_duration = normal; - // UL RS Config - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - - frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; - - downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31. - downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; - downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; - downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; - //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]); + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); + /* Set some default values that may be overwritten while reading options */ + frame_parms[CC_id]->frame_type = FDD; + frame_parms[CC_id]->tdd_config = 3; + frame_parms[CC_id]->tdd_config_S = 0; + frame_parms[CC_id]->N_RB_DL = 100; + frame_parms[CC_id]->N_RB_UL = 100; + frame_parms[CC_id]->Ncp = NORMAL; + frame_parms[CC_id]->Ncp_UL = NORMAL; + frame_parms[CC_id]->Nid_cell = 0; + frame_parms[CC_id]->num_MBSFN_config = 0; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; + frame_parms[CC_id]->nb_antennas_tx = 1; + frame_parms[CC_id]->nb_antennas_rx = 1; + + frame_parms[CC_id]->nushift = 0; + + frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; + frame_parms[CC_id]->phich_config_common.phich_duration = normal; + // UL RS Config + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; + + frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; + + downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31. + downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; + //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]); - } + } } @@ -1304,43 +1247,45 @@ void init_openair0(void); void init_openair0() { - int card; - int i; + int card; + int i; + + for (card=0; card<MAX_CARDS; card++) { + + openair0_cfg[card].mmapped_dma=mmapped_dma; + openair0_cfg[card].configFilename = NULL; + + if(frame_parms[0]->N_RB_DL == 100) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=23.04e6; + openair0_cfg[card].samples_per_frame = 230400; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } else { + openair0_cfg[card].sample_rate=30.72e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } + } else if(frame_parms[0]->N_RB_DL == 50) { + openair0_cfg[card].sample_rate=15.36e6; + openair0_cfg[card].samples_per_frame = 153600; + openair0_cfg[card].tx_bw = 5e6; + openair0_cfg[card].rx_bw = 5e6; + } else if (frame_parms[0]->N_RB_DL == 25) { + openair0_cfg[card].sample_rate=7.68e6; + openair0_cfg[card].samples_per_frame = 76800; + openair0_cfg[card].tx_bw = 2.5e6; + openair0_cfg[card].rx_bw = 2.5e6; + } else if (frame_parms[0]->N_RB_DL == 6) { + openair0_cfg[card].sample_rate=1.92e6; + openair0_cfg[card].samples_per_frame = 19200; + openair0_cfg[card].tx_bw = 1.5e6; + openair0_cfg[card].rx_bw = 1.5e6; + } - for (card=0; card<MAX_CARDS; card++) { - openair0_cfg[card].mmapped_dma=mmapped_dma; - openair0_cfg[card].configFilename = NULL; - if(frame_parms[0]->N_RB_DL == 100) { - if (frame_parms[0]->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - } else if(frame_parms[0]->N_RB_DL == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - } else if (frame_parms[0]->N_RB_DL == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; - } else if (frame_parms[0]->N_RB_DL == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; - } if (frame_parms[0]->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; @@ -1404,162 +1349,161 @@ void init_openair0() { } } -int main( int argc, char **argv ) -{ - int i,j,k,aa,re; +int main( int argc, char **argv ) { + int i,j,k,aa,re; #if defined (XFORMS) - void *status; + void *status; #endif - int CC_id; - uint8_t abstraction_flag=0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + int CC_id; + uint8_t abstraction_flag=0; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; #if defined (XFORMS) - int ret; + int ret; #endif #ifdef DEBUG_CONSOLE - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); #endif - PHY_VARS_UE *UE[MAX_NUM_CCs]; + PHY_VARS_UE *UE[MAX_NUM_CCs]; + + mode = normal_txrx; + memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); - mode = normal_txrx; - memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); + memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); + set_latency_target(); - memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); - set_latency_target(); + // set default parameters + set_default_frame_parms(frame_parms); - // set default parameters - set_default_frame_parms(frame_parms); + // initialize logging + logInit(); + + // get options and fill parameters from configuration file + get_options (argc, argv); //Command-line options, enb_properties - // initialize logging - logInit(); - // get options and fill parameters from configuration file - get_options (argc, argv); //Command-line options, enb_properties - - #if T_TRACER - T_init(T_port, T_wait, T_dont_fork); + T_init(T_port, T_wait, T_dont_fork); #endif - // initialize the log (see log.h for details) - set_glog(glog_level, glog_verbosity); - - //randominit (0); - set_taus_seed (0); + // initialize the log (see log.h for details) + set_glog(glog_level, glog_verbosity); - if (UE_flag==1) { - printf("configuring for UE\n"); + //randominit (0); + set_taus_seed (0); - set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); - set_comp_log(PHY, LOG_DEBUG, LOG_HIGH, 1); - set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RLC, LOG_INFO, LOG_HIGH, 1); - set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); - set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); + if (UE_flag==1) { + printf("configuring for UE\n"); + + set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); + set_comp_log(PHY, LOG_DEBUG, LOG_HIGH, 1); + set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RLC, LOG_INFO, LOG_HIGH, 1); + set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); + set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); #if defined(ENABLE_ITTI) - set_comp_log(EMU, LOG_INFO, LOG_MED, 1); + set_comp_log(EMU, LOG_INFO, LOG_MED, 1); # if defined(ENABLE_USE_MME) - set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); + set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); # endif #endif - } else { - printf("configuring for eNB\n"); - - set_comp_log(HW, hw_log_level, hw_log_verbosity, 1); - set_comp_log(PHY, phy_log_level, phy_log_verbosity, 1); - if (opt_enabled == 1 ) - set_comp_log(OPT, opt_log_level, opt_log_verbosity, 1); - set_comp_log(MAC, mac_log_level, mac_log_verbosity, 1); - set_comp_log(RLC, rlc_log_level, rlc_log_verbosity, 1); - set_comp_log(PDCP, pdcp_log_level, pdcp_log_verbosity, 1); - set_comp_log(RRC, rrc_log_level, rrc_log_verbosity, 1); + } else { + printf("configuring for eNB\n"); + + set_comp_log(HW, hw_log_level, hw_log_verbosity, 1); + set_comp_log(PHY, phy_log_level, phy_log_verbosity, 1); + if (opt_enabled == 1 ) + set_comp_log(OPT, opt_log_level, opt_log_verbosity, 1); + set_comp_log(MAC, mac_log_level, mac_log_verbosity, 1); + set_comp_log(RLC, rlc_log_level, rlc_log_verbosity, 1); + set_comp_log(PDCP, pdcp_log_level, pdcp_log_verbosity, 1); + set_comp_log(RRC, rrc_log_level, rrc_log_verbosity, 1); #if defined(ENABLE_ITTI) - set_comp_log(EMU, LOG_INFO, LOG_MED, 1); + set_comp_log(EMU, LOG_INFO, LOG_MED, 1); # if defined(ENABLE_USE_MME) - set_comp_log(UDP_, udp_log_level, udp_log_verbosity, 1); - set_comp_log(GTPU, gtpu_log_level, gtpu_log_verbosity, 1); - set_comp_log(S1AP, LOG_DEBUG, LOG_HIGH, 1); - set_comp_log(SCTP, LOG_INFO, LOG_HIGH, 1); + set_comp_log(UDP_, udp_log_level, udp_log_verbosity, 1); + set_comp_log(GTPU, gtpu_log_level, gtpu_log_verbosity, 1); + set_comp_log(S1AP, LOG_DEBUG, LOG_HIGH, 1); + set_comp_log(SCTP, LOG_INFO, LOG_HIGH, 1); # endif #if defined(ENABLE_SECURITY) - set_comp_log(OSA, osa_log_level, osa_log_verbosity, 1); + set_comp_log(OSA, osa_log_level, osa_log_verbosity, 1); #endif #endif #ifdef LOCALIZATION - set_comp_log(LOCALIZE, LOG_DEBUG, LOG_LOW, 1); - set_component_filelog(LOCALIZE); + set_comp_log(LOCALIZE, LOG_DEBUG, LOG_LOW, 1); + set_component_filelog(LOCALIZE); #endif - set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1); - set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); + set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1); + set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); - if (online_log_messages == 1) { - set_component_filelog(RRC); - set_component_filelog(PDCP); + if (online_log_messages == 1) { + set_component_filelog(RRC); + set_component_filelog(PDCP); + } } - } - if (ouput_vcd) { - if (UE_flag==1) - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); - else - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd"); - } + if (ouput_vcd) { + if (UE_flag==1) + VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); + else + VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd"); + } - if (opp_enabled ==1){ - reset_opp_meas(); - } - cpuf=get_cpu_freq_GHz(); + if (opp_enabled ==1) { + reset_opp_meas(); + } + cpuf=get_cpu_freq_GHz(); #if defined(ENABLE_ITTI) - if (UE_flag == 1) { - log_set_instance_type (LOG_INSTANCE_UE); - } else { - log_set_instance_type (LOG_INSTANCE_ENB); - } + if (UE_flag == 1) { + log_set_instance_type (LOG_INSTANCE_UE); + } else { + log_set_instance_type (LOG_INSTANCE_ENB); + } - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); - - // initialize mscgen log after ITTI - MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); + + // initialize mscgen log after ITTI + MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); #endif - - if (opt_type != OPT_NONE) { - radio_type_t radio_type; - if (frame_parms[0]->frame_type == FDD) - radio_type = RADIO_TYPE_FDD; - else - radio_type = RADIO_TYPE_TDD; + if (opt_type != OPT_NONE) { + radio_type_t radio_type; - if (init_opt(in_path, in_ip, NULL, radio_type) == -1) - LOG_E(OPT,"failed to run OPT \n"); - } + if (frame_parms[0]->frame_type == FDD) + radio_type = RADIO_TYPE_FDD; + else + radio_type = RADIO_TYPE_TDD; + + if (init_opt(in_path, in_ip, NULL, radio_type) == -1) + LOG_E(OPT,"failed to run OPT \n"); + } #ifdef PDCP_USE_NETLINK - netlink_init(); + netlink_init(); #if defined(PDCP_USE_NETLINK_QUEUES) - pdcp_netlink_init(); + pdcp_netlink_init(); #endif #endif #if !defined(ENABLE_ITTI) - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); + // to make a graceful exit when ctrl-c is pressed + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); #endif - check_clock(); + check_clock(); // init the parameters for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { @@ -1579,453 +1523,444 @@ int main( int argc, char **argv ) } - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - //init prach for openair1 test - - // prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type); - // N_ZC = (prach_fmt <4)?839:139; - } - - if (UE_flag==1) { - NB_UE_INST=1; - NB_INST=1; - - PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)); - PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + //init prach for openair1 test - PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag); - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]); - - if (phy_test==1) - UE[CC_id]->mac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; - - if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode - for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { - UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; - UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); - UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - UE[CC_id]->UE_scan = UE_scan; - UE[CC_id]->UE_scan_carrier = UE_scan_carrier; - UE[CC_id]->mode = mode; - printf("UE[%d]->mode = %d\n",CC_id,mode); - - compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common, - UE[CC_id]->frame_parms.frame_type, - UE[CC_id]->X_u); - - if (UE[CC_id]->mac_enabled == 1) - UE[CC_id]->pdcch_vars[0]->crnti = 0x1234; - else - UE[CC_id]->pdcch_vars[0]->crnti = 0x1235; - - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; - UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - - if (frame_parms[CC_id]->frame_type==FDD) { - UE[CC_id]->N_TA_offset = 0; - } - else { - if (frame_parms[CC_id]->N_RB_DL == 100) - UE[CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - UE[CC_id]->N_TA_offset = 624/4; - } - + // prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type); + // N_ZC = (prach_fmt <4)?839:139; } - // printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power)); - } else { - //this is eNB - PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB**)); - PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*)); + if (UE_flag==1) { + NB_UE_INST=1; + NB_INST=1; + + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)); + PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag); + UE[CC_id] = PHY_vars_UE_g[0][CC_id]; + printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]); + + if (phy_test==1) + UE[CC_id]->mac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + + if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode + for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { + UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; + UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); + UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + } + } + + UE[CC_id]->UE_scan = UE_scan; + UE[CC_id]->UE_scan_carrier = UE_scan_carrier; + UE[CC_id]->mode = mode; + printf("UE[%d]->mode = %d\n",CC_id,mode); + + compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common, + UE[CC_id]->frame_parms.frame_type, + UE[CC_id]->X_u); + + if (UE[CC_id]->mac_enabled == 1) + UE[CC_id]->pdcch_vars[0]->crnti = 0x1234; + else + UE[CC_id]->pdcch_vars[0]->crnti = 0x1235; + + UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; + + if (frame_parms[CC_id]->frame_type==FDD) { + UE[CC_id]->N_TA_offset = 0; + } else { + if (frame_parms[CC_id]->N_RB_DL == 100) + UE[CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + UE[CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + UE[CC_id]->N_TA_offset = 624/4; + } - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,node_function[CC_id],abstraction_flag); - PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff; - PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs; - PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6; - PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs; - // initialization for phy-test - for (k=0;k<NUMBER_OF_UE_MAX;k++) { - PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode; - if (transmission_mode==7) - lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k],frame_parms[CC_id]->Nid_cell,0x1235+k); - } - if ((transmission_mode==1) || (transmission_mode==7)) { - for (j=0; j<frame_parms[CC_id]->nb_antennas_tx; j++) - for (re=0; re<frame_parms[CC_id]->ofdm_symbol_size; re++) - PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx; - } + } - if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0; - else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1; - - if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode - for (i=0; i<NUMBER_OF_UE_MAX; i++) { - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common, - PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, - PHY_vars_eNB_g[0][CC_id]->X_u); - - - PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0]; + // printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power)); + } else { + //this is eNB + PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB**)); + PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*)); + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,node_function[CC_id],abstraction_flag); + PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff; + PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs; + PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6; + PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs; + // initialization for phy-test + for (k=0; k<NUMBER_OF_UE_MAX; k++) { + PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode; + if (transmission_mode==7) + lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k],frame_parms[CC_id]->Nid_cell,0x1235+k); + } + if ((transmission_mode==1) || (transmission_mode==7)) { + for (j=0; j<frame_parms[CC_id]->nb_antennas_tx; j++) + for (re=0; re<frame_parms[CC_id]->ofdm_symbol_size; re++) + PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx; + } + + if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0; + else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1; + + if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode + for (i=0; i<NUMBER_OF_UE_MAX; i++) { + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + } + } + + compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common, + PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, + PHY_vars_eNB_g[0][CC_id]->X_u); + + + PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0]; + + if (frame_parms[CC_id]->frame_type==FDD) { + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; + } else { + if (frame_parms[CC_id]->N_RB_DL == 100) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; + } - if (frame_parms[CC_id]->frame_type==FDD) { - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; - } - else { - if (frame_parms[CC_id]->N_RB_DL == 100) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; - } + } - } - - NB_eNB_INST=1; - NB_INST=1; + NB_eNB_INST=1; + NB_INST=1; - } + } - fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); - cpuf=get_cpu_freq_GHz(); + fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); + cpuf=get_cpu_freq_GHz(); - dump_frame_parms(frame_parms[0]); + dump_frame_parms(frame_parms[0]); - init_openair0(); + init_openair0(); #ifndef DEADLINE_SCHEDULER - /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ - - cpu_set_t cpuset; - int s; - char cpu_affinity[1024]; - CPU_ZERO(&cpuset); + /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ + + cpu_set_t cpuset; + int s; + char cpu_affinity[1024]; + CPU_ZERO(&cpuset); #ifdef CPU_AFFINITY - if (get_nprocs() > 2) - { - CPU_SET(0, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); + if (get_nprocs() > 2) { + CPU_SET(0, &cpuset); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } + LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); } #endif - /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); + /* Check the actual affinity mask assigned to the thread */ + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (int j = 0; j < CPU_SETSIZE; j++) - { - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (int j = 0; j < CPU_SETSIZE; j++) { + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); + } } - LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); + LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); #endif - - openair0_cfg[0].log_level = glog_level; - + openair0_cfg[0].log_level = glog_level; - int eMBMS_active=0; - if (node_function[0] <= NGFI_RAU_IF4p5) { // don't initialize L2 for RRU - LOG_I(PHY,"Intializing L2\n"); - mac_xface = malloc(sizeof(MAC_xface)); - l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, - 0,// cba_group_active - 0); // HO flag - mac_xface->macphy_exit = &exit_fun; - } - else if (node_function[0] == NGFI_RRU_IF4p5) { // Initialize PRACH in this case - } + + int eMBMS_active=0; + if (node_function[0] <= NGFI_RAU_IF4p5) { // don't initialize L2 for RRU + LOG_I(PHY,"Intializing L2\n"); + mac_xface = malloc(sizeof(MAC_xface)); + l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, + 0,// cba_group_active + 0); // HO flag + mac_xface->macphy_exit = &exit_fun; + } else if (node_function[0] == NGFI_RRU_IF4p5) { // Initialize PRACH in this case + + } #if defined(ENABLE_ITTI) - if ((UE_flag == 1)|| - (node_function[0]<NGFI_RAU_IF4p5)) - // don't create if node doesn't connect to RRC/S1/GTP - if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } + if ((UE_flag == 1)|| + (node_function[0]<NGFI_RAU_IF4p5)) + // don't create if node doesn't connect to RRC/S1/GTP + if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } - printf("ITTI tasks created\n"); + printf("ITTI tasks created\n"); #endif - if (phy_test==0) { - if (UE_flag==1) { - printf("Filling UE band info\n"); - fill_ue_band_info(); - mac_xface->dl_phy_sync_success (0, 0, 0, 1); - } else if (node_function[0]>NGFI_RRU_IF4p5) - mac_xface->mrbch_phy_sync_failure (0, 0, 0); - } + if (phy_test==0) { + if (UE_flag==1) { + printf("Filling UE band info\n"); + fill_ue_band_info(); + mac_xface->dl_phy_sync_success (0, 0, 0, 1); + } else if (node_function[0]>NGFI_RRU_IF4p5) + mac_xface->mrbch_phy_sync_failure (0, 0, 0); + } - mlockall(MCL_CURRENT | MCL_FUTURE); + mlockall(MCL_CURRENT | MCL_FUTURE); - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); #ifdef XFORMS - int UE_id; - - if (do_forms==1) { - fl_initialize (&argc, argv, NULL, 0, 0); - - if (UE_flag==0) { - form_stats_l2 = create_form_stats_form(); - fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - - for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - form_enb[CC_id][UE_id] = create_lte_phy_scope_enb(); - sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id); - fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - if (otg_enabled) { - fl_set_button(form_enb[CC_id][UE_id]->button_0,1); - fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON"); - } else { - fl_set_button(form_enb[CC_id][UE_id]->button_0,0); - fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF"); - } - } // CC_id - } // UE_id - } else { - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - UE_id = 0; - form_ue[UE_id] = create_lte_phy_scope_ue(); - sprintf (title, "LTE DL SCOPE UE"); - fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - /* - if (openair_daq_vars.use_ia_receiver) { - fl_set_button(form_ue[UE_id]->button_0,1); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); - } else { - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - }*/ - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - } + int UE_id; + + if (do_forms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + + if (UE_flag==0) { + form_stats_l2 = create_form_stats_form(); + fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); + form_stats = create_form_stats_form(); + fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); + + for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + form_enb[CC_id][UE_id] = create_lte_phy_scope_enb(); + sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id); + fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + if (otg_enabled) { + fl_set_button(form_enb[CC_id][UE_id]->button_0,1); + fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON"); + } else { + fl_set_button(form_enb[CC_id][UE_id]->button_0,0); + fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF"); + } + } // CC_id + } // UE_id + } else { + form_stats = create_form_stats_form(); + fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); + UE_id = 0; + form_ue[UE_id] = create_lte_phy_scope_ue(); + sprintf (title, "LTE DL SCOPE UE"); + fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + /* + if (openair_daq_vars.use_ia_receiver) { + fl_set_button(form_ue[UE_id]->button_0,1); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); + } else { + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + }*/ + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + } - ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); + ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); - if (ret == 0) - pthread_setname_np( forms_thread, "xforms" ); + if (ret == 0) + pthread_setname_np( forms_thread, "xforms" ); - printf("Scope thread created, ret=%d\n",ret); - } + printf("Scope thread created, ret=%d\n",ret); + } #endif - rt_sleep_ns(10*100000000ULL); + rt_sleep_ns(10*100000000ULL); - // start the main thread - if (UE_flag == 1) { - init_UE(1); - number_of_cards = 1; - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_UE_g[0][CC_id]->rf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; - } - } - else { - printf("Initializing eNB threads\n"); - init_eNB(node_function,node_timing,1,eth_params,single_thread_flag,wait_for_sync); + // start the main thread + if (UE_flag == 1) { + init_UE(1); + number_of_cards = 1; - number_of_cards = 1; - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_eNB_g[0][CC_id]->rf_map.card=0; - PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_UE_g[0][CC_id]->rf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } + } else { + printf("Initializing eNB threads\n"); + init_eNB(node_function,node_timing,1,eth_params,single_thread_flag,wait_for_sync); + + number_of_cards = 1; + + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_eNB_g[0][CC_id]->rf_map.card=0; + PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } } - } - // connect the TX/RX buffers - if (UE_flag==1) { + // connect the TX/RX buffers + if (UE_flag==1) { + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - for (CC_id=0;CC_id<MAX_NUM_CCs; CC_id++) { - #ifdef OAI_USRP - UE[CC_id]->hw_timing_advance = timing_advance; + UE[CC_id]->hw_timing_advance = timing_advance; #else - UE[CC_id]->hw_timing_advance = 160; + UE[CC_id]->hw_timing_advance = 160; #endif - } - if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { - printf("Error setting up eNB buffer\n"); - exit(-1); - } + } + if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { + printf("Error setting up eNB buffer\n"); + exit(-1); + } - if (input_fd) { - printf("Reading in from file to antenna buffer %d\n",0); - if (fread(UE[0]->common_vars.rxdata[0], - sizeof(int32_t), - frame_parms[0]->samples_per_tti*10, - input_fd) != frame_parms[0]->samples_per_tti*10) - printf("error reading from file\n"); - } - //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; - } else { + if (input_fd) { + printf("Reading in from file to antenna buffer %d\n",0); + if (fread(UE[0]->common_vars.rxdata[0], + sizeof(int32_t), + frame_parms[0]->samples_per_tti*10, + input_fd) != frame_parms[0]->samples_per_tti*10) + printf("error reading from file\n"); + } + //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; + } else { - printf("Setting eNB buffer to all-RX\n"); + printf("Setting eNB buffer to all-RX\n"); - // Set LSBs for antenna switch (ExpressMIMO) - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0; - for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++) - for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++) - PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001; + // Set LSBs for antenna switch (ExpressMIMO) + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0; + for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++) + for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++) + PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001; + } } - } - sleep(3); + sleep(3); - printf("Sending sync to all threads\n"); + printf("Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); - // wait for end of program - printf("TYPE <CTRL-C> TO TERMINATE\n"); - //getchar(); + // wait for end of program + printf("TYPE <CTRL-C> TO TERMINATE\n"); + //getchar(); #if defined(ENABLE_ITTI) - printf("Entering ITTI signals handler\n"); - itti_wait_tasks_end(); - oai_exit=1; + printf("Entering ITTI signals handler\n"); + itti_wait_tasks_end(); + oai_exit=1; #else - while (oai_exit==0) - rt_sleep_ns(100000000ULL); + while (oai_exit==0) + rt_sleep_ns(100000000ULL); #endif - // stop threads + // stop threads #ifdef XFORMS - printf("waiting for XFORMS thread\n"); + printf("waiting for XFORMS thread\n"); - if (do_forms==1) { - pthread_join(forms_thread,&status); - fl_hide_form(form_stats->stats_form); - fl_free_form(form_stats->stats_form); + if (do_forms==1) { + pthread_join(forms_thread,&status); + fl_hide_form(form_stats->stats_form); + fl_free_form(form_stats->stats_form); - if (UE_flag==1) { - fl_hide_form(form_ue[0]->lte_phy_scope_ue); - fl_free_form(form_ue[0]->lte_phy_scope_ue); - } else { - fl_hide_form(form_stats_l2->stats_form); - fl_free_form(form_stats_l2->stats_form); - - for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); - fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); - } - } + if (UE_flag==1) { + fl_hide_form(form_ue[0]->lte_phy_scope_ue); + fl_free_form(form_ue[0]->lte_phy_scope_ue); + } else { + fl_hide_form(form_stats_l2->stats_form); + fl_free_form(form_stats_l2->stats_form); + + for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); + fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); + } + } + } } - } #endif - printf("stopping MODEM threads\n"); + printf("stopping MODEM threads\n"); - // cleanup - if (UE_flag == 1) { - } else { - stop_eNB(1); - } + // cleanup + if (UE_flag == 1) { + } else { + stop_eNB(1); + } - pthread_cond_destroy(&sync_cond); - pthread_mutex_destroy(&sync_mutex); + pthread_cond_destroy(&sync_cond); + pthread_mutex_destroy(&sync_mutex); - // *** Handle per CC_id openair0 - if (UE_flag==1) { - if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) - PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); - } - else { - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func) - PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); - if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func) - PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + // *** Handle per CC_id openair0 + if (UE_flag==1) { + if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); + } else { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func) + PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); + if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func) + PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + } } - } - if (ouput_vcd) - VCD_SIGNAL_DUMPER_CLOSE(); + if (ouput_vcd) + VCD_SIGNAL_DUMPER_CLOSE(); - if (opt_enabled == 1) - terminate_opt(); + if (opt_enabled == 1) + terminate_opt(); - logClean(); + logClean(); - return 0; + return 0; } diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h new file mode 100644 index 0000000000000000000000000000000000000000..e499bd12be3ac22e8e37e584801001a06dd0939c --- /dev/null +++ b/targets/RT/USER/lte-softmodem.h @@ -0,0 +1,95 @@ +#ifndef LTE_SOFTMODEM_H +#define LTE_SOFTMODEM_H + +#define _GNU_SOURCE +#include <execinfo.h> +#include <fcntl.h> +#include <getopt.h> +#include <linux/sched.h> +#include "rt_wrapper.h" +#include <sched.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syscall.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/sysinfo.h> +#include <sys/types.h> +#include <unistd.h> + +#include <sys/sysinfo.h> +#include "rt_wrapper.h" +#include "../../ARCH/COMMON/common_lib.h" +#undef MALLOC +#include "assertions.h" +#include "msc.h" +#include "PHY/types.h" +#include "PHY/defs.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" + +#if defined(ENABLE_ITTI) +#if defined(ENABLE_USE_MME) +#include "s1ap_eNB.h" +#ifdef PDCP_USE_NETLINK +#include "SIMULATION/ETH_TRANSPORT/proto.h" +#endif +#endif +#endif + +extern pthread_cond_t sync_cond; +extern pthread_mutex_t sync_mutex; +extern int sync_var; + + +extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +extern int rx_input_level_dBm; +extern uint8_t exit_missed_slots; +extern uint64_t num_missed_slots; // counter for the number of missed slots + +extern int oaisim_flag; +extern volatile int oai_exit; + +extern openair0_config_t openair0_cfg[MAX_CARDS]; +extern pthread_cond_t sync_cond; +extern pthread_mutex_t sync_mutex; +extern int sync_var; +extern int transmission_mode; +extern double cpuf; + +#if defined(ENABLE_ITTI) +extern volatile int start_eNB; +extern volatile int start_UE; +#endif + +typedef struct threads_s { + int iq; + int odd; + int even; +} threads_t; +extern threads_t threads; + +extern void exit_fun(const char* s); +// In lte-enb.c +extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg); +extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int,int); +extern void stop_eNB(int); +extern void kill_eNB_proc(int inst); + +// In lte-ue.c +extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg); +extern void fill_ue_band_info(void); +extern void init_UE(int); +extern void reset_opp_meas(void); +extern void print_opp_meas(void); + +extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); +extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); +extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); + +#endif diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 3745c61a9e95ae137eac2cd75d7502064ca40eb0..e6eea65375dce7a2c7d0bcca537bba731b8d0fc8 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -29,29 +29,10 @@ * \note * \warning */ -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sched.h> -#include <linux/sched.h> -#include <signal.h> -#include <execinfo.h> -#include <getopt.h> -#include <syscall.h> -#include <sys/sysinfo.h> +#include "lte-softmodem.h" #include "rt_wrapper.h" -#include "assertions.h" -#include "PHY/types.h" -#include "PHY/defs.h" #ifdef OPENAIR2 #include "LAYER2/MAC/defs.h" #include "RRC/LITE/extern.h" @@ -61,8 +42,6 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "../../ARCH/COMMON/common_lib.h" - #include "PHY/extern.h" #include "SCHED/extern.h" #include "LAYER2/MAC/extern.h" @@ -79,811 +58,523 @@ #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL +#define FIFO_PRIORITY 40 typedef enum { - pss=0, - pbch=1, - si=2 + pss=0, + pbch=1, + si=2 } sync_mode_t; -void init_UE_threads(int nb_inst); +void init_UE_threads(PHY_VARS_UE *UE); void *UE_thread(void *arg); void init_UE(int nb_inst); -extern pthread_cond_t sync_cond; -extern pthread_mutex_t sync_mutex; -extern int sync_var; - - -extern openair0_config_t openair0_cfg[MAX_CARDS]; -extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; -extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -extern int oai_exit; - int32_t **rxdata; int32_t **txdata; -//extern unsigned int tx_forward_nsamps; -//extern int tx_delay; - -extern int rx_input_level_dBm; -extern uint8_t exit_missed_slots; -extern uint64_t num_missed_slots; // counter for the number of missed slots - -extern int oaisim_flag; - -extern void exit_fun(const char* s); - #define KHz (1000UL) -#define MHz (1000 * KHz) +#define MHz (1000*KHz) typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; } eutra_band_t; typedef struct band_info_s { - int nbands; - eutra_band_t band_info[100]; + int nbands; + eutra_band_t band_info[100]; } band_info_t; band_info_t bands_to_scan; static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, }; pthread_t main_ue_thread; pthread_attr_t attr_UE_thread; struct sched_param sched_param_UE_thread; -void init_UE(int nb_inst) { +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { - int error_code; - int inst; - PHY_VARS_UE *UE; - int ret; - - for (inst=0;inst<nb_inst;inst++) { - printf("Intializing UE Threads for instance %d ...\n",inst); - init_UE_threads(inst); - sleep(1); - UE = PHY_vars_UE_g[inst][0]; - - if (oaisim_flag == 0) { - ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]); - if (ret !=0){ - exit_fun("Error loading device library"); - } - } - UE->rfdevice.host_type = BBU_HOST; - // UE->rfdevice.type = NONE_DEV; - error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, UE); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return; - } else { - char name[128]; - sprintf(name, "main UE %d", inst); - LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np(UE->proc.pthread_ue, name); +#ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { + struct sched_attr attr= {0}; + attr.size = sizeof(attr); + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = sched_runtime; + attr.sched_deadline = sched_deadline; + attr.sched_period = 0; + AssertFatal(sched_setattr(0, &attr, 0) == 0, + "[SCHED] %s thread: sched_setattr failed %s \n", name, perror(errno)); + LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", + name, (unsigned long)gettid(), sched_getcpu()); } - } - - printf("UE threads created\n"); -#if 0 -#if defined(ENABLE_USE_MME) - extern volatile int start_UE; - while (start_UE == 0) { - sleep(1); - } -#endif -#endif -} -/*! - * \brief This is the UE synchronize thread. - * It performs band scanning and synchonization. - * \param arg is a pointer to a \ref PHY_VARS_UE structure. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -static void *UE_thread_synch(void *arg) -{ - static int UE_thread_synch_retval; - int i, hw_slot_offset; - PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; - int current_band = 0; - int current_offset = 0; - sync_mode_t sync_mode = pbch; - int CC_id = UE->CC_id; - int ind; - int found; - int freq_offset=0; - - UE->is_synchronized = 0; - printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - printf("waiting for sync (UE_thread_synch) \n"); - -#ifndef DEADLINE_SCHEDULER - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - CPU_ZERO(&cpuset); - - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); +#else + if (CPU_COUNT(cpuset) > 0) + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; + sp.sched_priority = sched_fifo; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); + /* Check the actual affinity mask assigned to the thread */ + cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); + if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { + char txt[512]={0}; + for (int j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, cset)) + sprintf(txt+strlen(txt), " %d ", j); + printf("CPU Affinity of thread %s is %s\n", name, txt); } - } - #endif - - /* Check the actual affinity mask assigned to the thread */ - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - + CPU_FREE(cset); #endif + // Lock memory from swapping. This is a process wide call (not constraint to this thread). + mlockall(MCL_CURRENT | MCL_FUTURE); + pthread_setname_np( pthread_self(), name ); + + // LTS: this sync stuff should be wrong + printf("waiting for sync (%s)\n",name); + pthread_mutex_lock(&sync_mutex); + printf("Locked sync_mutex, waiting (%s)\n",name); + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + pthread_mutex_unlock(&sync_mutex); + printf("started %s as PID: %ld\n",name, gettid()); +} +void init_UE(int nb_inst) { - - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); - ind = 0; - found = 0; - - - if (UE->UE_scan == 0) { - do { - current_band = eutra_bands[ind].band; - printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); - - if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { - for (i=0; i<4; i++) - uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; - - found = 1; - break; - } - - ind++; - } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - - if (found == 0) { - exit_fun("Can't find EUTRA band for frequency"); - return &UE_thread_synch_retval; - } - - - - - - - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); - - for (i=0;i<openair0_cfg[UE->rf_map.card].rx_num_channels;i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - if (uplink_frequency_offset[CC_id][i] != 0) // - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; - else //FDD - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + for (long long inst=0; inst<nb_inst; inst++) { + // UE->rfdevice.type = NONE_DEV; + PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0]; + AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, + &UE->proc.attr_ue, + UE_thread, + (void*)UE), ""); } - sync_mode = pbch; - - } else if (UE->UE_scan == 1) { - current_band=0; - - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + printf("UE threads created by %ld\n", gettid()); +#ifdef USE_MME + while (start_UE == 0) { + sleep(1); } - } - - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); +#endif - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } +} - while (oai_exit==0) { +/*! + * \brief This is the UE synchronize thread. + * It performs band scanning and synchonization. + * \param arg is a pointer to a \ref PHY_VARS_UE structure. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ +static void *UE_thread_synch(void *arg) { + static int __thread UE_thread_synch_retval; + int i, hw_slot_offset; + PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; + int current_band = 0; + int current_offset = 0; + sync_mode_t sync_mode = pbch; + int CC_id = UE->CC_id; + int freq_offset=0; + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + if ( threads.iq != -1 ) + CPU_SET(threads.iq, &cpuset); + // this thread priority must be lower that the main acquisition thread + init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, + "sync UE"); + + UE->is_synchronized = 0; + + if (UE->UE_scan == 0) { + int ind; + for ( ind=0; + ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); + ind++) { + current_band = eutra_bands[ind].band; + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); + if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { + for (i=0; i<4; i++) + uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; + break; + } + } + AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); + + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", + downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0], + oai_exit, openair0_cfg[0].rx_num_channels); + + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + if (uplink_frequency_offset[CC_id][i] != 0) // + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; + else //FDD + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + } + sync_mode = pbch; - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; + } else { + current_band=0; + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = + bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + } } - - while (UE->proc.instance_cnt_synch < 0) { - // the thread waits here most of the time - pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); - } + AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_synch_retval; - } + while (oai_exit==0) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + while (UE->proc.instance_cnt_synch < 0) + // the thread waits here most of the time + pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); + switch (sync_mode) { + case pss: + LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + current_offset += 20000000; // increase by 20 MHz - switch (sync_mode) { - case pss: - LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - current_offset += 20000000; // increase by 20 MHz + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { + current_band++; + current_offset=0; + } - if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { - current_band++; - current_offset=0; - } + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } - if (current_band==bands_to_scan.nbands) { - current_band=0; - oai_exit=1; - } - - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - if (UE->UE_scan_carrier) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - - } - - break; - - case pbch: - - LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (initial_sync( UE, UE->mode ) == 0) { - - hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; - LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", - hw_slot_offset, - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, - UE->UE_scan_carrier ); - - if (UE->UE_scan_carrier == 1) { - - UE->UE_scan_carrier = 0; - // rerun with new cell parameters and frequency-offset - for (i=0;i<openair0_cfg[UE->rf_map.card].rx_num_channels;i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (freq_offset >= 0) - { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); - } - else - { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); - } - LOG_I(PHY," new cell parameters and frequency-offset %f freq_offset %d UE->common_vars.freq_offset %d \n", openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i], freq_offset, UE->common_vars.freq_offset); - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; - downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; - freq_offset=0; - } - - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); - UE->rfdevice.trx_stop_func(&UE->rfdevice); - sleep(1); - init_frame_parms(&UE->frame_parms,1); - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - } - else { - UE->is_synchronized = 1; - - if( UE->mode == rx_dump_frame ){ - FILE *fd; - if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present - if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - else { - LOG_E(PHY,"Cannot open file for writing\n"); - exit(0); - } - } - else { - UE->is_synchronized = 0; - } - } - } - } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) { - freq_offset += 100; - freq_offset *= -1; - } else { - freq_offset *= -1; - } - - if (abs(freq_offset) > 7500) { - LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); - FILE *fd; - if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - mac_xface->macphy_exit("No cell synchronization found, abandoning"); - return &UE_thread_synch_retval; // not reached - } - } - else { - - } - LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); - - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - if (UE->UE_scan_carrier==1) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - - }// initial_sync=0 - - break; - - case si: - default: - break; - } + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + } - // indicate readiness - UE->proc.instance_cnt_synch--; + break; + + case pbch: + + LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + if (initial_sync( UE, UE->mode ) == 0) { + + hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; + LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + hw_slot_offset, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); + + if (UE->UE_scan_carrier == 1) { + UE->UE_scan_carrier = 0; + // rerun with new cell parameters and frequency-offset + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + if (freq_offset >= 0) + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += UE->common_vars.freq_offset; + else + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + freq_offset=0; + } + + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + UE->rfdevice.trx_stop_func(&UE->rfdevice); + sleep(1); + init_frame_parms(&UE->frame_parms,1); + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + } + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 1; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + if( UE->mode == rx_dump_frame ) { + FILE *fd; + if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } else { + LOG_E(PHY,"Cannot open file for writing\n"); + exit(0); + } + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 0; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + } + } + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + freq_offset += 100; + freq_offset *= -1; + + if (abs(freq_offset) > 7500) { + LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); + FILE *fd; + if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } + mac_xface->macphy_exit("No cell synchronization found, abandoning"); + return &UE_thread_synch_retval; // not reached + } + } + LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + if (UE->UE_scan_carrier==1) + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + }// initial_sync=0 + break; + case si: + default: + break; + } - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + // indicate readiness + UE->proc.instance_cnt_synch--; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); - } // while !oai_exit + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); + } // while !oai_exit - return &UE_thread_synch_retval; + return &UE_thread_synch_retval; } -/* this structure is used to pass both UE phy vars and - * proc to the function UE_thread_rxn_txnp4 - */ -struct rx_tx_thread_data { - PHY_VARS_UE *UE; - UE_rxtx_proc_t *proc; -}; - /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. * This thread performs the phy_procedures_UE_RX() on every received slot. - * then, if TX is enabled it performs TX for n+4. + * then, if TX is enabled it performs TX for n+4. * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *UE_thread_rxn_txnp4(void *arg) -{ - static int UE_thread_rxtx_retval; - struct rx_tx_thread_data *rtd = arg; - UE_rxtx_proc_t *proc = rtd->proc; - PHY_VARS_UE *UE = rtd->UE; - int ret; - proc->instance_cnt_rxtx=-1; - - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - // This creates a .5ms reservation every 1ms period - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 900000; // each rx thread requires 1ms to finish its job - attr.sched_deadline = 1000000; // each rx thread will finish within 1ms - attr.sched_period = 1000000; // each rx thread has a period of 1ms from the starting point - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] UE_thread_rxtx : sched_setattr failed\n"); - return &UE_thread_rxtx_retval; - } - -#else - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - CPU_ZERO(&cpuset); - - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } - #endif - - /* Check the actual affinity mask assigned to the thread */ - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE RX thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - - -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread_rxn_txnp4)\n"); - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread_rxn_txnp4)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - -#define THREAD_NAME_LEN 16 - char threadname[THREAD_NAME_LEN]; - ret = pthread_getname_np(proc->pthread_rxtx, threadname, THREAD_NAME_LEN); - if (ret != 0) - { - perror("pthread_getname_np : "); - exit_fun("Error getting thread name"); - } - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread_rxtx)\n"); - - printf("Starting UE RXN_TXNP4 thread (%s)\n", threadname); - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->proc_id), 1 ); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("nothing to add"); - return &UE_thread_rxtx_retval; - } - - while (proc->instance_cnt_rxtx < 0) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->proc_id), 1 ); - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->proc_id), 0 ); - - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - return &UE_thread_rxtx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->proc_id), 0 ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->proc_id), 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_UE+(proc->proc_id), proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_UE+(proc->proc_id), proc->subframe_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE+(proc->proc_id), proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE+(proc->proc_id), proc->frame_tx ); - - lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { - - if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", - threadname, - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } else { - LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", - threadname, - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } - phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); - } - - if (UE->mac_enabled==1) { - - ret = mac_xface->ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); - - if (ret == CONNECTION_LOST) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, returning to PRACH\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = PRACH; - } else if (ret == PHY_RESYNCH) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, trying to resynch\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = RESYNCH; - } else if (ret == PHY_HO_PRACH) { - LOG_I( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u, return to PRACH and perform a contention-free access\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = PRACH; - } - } +static void *UE_thread_rxn_txnp4(void *arg) { + static __thread int UE_thread_rxtx_retval; + UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + int ret; + PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; + + static long long __thread instance_cnt_rxtx=-1; + proc->subframe_rx=proc->sub_frame_start; + + char threadname[256]= {0}; + sprintf(threadname,"UE_proc_%d",proc->sub_frame_start); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 ) + CPU_SET(threads.even, &cpuset); + if ( (proc->sub_frame_start+1)%2 == 1 && threads.odd != -1 ) + CPU_SET(threads.odd, &cpuset); + init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, + threadname); + + while (!oai_exit) { + // Wait Rx data to process are available + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) + LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %lld, got %d\n", + (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); + instance_cnt_rxtx=proc->subframe_rx; + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + + initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); + + // Process Rx data for one sub-frame + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadname, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadname, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); + } + if (UE->mac_enabled==1) { + + ret = mac_xface->ue_scheduler(UE->Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { + char *txt; + switch (ret) { + case CONNECTION_LOST: + txt="RRC Connection lost, returning to PRACH"; + break; + case PHY_RESYNCH: + txt="RRC Connection lost, trying to resynch"; + break; + case RESYNCH: + txt="return to PRACH and perform a contention-free access"; + break; + default: + txt="UNKNOWN RETURN CODE"; + }; + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); + } + } + // Prepare the future Tx data - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) { + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) + phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); - if (UE->mode != loop_through_memory) { - phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); - } - } - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && - (UE->frame_parms.frame_type == TDD)) { + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && + (UE->frame_parms.frame_type == TDD)) + if (UE->mode != loop_through_memory) + phy_procedures_UE_S_TX(UE,0,0,no_relay); + updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); - if (UE->mode != loop_through_memory) { - phy_procedures_UE_S_TX(UE,0,0,no_relay); - } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->proc_id), 0 ); - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->proc_id), 1 ); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - return &UE_thread_rxtx_retval; - } - - proc->instance_cnt_rxtx--; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx); - - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - return &UE_thread_rxtx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->proc_id), 0 ); - } - - // thread finished - free(arg); - return &UE_thread_rxtx_retval; +// thread finished + return &UE_thread_rxtx_retval; } - - - - -#define RX_OFF_MAX 23 -#define RX_OFF_MIN 0 -#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) - /*! * \brief This is the main UE thread. * This thread controls the other three UE threads: @@ -896,805 +587,205 @@ static void *UE_thread_rxn_txnp4(void *arg) void *UE_thread(void *arg) { - static int UE_thread_retval; - PHY_VARS_UE *UE = arg; //PHY_vars_UE_g[0][0]; - // int tx_enabled = 0; - uint32_t rxs=0,txs=0; - int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); - openair0_timestamp timestamp,timestamp1; - void* rxp[2], *txp[2]; - -#ifdef NAS_UE - MessageDef *message_p; -#endif - - int start_rx_stream = 0; - int rx_off_diff = 0; - int rx_correction_timer = 0; - int i; - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); - - // This creates a .5 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 100000; - attr.sched_deadline = 500000; - attr.sched_period = 500000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] main eNB thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - return &UE_thread_retval; - } - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", - (unsigned long)gettid(), sched_getcpu()); - -#else - struct sched_param sp; - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); - -#ifdef NAS_UE - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); -#endif - - while (!oai_exit) { - - if (UE->is_synchronized == 0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] verror locking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_synch = UE->proc.instance_cnt_synch; - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - if (instance_cnt_synch < 0) { // we can invoke the synch - // grab 10 ms of signal and wakeup synch thread - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; - - if (UE->mode != loop_through_memory) { - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx); - - - if (rxs!=UE->frame_parms.samples_per_tti*10) { - LOG_E(PHY, "problem in rx 1! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti*10, rxs); - exit_fun("problem in rx 1"); - return &UE_thread_retval; - } - } - - instance_cnt_synch = ++UE->proc.instance_cnt_synch; - if (instance_cnt_synch == 0) { - if (pthread_cond_signal(&UE->proc.cond_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } // - else { - // grab 10 ms of signal into dummy buffer - - if (UE->mode != loop_through_memory) { - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0;sf<10;sf++) { - // printf("Reading dummy sf %d\n",sf); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - - if (rxs!=UE->frame_parms.samples_per_tti){ - LOG_E(PHY, "problem in rx 2! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); - exit_fun("problem in rx 2"); - return &UE_thread_retval; - } - - } - } - } - - } // UE->is_synchronized==0 - else { - if (start_rx_stream==0) { - start_rx_stream=1; - if (UE->mode != loop_through_memory) { - - if (UE->no_timing_correction==0) { - LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)UE->common_vars.rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); - if (rxs != UE->rx_offset) { - LOG_E(PHY, "problem in rx 3! expect #samples=%d but got only %d!\n", UE->rx_offset, rxs); - exit_fun("problem in rx 3!"); - return &UE_thread_retval; - } - } - LOG_D(PHY,"Set rx_offset to 0 \n"); - UE->rx_offset=0; - UE->proc.proc_rxtx[0].frame_rx++; - UE->proc.proc_rxtx[1].frame_rx++; - - // read in first symbol - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)UE->common_vars.rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); - if (rxs != (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0)) { - LOG_E(PHY, "problem in rx 4! expect #samples=%d but got only %d!\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, rxs); - exit_fun("problem in rx 4!"); - return &UE_thread_retval; - } - slot_fep(UE, - 0, - 0, - 0, - 0, - 0); - if (rxs != UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - } //UE->mode != loop_through_memory - else - rt_sleep_ns(1000000); - - }// start_rx_stream==0 - else { - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - - for (int sf=0;sf<10;sf++) { - for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti)]; - // grab signal for subframe - if (UE->mode != loop_through_memory) { - if (sf<9) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - LOG_D(PHY,"grab signal for subframe %d offset %d Nbsamples %d \n", sf, UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti), - UE->frame_parms.samples_per_tti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING, UE->frame_parms.samples_per_tti - rxs); - if (rxs != UE->frame_parms.samples_per_tti) { - LOG_E(PHY, "problem in rx 5! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); - exit_fun("problem in rx 5!"); - return &UE_thread_retval; - } - - // prepare tx buffer pointers - for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - txs = UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_tx, - 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, txs ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING, UE->frame_parms.samples_per_tti - txs); - if (txs != UE->frame_parms.samples_per_tti) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti); - exit_fun( "problem transmitting samples" ); - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING, UE->frame_parms.samples_per_tti - txs); - } - - else { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); - - LOG_D(PHY,"grab signal for subframe %d offset %d Nbsamples %d \n", sf, UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti), - UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING, (UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0) - rxs); - if (rxs != (UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0)) { - LOG_E(PHY, "problem in rx 6! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, rxs); - exit_fun("problem in rx 6!"); - return &UE_thread_retval; - } - - // prepare tx buffer pointers - for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 1 ); - txs = UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - UE->frame_parms.samples_per_tti - rx_off_diff, - UE->frame_parms.nb_antennas_tx, - 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, txs ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING, (UE->frame_parms.samples_per_tti - rx_off_diff) - txs); - if (txs != UE->frame_parms.samples_per_tti - rx_off_diff) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti-rx_off_diff); - exit_fun( "problem transmitting samples" ); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); - // read in first symbol of next frame and adjust for timing drift - for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) - { - rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; - } - - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp1, - rxp, - UE->frame_parms.nb_prefix_samples0 - rx_off_diff, - UE->frame_parms.nb_antennas_rx); - - for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) - { - rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.nb_prefix_samples0]; - } - - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp1, - rxp, - UE->frame_parms.ofdm_symbol_size, - UE->frame_parms.nb_antennas_rx); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != (UE->frame_parms.ofdm_symbol_size)) { - LOG_E(PHY, "problem in rx 7! expect #samples=%d but got only %d! rx_off_diff=%d\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff, rxs, rx_off_diff); - exit_fun("problem in rx 7!"); - return &UE_thread_retval; - } - UE->rx_offset_diff = rx_off_diff; - LOG_D(PHY,"SET rx_off_diff to %d\n",UE->rx_offset_diff); - rx_off_diff = 0; - } - } - // operate on thread sf mod 2 - uint8_t proc_select = sf&1; - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[proc_select]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+proc_select, 1 ); - // lock mutex - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - // increment instance count and change proc subframe/frame variables - int instance_cnt_rxtx = ++proc->instance_cnt_rxtx; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx); - if(sf == 0) - { - UE->proc.proc_rxtx[0].frame_rx++; - UE->proc.proc_rxtx[1].frame_rx++; - } - proc->subframe_rx=sf; - proc->subframe_tx=(sf+4)%10; - proc->frame_tx = proc->frame_rx + ((proc->subframe_rx>5)?1:0); - proc->timestamp_tx = timestamp+(4*UE->frame_parms.samples_per_tti)-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - -#if T_TRACER - T(T_UE_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx)); -#endif - /* - if (sf != (timestamp/UE->frame_parms.samples_per_tti)%10) { - LOG_E(PHY,"steady-state UE_thread error : frame_rx %d, subframe_rx %d, frame_tx %d, subframe_tx %d, rx subframe %d\n",proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,(timestamp/UE->frame_parms.samples_per_tti)%10); - exit(-1); - } - */ - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+proc_select, 0 ); - - - if (instance_cnt_rxtx == 0) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX0+proc_select, 1 ); - if (pthread_cond_signal(&proc->cond_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - LOG_D(PHY, "firing up rxtx_thread[%d] at subframe %d\n", proc_select, sf); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX0+proc_select, 0 ); - - } else { - LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rxtx); - if (instance_cnt_rxtx > 2) { - sleep(1); - exit_fun("instance_cnt_rxtx > 2"); - return &UE_thread_retval; - } - } - if (UE->mode == loop_through_memory) { - printf("Processing subframe %d",proc->subframe_rx); - getchar(); - } - }// for sf=0..10 - - uint8_t proc_select = 9&1; - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[proc_select]; - - if (UE->no_timing_correction == 0) { - if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset > 0) && - (rx_correction_timer == 0)) { - rx_off_diff = -1 ; - LOG_D(PHY,"AbsSubframe %d.%d UE->rx_offset %d > %d, diff %d\n",proc->frame_rx,proc->subframe_rx,UE->rx_offset,0,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset < ((10*UE->frame_parms.samples_per_tti))) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = 1; - LOG_D(PHY,"AbsSubframe %d.%d UE->rx_offset %d < %d, diff %d\n",proc->frame_rx,proc->subframe_rx,UE->rx_offset,10*UE->frame_parms.samples_per_tti,rx_off_diff); - - rx_correction_timer = 5; - } - - if (rx_correction_timer>0) - rx_correction_timer--; - } - } // start_rx_stream==1 - } // UE->is_synchronized==1 - - } // while !oai_exit - return NULL; -} // UE_thread - -/* -void *UE_thread_old(void *arg) -{ - UNUSED(arg) - static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - int spp = openair0_cfg[0].samples_per_packet; - int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=openair0_cfg[0].tx_scheduling_advance; -#ifdef __AVX2__ - int dummy[2][spp] __attribute__((aligned(32))); -#else - int dummy[2][spp] __attribute__((aligned(16))); -#endif - int dummy_dump = 0; - int tx_enabled = 0; - int start_rx_stream = 0; - int rx_off_diff = 0; - int rx_correction_timer = 0; - int first_rx = 0; - RTIME T0; - unsigned int rxs; - void* rxp[2]; - - openair0_timestamp timestamp; - -#ifdef NAS_UE - MessageDef *message_p; -#endif - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); - - // This creates a .5 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 100000; - attr.sched_deadline = 500000; - attr.sched_period = 500000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] main eNB thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - return &UE_thread_retval; - } - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", - (unsigned long)gettid(), sched_getcpu()); - -#else - struct sched_param sp; - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); + PHY_VARS_UE *UE = (PHY_VARS_UE *) arg; + // int tx_enabled = 0; + int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); + openair0_timestamp timestamp,timestamp1; + void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + int start_rx_stream = 0; + int i; + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + if ( threads.iq != -1 ) + CPU_SET(threads.iq, &cpuset); + init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, + "UHD Threads"); + if (oaisim_flag == 0) + AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); + UE->rfdevice.host_type = BBU_HOST; + pthread_setname_np( pthread_self(), "Main UE" ); + init_UE_threads(UE); #ifdef NAS_UE - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); -#endif - - T0 = rt_get_time_ns(); - first_rx = 1; - rxpos=0; - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP, dummy_dump ); - - - while (rxpos < (1+hw_subframe)*UE->frame_parms.samples_per_tti) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - -#ifndef USRP_DEBUG - - DevAssert( UE->frame_parms.nb_antennas_rx <= 2 ); - void* rxp[2]; - - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rxpos] : (void*)dummy[i]; - - - if (UE->mode != loop_through_memory) { - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - spp - ((first_rx==1) ? rx_off_diff : 0), - UE->frame_parms.nb_antennas_rx); - - if (rxs != (spp- ((first_rx==1) ? rx_off_diff : 0))) { - printf("rx error: asked %d got %d ",spp - ((first_rx==1) ? rx_off_diff : 0),rxs); - if (UE->is_synchronized == 1) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - } - } - - if (rx_off_diff !=0) - LOG_D(PHY,"frame %d, rx_offset %d, rx_off_diff %d\n",UE->frame_rx,UE->rx_offset,rx_off_diff); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - // Transmit TX buffer based on timestamp from RX - if ((tx_enabled==1) && (UE->mode!=loop_through_memory)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - - DevAssert( UE->frame_parms.nb_antennas_tx <= 2 ); - void* txp[2]; - - for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++) - txp[i] = (void*)&txdata[i][txpos]; - - UE->rfdevice.trx_write_func(&openair0, - (timestamp+openair0_cfg[0].tx_scheduling_advance-openair0_cfg[0].tx_sample_advance), - txp, - spp - ((first_rx==1) ? rx_off_diff : 0), - UE->frame_parms.nb_antennas_tx, - 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - } - else if (UE->mode == loop_through_memory) - rt_sleep_ns(1000000); -#else - // define USRP_DEBUG is active - rt_sleep_ns(1000000); + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); #endif - rx_off_diff = 0; - first_rx = 0; - - rxpos += spp; - txpos += spp; - - if (txpos >= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti) - txpos -= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti; - } - - if (rxpos >= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti) - rxpos -= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti; - - if (UE->is_synchronized == 1) { - LOG_D( HW, "UE_thread: hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - - if (start_rx_stream == 1) { - LOG_D(PHY,"Locking mutex_rx (IC %d)\n",UE->instance_cnt_rx); - if (pthread_mutex_lock(&UE->mutex_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_rx = ++UE->instance_cnt_rx; - - LOG_D(PHY,"Unlocking mutex_rx (IC %d)\n",instance_cnt_rx); - if (pthread_mutex_unlock(&UE->mutex_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, instance_cnt_rx); - - - if (instance_cnt_rx == 0) { - LOG_D(HW,"signalling rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - if (pthread_cond_signal(&UE->proc.cond_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - LOG_D(HW,"signalled rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - if (UE->mode == loop_through_memory) { - printf("Processing subframe %d",UE->slot_rx>>1); - getchar(); - } - - if (UE->mode == rx_calib_ue) { - if (frame == 10) { - LOG_D(PHY, - "[SCHED][UE] Found cell with N_RB_DL %"PRIu8", PHICH CONFIG (%d,%d), Nid_cell %"PRIu16", NB_ANTENNAS_TX %"PRIu8", frequency offset "PRIi32" Hz, RSSI (digital) %hu dB, measured Gain %d dB, total_rx_gain %"PRIu32" dB, USRP rx gain %f dB\n", - UE->frame_parms.N_RB_DL, - UE->frame_parms.phich_config_common.phich_duration, - UE->frame_parms.phich_config_common.phich_resource, - UE->frame_parms.Nid_cell, - UE->frame_parms.nb_antennas_tx_eNB, - UE->common_vars.freq_offset, - UE->measurements.rx_power_avg_dB[0], - UE->measurements.rx_power_avg_dB[0] - rx_input_level_dBm, - UE->rx_total_gain_dB, - openair0_cfg[0].rx_gain[0] - ); - exit_fun("[HW][UE] UE in RX calibration mode, exiting"); - return &UE_thread_retval; - } - } - } else { - LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rx); - if (instance_cnt_rx > 2) { - exit_fun("instance_cnt_rx > 1"); - return &UE_thread_retval; - } - } - - - if ((tx_enabled==1)&&(UE->mode != loop_through_memory)) { - - if (pthread_mutex_lock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - - int instance_cnt_tx = ++UE->instance_cnt_tx; - - if (pthread_mutex_unlock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, instance_cnt_tx); - - - if (instance_cnt_tx == 0) { - if (pthread_cond_signal(&UE->cond_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; + int sub_frame=-1; + //int cumulated_shift=0; + while (!oai_exit) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + int instance_cnt_synch = UE->proc.instance_cnt_synch; + int is_synchronized = UE->is_synchronized; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + if (is_synchronized == 0) { + if (instance_cnt_synch < 0) { // we can invoke the synch + // grab 10 ms of signal and wakeup synch thread + for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; + + if (UE->mode != loop_through_memory) + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + instance_cnt_synch = ++UE->proc.instance_cnt_synch; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + if (instance_cnt_synch == 0) { + AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); + } else { + LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); + exit_fun("nothing to add"); + } + } else { + // grab 10 ms of signal into dummy buffer + if (UE->mode != loop_through_memory) { + for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&dummy_rx[i][0]; + for (int sf=0; sf<10; sf++) + // printf("Reading dummy sf %d\n",sf); + AssertFatal ( UE->frame_parms.samples_per_tti == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx), ""); + } } - LOG_D(HW,"signalled tx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - - } else { - LOG_E( PHY, "[SCHED][UE] UE TX thread busy (IC %d)!!\n" ); - if (instance_cnt_tx>2) { - exit_fun("instance_cnt_tx > 1"); - return &UE_thread_retval; - } - } - } - } - } else { - // we are not yet synchronized - if ((hw_subframe == 9) && (dummy_dump == 0)) { - // Wake up initial synch thread - if (pthread_mutex_lock(&UE->mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_synch = ++UE->instance_cnt_synch; - - if (pthread_mutex_unlock(&UE->mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - dummy_dump = 1; - - if (instance_cnt_synch == 0) { - if (pthread_cond_signal(&UE->cond_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } - } - - hw_subframe++; - slot+=2; - - if (hw_subframe==10) { - hw_subframe = 0; - first_rx = 1; - frame++; - slot = 1; - - int fail = pthread_mutex_lock(&UE->mutex_synch); - int instance_cnt_synch = UE->instance_cnt_synch; - fail = fail || pthread_mutex_unlock(&UE->mutex_synch); - - if (fail) { - LOG_E( PHY, "[SCHED][UE] error (un-)locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_retval; - } - - if (instance_cnt_synch < 0) { - // the UE_thread_synch is ready - if (UE->is_synchronized == 1) { - rx_off_diff = 0; - LTE_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; // for macro FRAME_LENGTH_COMPLEX_SAMPLES - - // LOG_I(PHY,"UE->rx_offset %d\n",UE->rx_offset); - if ((UE->rx_offset > RX_OFF_MAX) && (start_rx_stream == 0)) { - start_rx_stream=1; - frame=0; - // dump ahead in time to start of frame - -#ifndef USRP_DEBUG - if (UE->mode != loop_through_memory) { - LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); - if (rxs != UE->rx_offset) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - UE->rx_offset=0; - tx_enabled = 1; - } - else - rt_sleep_ns(1000000); -#else - rt_sleep_ns(10000000); -#endif - - } else if ((UE->rx_offset<(FRAME_LENGTH_COMPLEX_SAMPLES/2)) && - (UE->rx_offset > RX_OFF_MIN) && - (start_rx_stream==1) && - (rx_correction_timer == 0)) { - rx_off_diff = -UE->rx_offset + RX_OFF_MIN; - LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(FRAME_LENGTH_COMPLEX_SAMPLES/2)) && - (UE->rx_offset < (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MIN)) && - (start_rx_stream==1) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES - RX_OFF_MIN - UE->rx_offset; - LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MIN,rx_off_diff); - - rx_correction_timer = 5; - } - - if (rx_correction_timer>0) - rx_correction_timer--; - } - - dummy_dump=0; - } - } - -#if defined(ENABLE_ITTI) - itti_update_lte_time(frame, slot); -#endif - } - - return &UE_thread_retval; + } // UE->is_synchronized==0 + else { + if (start_rx_stream==0) { + start_rx_stream=1; + if (UE->mode != loop_through_memory) { + if (UE->no_timing_correction==0) { + LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + AssertFatal(UE->rx_offset == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)UE->common_vars.rxdata, + UE->rx_offset, + UE->frame_parms.nb_antennas_rx),""); + } + UE->rx_offset=0; + UE->proc.proc_rxtx[0].frame_rx++; + UE->proc.proc_rxtx[1].frame_rx++; + + // read in first symbol + AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)UE->common_vars.rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx),""); + slot_fep(UE,0, 0, 0, 0, 0); + } //UE->mode != loop_through_memory + else + rt_sleep_ns(1000*1000); + + } else { + sub_frame++; + sub_frame%=10; + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1]; + + if (UE->mode != loop_through_memory) { + for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ + UE->frame_parms.nb_prefix_samples0+ + sub_frame*UE->frame_parms.samples_per_tti]; + for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) + txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; + + int readBlockSize, writeBlockSize; + if (sub_frame<9) { + readBlockSize=UE->frame_parms.samples_per_tti; + writeBlockSize=UE->frame_parms.samples_per_tti; + } else { + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && + UE->rx_offset > 0 ) + UE->rx_offset_diff = -1 ; + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && + UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) + UE->rx_offset_diff = 1; + + LOG_D(PHY,"SET rx_off_diff to %d\n",UE->rx_offset_diff); + readBlockSize=UE->frame_parms.samples_per_tti - + UE->frame_parms.ofdm_symbol_size - + UE->frame_parms.nb_prefix_samples0 - + UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.samples_per_tti - + UE->rx_offset_diff; + } + + AssertFatal(readBlockSize == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + readBlockSize, + UE->frame_parms.nb_antennas_rx),""); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (2*UE->frame_parms.samples_per_tti) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + if( sub_frame==9) { + // read in first symbol of next frame and adjust for timing drift + int first_symbols=writeBlockSize-readBlockSize; + if ( first_symbols > 0 ) + AssertFatal(first_symbols == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp1, + (void**)UE->common_vars.rxdata, + first_symbols, + UE->frame_parms.nb_antennas_rx),""); + if ( first_symbols <0 ) + LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); + } + pickTime(gotIQs); + // operate on thread sf mod 2 + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + if(sub_frame == 0) { + UE->proc.proc_rxtx[0].frame_rx++; + UE->proc.proc_rxtx[1].frame_rx++; + } + UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); + UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); + proc->subframe_rx=sub_frame; + proc->subframe_tx=(sub_frame+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + proc->timestamp_tx = timestamp+ + (4*UE->frame_parms.samples_per_tti)- + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; + + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + initRefTimes(t1); + initStaticTime(lastTime); + updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); + pickStaticTime(lastTime); + + } else { + printf("Processing subframe %d",proc->subframe_rx); + getchar(); + } + } // start_rx_stream==1 + } // UE->is_synchronized==1 + + } // while !oai_exit + return NULL; } -*/ - /*! * \brief Initialize the UE theads. * Creates the UE threads: @@ -1703,139 +794,95 @@ void *UE_thread_old(void *arg) * - UE_thread_synch * and the locking between them. */ -void init_UE_threads(int inst) -{ - struct rx_tx_thread_data *rtd; - char name[128]; - PHY_VARS_UE *UE; - - UE = PHY_vars_UE_g[inst][0]; - - pthread_attr_init (&UE->proc.attr_ue); - pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - -#ifndef LOWLATENCY - UE->proc.sched_param_ue.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&UE->proc.attr_ue,&sched_param_UE_thread); -#endif +void init_UE_threads(PHY_VARS_UE *UE) { + + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + + pthread_mutex_init(&UE->proc.mutex_synch,NULL); + pthread_cond_init(&UE->proc.cond_synch,NULL); + + // the threads are not yet active, therefore access is allowed without locking + int nb_threads=2; + for (int i=0; i<nb_threads; i++) { + pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[i]); + } + pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - // the threads are not yet active, therefore access is allowed without locking - UE->proc.proc_rxtx[0].instance_cnt_rxtx = -1; - UE->proc.proc_rxtx[1].instance_cnt_rxtx = -1; - UE->proc.proc_rxtx[0].proc_id = 0; - UE->proc.proc_rxtx[1].proc_id = 1; - UE->proc.instance_cnt_synch = -1; - pthread_mutex_init(&UE->proc.proc_rxtx[0].mutex_rxtx,NULL); - pthread_mutex_init(&UE->proc.proc_rxtx[1].mutex_rxtx,NULL); - pthread_mutex_init(&UE->proc.mutex_synch,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[0].cond_rxtx,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[1].cond_rxtx,NULL); - pthread_cond_init(&UE->proc.cond_synch,NULL); - rtd = calloc(1, sizeof(struct rx_tx_thread_data)); - if (rtd == NULL) abort(); - rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[0].CC_id]; - rtd->proc = &UE->proc.proc_rxtx[0]; - pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[0]); - sprintf(name, "rxn_txnp4_even UE %d", inst); - pthread_setname_np(UE->proc.proc_rxtx[0].pthread_rxtx, name); - rtd = calloc(1, sizeof(struct rx_tx_thread_data)); - if (rtd == NULL) abort(); - rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[1].CC_id]; - rtd->proc = &UE->proc.proc_rxtx[1]; - pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[1]); - sprintf(name, "rxn_txnp4_odd UE %d", inst); - pthread_setname_np(UE->proc.proc_rxtx[1].pthread_rxtx, name); - pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - sprintf(name, "UE_thread_synch UE %d", inst); - pthread_setname_np(UE->proc.pthread_synch, name); } #ifdef OPENAIR2 -void fill_ue_band_info(void) -{ - - UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; - int i,j; - - bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - - for (i=0; i<bands_to_scan.nbands; i++) { - - for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) - if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { - memcpy(&bands_to_scan.band_info[i], - &eutra_bands[j], - sizeof(eutra_band_t)); - - printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", - bands_to_scan.band_info[i].band, - UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, - bands_to_scan.band_info[i].dl_min, - bands_to_scan.band_info[i].dl_max, - bands_to_scan.band_info[i].ul_min, - bands_to_scan.band_info[i].ul_max, - (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); - break; - } - } +void fill_ue_band_info(void) { + + UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; + int i,j; + + bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; + + for (i=0; i<bands_to_scan.nbands; i++) { + + for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) + if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { + memcpy(&bands_to_scan.band_info[i], + &eutra_bands[j], + sizeof(eutra_band_t)); + + printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", + bands_to_scan.band_info[i].band, + UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, + bands_to_scan.band_info[i].dl_min, + bands_to_scan.band_info[i].dl_max, + bands_to_scan.band_info[i].ul_min, + bands_to_scan.band_info[i].ul_max, + (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); + break; + } + } } #endif -int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) -{ +int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { - int i, CC_id; - LTE_DL_FRAME_PARMS *frame_parms; - openair0_rf_map *rf_map; + int i, CC_id; + LTE_DL_FRAME_PARMS *frame_parms; + openair0_rf_map *rf_map; - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - rf_map = &phy_vars_ue[CC_id]->rf_map; - - if (phy_vars_ue[CC_id]) { - frame_parms = &(phy_vars_ue[CC_id]->frame_parms); - } else { - printf("phy_vars_UE[%d] not initialized\n", CC_id); - return(-1); - } - - /* - if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) - N_TA_offset = 624; - else if (frame_parms->N_RB_DL == 50) - N_TA_offset = 624/2; - else if (frame_parms->N_RB_DL == 25) - N_TA_offset = 624/4; - } - */ - - // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); - - for (i=0; i<frame_parms->nb_antennas_rx; i++) { - printf( "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD - printf("rxdata[%d] : %p\n",i,rxdata[i]); - } - - for (i=0; i<frame_parms->nb_antennas_tx; i++) { - printf( "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; - printf("txdata[%d] : %p\n",i,txdata[i]); + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + rf_map = &phy_vars_ue[CC_id]->rf_map; + + AssertFatal( phy_vars_ue[CC_id] !=0, ""); + frame_parms = &(phy_vars_ue[CC_id]->frame_parms); + + // replace RX signal buffers with mmaped HW versions + rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); + txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + + for (i=0; i<frame_parms->nb_antennas_rx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); + rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD + } + + for (i=0; i<frame_parms->nb_antennas_tx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); + txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; + } + + // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] + // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] + // be careful when releasing memory! + // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) } - - // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] - // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] - // be careful when releasing memory! - // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) - - } - - return 0; + return 0; } +