diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 29792d126001660927e366f9393aa94564605bd9..22394aa5ebf4691bfe15c52cbe222578313d22aa 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -174,7 +174,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}" ) set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}" + "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D${MKVER}" ) @@ -604,7 +604,6 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} ) set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") -add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c) ########################################################## @@ -1986,6 +1985,11 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_ target_link_libraries(enbscope ${XFORMS_LIBRARIES}) target_link_libraries(uescope ${XFORMS_LIBRARIES}) +add_library(rfsimulator MODULE + ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c + ) +target_link_libraries(rfsimulator SIMU ${ATLAS_LIBRARIES}) + set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") #include T directory even if the T is off because T macros are in the code @@ -2029,6 +2033,25 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) ################################# # add executables for operation ################################# +add_library(minimal_lib + ${OPENAIR_DIR}/common/utils/backtrace.c + ${OPENAIR_DIR}/common/utils/LOG/log.c + ${OPENAIR_DIR}/common/config/config_userapi.c + ${OPENAIR_DIR}/common/config/config_load_configmodule.c + ${OPENAIR_DIR}/common/config/config_cmdline.c + ${OPENAIR_DIR}/common/utils/minimal_stub.c + ${T_SOURCE} + ) +target_link_libraries(minimal_lib pthread dl ${T_LIB}) + +add_executable(replay_node + ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c + ) +target_link_libraries (replay_node minimal_lib) + +add_executable(measurement_display + ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) +target_link_libraries (measurement_display minimal_lib) # lte-softmodem is both eNB and UE implementation ################################################### diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 66d3078d333cc3b697d5ee9ae81b406e213cf064..65e7a6dcc23c6e0ed760ef885c0f8dff186919b9 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -450,7 +450,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double)); if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { - *(cfgoptions->u64ptr)=cfgoptions->defdblval; + *(cfgoptions->dblptr)=cfgoptions->defdblval; status=1; printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); } diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c new file mode 100644 index 0000000000000000000000000000000000000000..86454fe53f87dad750a11d7c0a1f07d67b5e5379 --- /dev/null +++ b/common/utils/minimal_stub.c @@ -0,0 +1,4 @@ +int T_stdout; + +void exit_function(const char *file, const char *function, const int line, const char *s) { +} diff --git a/common/utils/simple_executable.h b/common/utils/simple_executable.h new file mode 100644 index 0000000000000000000000000000000000000000..98b75012dff61df05c20328904779734f2609067 --- /dev/null +++ b/common/utils/simple_executable.h @@ -0,0 +1,37 @@ +#ifndef __SIMPLE_EXE_H__ +#define __SIMPLE_EXE_H__ +#ifndef __USE_GNU +#define __USE_GNU +#endif +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <stdio.h> +#include <pthread.h> +#include <sched.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <string.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/time.h> +#include <stdint.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdbool.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <common/utils/assertions.h> +#include <common/utils/LOG/log.h> +#include "common_lib.h" + +#ifdef T + #undef T + #define T(...) +#endif + +#endif diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 1f2c44ca5b0a39c1103e7bac2ea20ebad049d4c6..f7123d6b43b72b06ce88fbd317a70174a0691162 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -33,7 +33,9 @@ #define __PHY_DEFS_ENB__H__ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include <sched.h> #include <stdio.h> #include <stdlib.h> diff --git a/openair1/PHY/impl_defs_lte_NB_IoT.h b/openair1/PHY/impl_defs_lte_NB_IoT.h index 1167323174e1a3048df10768afd2ca481841c97a..97617b0ee063ed82355a65fc27085f207d37e545 100644 --- a/openair1/PHY/impl_defs_lte_NB_IoT.h +++ b/openair1/PHY/impl_defs_lte_NB_IoT.h @@ -415,7 +415,7 @@ typedef struct { /// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented uint16_t nprach_CP_Length; /// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled. \vr{[1..2]} - struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList; + rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList; /// NPRACH Parameters List NPRACH_List_NB_IoT_t nprach_ParametersList; diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index df1f6f46933818054bcd1252fb05d54961fde544..c7c3e0e92e9f0b8dd403113481c264073639ae1c 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -282,8 +282,16 @@ typedef struct { #define cmax(a,b) ((a>b) ? (a) : (b)) #define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) #define cmin(a,b) ((a<b) ? (a) : (b)) + +#ifdef __cplusplus +#ifdef min +#undef min +#undef max +#endif +#else #define max(a,b) cmax(a,b) #define min(a,b) cmin(a,b) +#endif #ifndef malloc16 # ifdef __AVX2__ diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ba1c1832cda208534df1b5bc7a5bef68ebddc048..cc6751ddb13aaa6108461dc766662c36814febb4 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1001,7 +1001,7 @@ void eNB_Config_Local_DRX( { UE_list_t *UE_list_mac = NULL; int UE_id = -1; - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; UE_list_mac = &(RC.mac[Mod_id]->UE_list); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index bb051dcd1ece3049c264cf0c4385cb1f95190858..c6200dc74d8fd114722ba340c7c4a60aa767cf2c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -91,7 +91,7 @@ void schedule_SRS(module_id_t module_idP, eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &(eNB->UE_list); nfapi_ul_config_request_body_t *ul_req = NULL; - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; COMMON_channels_t *cc = eNB->common_channels; LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon = NULL; struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated = NULL; @@ -198,7 +198,7 @@ void schedule_CSI(module_id_t module_idP, UE_list_t *UE_list = &eNB->UE_list; COMMON_channels_t *cc = NULL; nfapi_ul_config_request_body_t *ul_req = NULL; - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { cc = &eNB->common_channels[CC_id]; @@ -571,7 +571,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &(eNB->UE_list); COMMON_channels_t *cc = eNB->common_channels; - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; start_meas(&(eNB->eNB_scheduler)); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 95e2bf59e8ee6e8173c5b52376df39591fb5641b..ddbda5b2a0e49cfa178b856a1fbe7e0dea4fa3c5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -480,7 +480,7 @@ schedule_ue_spec(module_id_t module_idP, eNB_UE_STATS *eNB_UE_stats = NULL; UE_TEMPLATE *ue_template = NULL; eNB_STATS *eNB_stats = NULL; - RRC_release_ctrl *release_ctrl = NULL; + RRC_release_ctrl_t *release_ctrl = NULL; DLSCH_PDU *dlsch_pdu = NULL; RA_t *ra = NULL; int sdu_length_total = 0; @@ -490,7 +490,7 @@ schedule_ue_spec(module_id_t module_idP, int continue_flag = 0; int32_t normalized_rx_power, target_rx_power; int tpc = 1; - UE_sched_ctrl *ue_sched_ctrl; + UE_sched_ctrl_t *ue_sched_ctrl; int mcs; int i; int min_rb_unit[NFAPI_CC_MAX]; @@ -1688,7 +1688,7 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int nb_mac_CC = RC.nb_mac_CC[Mod_id]; UE_list_t *UE_list = &eNB->UE_list; slice_info_t *sli = &eNB->slice_info; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; int slice_sorted_list[MAX_NUM_SLICES]; @@ -1914,7 +1914,7 @@ schedule_ue_spec_br(module_id_t module_idP, COMMON_channels_t *cc = mac->common_channels; UE_list_t *UE_list = &mac->UE_list; UE_TEMPLATE *UE_template = NULL; - UE_sched_ctrl *ue_sched_ctl = NULL; + UE_sched_ctrl_t *ue_sched_ctl = NULL; nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL; nfapi_ul_config_request_pdu_t *ul_config_pdu = NULL; nfapi_tx_request_pdu_t *TX_req = NULL; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 4c2e0b46a2827af6a08d56abeeb5e5985a0d5b8f..697c738b807b2d37668ec79177b99b2c10246d18 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -179,7 +179,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &eNB->UE_list; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; uint8_t CC_id; int UE_id; unsigned char round = 0; @@ -585,7 +585,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, // uint16_t r1=0; uint8_t CC_id; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; // int rrc_status = RRC_IDLE; COMMON_channels_t *cc; #ifdef TM5 @@ -596,7 +596,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, rnti_t rnti1, rnti2; LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; + UE_sched_ctrl_t *ue_sched_ctl1, *ue_sched_ctl2; #endif memset(rballoc_sub[0],0,(MAX_NUM_CCs)*(N_RBG_MAX)*sizeof(unsigned char)); memset(min_rb_unit,0,sizeof(min_rb_unit)); @@ -828,7 +828,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, int32_t normalized_rx_power, target_rx_power; int32_t tpc = 1; static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; int mcs; int i; int min_rb_unit[MAX_NUM_CCs]; @@ -1968,7 +1968,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( uint8_t ulsch_ue_max_num[MAX_NUM_CCs]; uint16_t saved_ulsch_dci[MAX_NUM_CCs]; rnti_t rnti; - UE_sched_ctrl *UE_sched_ctl = NULL; + UE_sched_ctrl_t *UE_sched_ctl = NULL; uint8_t cc_id_flag[MAX_NUM_CCs]; uint8_t harq_pid = 0,round = 0; UE_list_t *UE_list= &eNB->UE_list; @@ -2627,7 +2627,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, COMMON_channels_t *cc; UE_list_t *UE_list=&eNB->UE_list; UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; + UE_sched_ctrl_t *UE_sched_ctrl; int sched_frame=frameP; int rvidx_tab[4] = {0,2,3,1}; uint16_t ul_req_index; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c index 2f566c0d7a0d48d1397c23b4fe4892cba59879dc..4f74ab0d09a908a0f139cc0c705ef90a8e442935 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -208,7 +208,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s COMMON_channels_t *cc = &mac->common_channels[0]; UE_list_t *UE_list=&mac->UE_list; UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; + UE_sched_ctrl_t *UE_sched_ctrl; int sched_frame=frameP; int sched_subframe = (subframeP+4)%10; uint16_t ul_req_index; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 85fd84a305c4b5c22bada80b89980d6d95201d65..856045166f7b3f3b277e3d23947948b0527b8438 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1073,7 +1073,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc, //------------------------------------------------------------------------------ uint8_t -get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl, +get_rel8_dl_cqi_pmi_size(UE_sched_ctrl_t *sched_ctl, int CC_idP, COMMON_channels_t *cc, uint8_t tmode, @@ -2182,7 +2182,7 @@ add_new_ue(module_id_t mod_idP, #endif memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, - sizeof(UE_sched_ctrl)); + sizeof(UE_sched_ctrl_t)); memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0, sizeof(eNB_UE_STATS)); @@ -2520,7 +2520,7 @@ UE_is_to_be_scheduled(module_id_t module_idP, //------------------------------------------------------------------------------ { UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; - UE_sched_ctrl *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; // do not schedule UE if UL is not working if (UE_sched_ctl->ul_failure_timer > 0 || UE_sched_ctl->ul_out_of_sync > 0) @@ -3928,7 +3928,7 @@ extract_harq(module_id_t mod_idP, { eNB_MAC_INST *eNB = RC.mac[mod_idP]; UE_list_t *UE_list = &eNB->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; rnti_t rnti = UE_RNTI(mod_idP, UE_id); COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; @@ -4573,7 +4573,7 @@ extract_pucch_csi(module_id_t mod_idP, //------------------------------------------------------------------------------ { UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; int no_pmi; uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; @@ -4685,7 +4685,7 @@ extract_pusch_csi(module_id_t mod_idP, { UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 }; int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; @@ -4980,7 +4980,7 @@ cqi_indication(module_id_t mod_idP, return; } - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; if (UE_id >= 0) { LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", @@ -5047,7 +5047,7 @@ SR_indication(module_id_t mod_idP, T_INT(rntiP)); int UE_id = find_UE_id(mod_idP, rntiP); UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *UE_scheduling_ctrl = NULL; + UE_sched_ctrl_t *UE_scheduling_ctrl = NULL; if (UE_id != -1) { UE_scheduling_ctrl = &(UE_list->UE_sched_ctrl[UE_id]); @@ -5178,7 +5178,7 @@ harq_indication(module_id_t mod_idP, } UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; // extract HARQ Information diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 454278ed9833d8a3bce1a2f2eee2053f9bee614b..dd228c4250eca1fb13b85294e7ff199765981d46 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -121,7 +121,7 @@ rx_sdu(const module_id_t enb_mod_idP, eNB_MAC_INST *mac = NULL; UE_list_t *UE_list = NULL; rrc_eNB_ue_context_t *ue_contextP = NULL; - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; UE_TEMPLATE *UE_template_ptr = NULL; /* Init */ @@ -1340,7 +1340,7 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_list_t *UE_list = NULL; slice_info_t *sli = NULL; UE_TEMPLATE *UE_template_ptr = NULL; - UE_sched_ctrl *UE_sched_ctrl_ptr = NULL; + UE_sched_ctrl_t *UE_sched_ctrl_ptr = NULL; int rvidx_tab[4] = {0, 2, 3, 1}; int first_rb_slice[NFAPI_CC_MAX]; int n_rb_ul_tab[NFAPI_CC_MAX]; @@ -1954,7 +1954,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &(eNB->UE_list); UE_TEMPLATE *UE_template = NULL; - UE_sched_ctrl *UE_sched_ctrl = NULL; + UE_sched_ctrl_t *UE_sched_ctrl = NULL; if (sched_subframeP < subframeP) { sched_frame++; diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 8f9a1b94f61014c339ffba776d7cf6d40cb13029..276f1e4e6f25af1a85c256d0eda2a48a10d553a7 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1070,7 +1070,7 @@ typedef struct { /// DRX UL retransmission timer, one per UL HARQ process /* Not implemented yet */ /* End of C-DRX related timers */ -} UE_sched_ctrl; +} UE_sched_ctrl_t; /*! \brief eNB template for the Random access information */ typedef struct { @@ -1168,7 +1168,7 @@ typedef struct { /// eNB to UE statistics eNB_UE_STATS eNB_UE_stats[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; /// scheduling control info - UE_sched_ctrl UE_sched_ctrl[MAX_MOBILES_PER_ENB]; + UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_ENB]; int next[MAX_MOBILES_PER_ENB]; int head; int next_ul[MAX_MOBILES_PER_ENB]; @@ -1191,11 +1191,11 @@ typedef struct { rnti_t rnti; ///remove UE context flag boolean_t removeContextFlg; -} UE_free_ctrl; +} UE_free_ctrl_t; /*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/ typedef struct { /// deleting control info - UE_free_ctrl UE_free_ctrl[NUMBER_OF_UE_MAX+1]; + UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1]; int num_UEs; int head_freelist; ///the head position of the delete list int tail_freelist; ///the tail position of the delete list @@ -1772,11 +1772,11 @@ typedef struct { volatile uint8_t flag; rnti_t rnti; mui_t rrc_eNB_mui; -}RRC_release_ctrl; +}RRC_release_ctrl_t; typedef struct { uint16_t num_UEs; - RRC_release_ctrl RRC_release_ctrl[NUMBER_OF_UE_MAX]; + RRC_release_ctrl_t RRC_release_ctrl[NUMBER_OF_UE_MAX]; } RRC_release_list_t; typedef struct { diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index f5762cb14ec486f48030981786cd2c1af534a959..695005cd1f871848d8bc3fc5ef3aca2e1a553458 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -1160,7 +1160,7 @@ void get_csi_params(COMMON_channels_t * cc, struct LTE_CQI_ReportPeriodic *cqi_PMI_ConfigIndex, uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H); -uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, +uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl_t * sched_ctl, int CC_idP, COMMON_channels_t * cc, uint8_t tmode, struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index a162dd5bd611dbe5f1b97de1649cd3437ef245b5..0dc11b0e45a4fa7f35c7964615065435e4794eeb 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -505,7 +505,7 @@ void sort_UEs(module_id_t Mod_idP, int list_size = 0; struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx}; UE_list_t *UE_list = &(RC.mac[Mod_idP]->UE_list); - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { @@ -546,7 +546,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, const uint8_t rbs_retx[NFAPI_CC_MAX]) { int UE_id, CC_id, N_RB_DL, i; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; uint16_t available_rbs; for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { @@ -590,7 +590,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int ue_count_retx[NFAPI_CC_MAX]; //uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; COMMON_channels_t *cc; // Reset @@ -1226,7 +1226,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; UE_list_t *UE_list = &eNB->UE_list; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; // int rrc_status = RRC_IDLE; #ifdef TM5 int harq_pid1 = 0; @@ -1236,7 +1236,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, rnti_t rnti1, rnti2; LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; + UE_sched_ctrl_t *ue_sched_ctl1, *ue_sched_ctl2; #endif // Initialize scheduling information for all active UEs memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx])); @@ -1391,7 +1391,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, uint8_t CC_id; int i, j; UE_list_t *UE_list; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; int N_RB_DL, RBGsize, RBGsize_last; int N_RBG[NFAPI_CC_MAX]; #ifdef SF0_LIMIT @@ -1615,7 +1615,7 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int i; int tm = get_tmode(Mod_id, CC_id, UE_id); UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); for (i = 0; i < N_RBG; i++) { @@ -1685,7 +1685,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, UE_list_t *UE_list = &eNB->UE_list; slice_info_t *sli = &eNB->slice_info; UE_TEMPLATE *UE_template = 0; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; int N_RB_UL = 0; uint16_t available_rbs, first_rb_offset; rnti_t rntiTable[MAX_MOBILES_PER_ENB]; @@ -1865,7 +1865,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, UE_list_t *UE_list = &eNB->UE_list; slice_info_t *sli = &eNB->slice_info; UE_TEMPLATE *UE_template; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl_t *ue_sched_ctl; int Ncp; int N_RB_UL; int first_rb_offset, available_rbs; @@ -2042,7 +2042,7 @@ void sort_ue_ul(module_id_t module_idP, int list_size = 0; struct sort_ue_ul_params params = { module_idP, sched_frameP, sched_subframeP }; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - UE_sched_ctrl *UE_scheduling_control = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 230b9511f0df195478bfb8f8ed1bffe526d78111..b7ca81f6dde7a285821766fa755575779bdf3baa 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -5814,7 +5814,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n",PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ue_context_pP->ue_context.rnti); return; } - UE_sched_ctrl *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 3f81816aa1022de2a623cb8bc865cadb0f9e74cd..42a39f90ed546940e230bd601b066ad46853bf74 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -42,35 +42,35 @@ int set_device(openair0_device *device) { switch (device->type) { case EXMIMO_DEV: - printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case USRP_B200_DEV: - printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case USRP_X300_DEV: - printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case BLADERF_DEV: - printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case LMSSDR_DEV: - printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case IRIS_DEV: - printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case NONE_DEV: - printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_I(HW,"[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; default: - printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_E(HW,"[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); return -1; } @@ -90,7 +90,7 @@ int set_transport(openair0_device *device) { break; default: - printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + LOG_E(HW,"[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); return -1; break; } @@ -119,7 +119,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param ret=load_module_shlib(libname,shlib_fdesc,1,NULL); if (ret < 0) { - fprintf(stderr,"Library %s couldn't be loaded\n",libname); + LOG_E(HW,"Library %s couldn't be loaded\n",libname); } else { ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); } @@ -135,7 +135,7 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf if ( rc >= 0) { if ( set_device(device) < 0) { - fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); + LOG_E(HW, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); return -1; } } @@ -149,7 +149,7 @@ int openair0_transport_load(openair0_device *device, openair0_config_t *openair0 if ( rc >= 0) { if ( set_transport(device) < 0) { - fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__); + LOG_E(HW, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__); return -1; } } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index c7ae3b9d25d18da5c5c9d028f495f0acfb6fb796..81a5bd0f54f740cbb66e2d82180f8a3f67539c0b 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -34,6 +34,7 @@ #define COMMON_LIB_H #include <stdint.h> #include <sys/types.h> +#include <openair1/PHY/TOOLS/tools_defs.h> /* name of shared library implementing the radio front end */ #define OAI_RF_LIBNAME "oai_device" @@ -83,9 +84,6 @@ typedef enum { */ /*!\brief RF device types */ -#ifdef OCP_FRAMEWORK -#include <enums.h> -#else typedef enum { MIN_RF_DEV_TYPE = 0, /*!\brief device is ExpressMIMO */ @@ -102,10 +100,13 @@ typedef enum { IRIS_DEV, /*!\brief device is NONE*/ NONE_DEV, + /*!\brief device is ADRV9371_ZC706 */ + ADRV9371_ZC706_DEV, + /*!\brief device is UEDv2 */ + UEDv2_DEV, MAX_RF_DEV_TYPE } dev_type_t; -#endif /*!\brief transport protocol types */ @@ -397,6 +398,31 @@ struct openair0_device_t { typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); /* type of transport init function, implemented in shared lib */ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); +#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record +#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record +#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record +#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record + +#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record +#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record +#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record +#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record + +#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) + +#define sample_t struct complex16 // 2*16 bits complex number + +typedef struct { + uint64_t magic; // Magic value (see defines above) + uint32_t size; // Number of samples per antenna to follow this header + uint32_t nbAnt; // Total number of antennas following this header + // Samples per antenna follow this header, + // i.e. nbAnt = 2 => this header+samples_antenna_0+samples_antenna_1 + // data following this header in bytes is nbAnt*size*sizeof(sample_t) + uint64_t timestamp; // Timestamp value of first sample + uint32_t option_value; // Option value + uint32_t option_flag; // Option flag +} samplesBlockHeader_t; #ifdef __cplusplus extern "C" diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md index ebe7d72ee05860907e1c3b5315bb84270d0879b6..ae82b27f93cd52210ea992613caf7844fd1c8f1a 100644 --- a/targets/ARCH/rfsimulator/README.md +++ b/targets/ARCH/rfsimulator/README.md @@ -1,14 +1,26 @@ -## General - +#General This is a RF simulator that allows to test OAI without a RF board. It replaces a actual RF board driver. As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound) -## build +#build - No specific build is required, use the [oai softmodem build procedure](../../../doc/BUILD.md) +## From build_oai +You can build it the same way, and together with actual RF driver +Example: +```bash +./build_oai --ue-nas-use-tun --UE --eNB -w SIMU +``` +It is also possible to build actual RF and use choose on each run: +```bash +./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator +``` +Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem) +We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver. + +## Add the rfsimulator after initial build After any regular build, you can compile the driver ```bash cd <the_compilation_dir_from_bouild_oai_script>/build @@ -18,25 +30,15 @@ Then, you can use it freely # Usage Setting the env variable RFSIMULATOR enables the RF board simulator -It should the set to "enb" in the eNB +It should the set to "server" in the eNB or gNB ## 4G case For the UE, it should be set to the IP address of the eNB example: ```bash -sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 --rfsim +sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 ``` -For the eNodeB, use a valid configuration file setup for USRP board tests and start the softmodem as usual, but adding the `--rfsim` option. - - - -```bash -sudo RFSIMULATOR=enb ./lte-softmodem -O <config file> --rfsim -``` - - - Except this, the UE and the eNB can be used as it the RF is real If you reach 'RA not active' on UE, be careful to generate a valid SIM @@ -55,7 +57,7 @@ make rfsimulator ``` ### Launch gNB in one window ```bash -sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD +sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD ``` ### Launch UE in another window ```bash @@ -64,8 +66,40 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine In UE, you can add "-d" to get the softscope -## Caveacts +### store and replay -Still issues in power control: txgain, rxgain are not used +You can store emitted I/Q samples: + +If you set the environment variable: saveIQfile to a file name +The simulator will write all IQ samples into this file + +Then, you can replay with the executable "replay_node" + +First compile it, as the other binaries +``` +make replay_node +``` +You can use this binary as I/Q data source to feed whatever UE or NB with recorded I/Q samples. + +The file format is successive blocks of a header followed by the I/Q array. +If you have existing stored I/Q, you can adpat the tool "replay_node" to convert your format to the rfsimulator format. + +The format intend to be compatible with the OAI store/replay feature on USRP +### Channel simulation +The RF channel simulator is called. +In current version all channel paramters are hard coded in the call to: +``` +new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, + AWGN, + bridge->sample_rate, + bridge->tx_bw, + 0.0, // forgetting_factor + 0, // maybe used for TA + 0); // path_loss in dB +``` +Only the input noise can be changed on command line with -s parameter. +With path loss = 0 set "-s 5" to see a little noise +#Caveacts +Still issues in power control: txgain, rxgain are not used diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index a17327b03ecc5791cadc7cef76fbecc9d3205da8..c8c21fce4f6cf72102fee639085e467b4c659191 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -21,63 +21,172 @@ #include "common_lib.h" #include <openair1/PHY/defs_eNB.h> #include "openair1/PHY/defs_UE.h" +#include <openair1/SIMULATION/TOOLS/sim.h> #define PORT 4043 //TCP port for this simulator #define CirSize 3072000 // 100ms is enough -#define sample_t uint32_t // 2*16 bits complex number #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) -#define MAGICeNB 0xA5A5A5A5A5A5A5A5 -#define MAGICUE 0x5A5A5A5A5A5A5A5A -typedef struct { - uint64_t magic; - uint32_t size; - uint32_t nbAnt; - uint64_t timestamp; -} transferHeader; +#define MAX_SIMULATION_CONNECTED_NODES 5 +#define GENERATE_CHANNEL 10 //each frame in DL + +// Fixme: datamodel, external variables in .h files, ... +#include <common/ran_context.h> +extern double snr_dB; +extern RAN_CONTEXT_t RC; +// + +pthread_mutex_t Sockmutex; typedef struct buffer_s { int conn_sock; bool alreadyRead; uint64_t lastReceivedTS; bool headerMode; - transferHeader th; + samplesBlockHeader_t th; char *transferPtr; uint64_t remainToTransfer; char *circularBufEnd; sample_t *circularBuf; + channel_desc_t *channel_model; } buffer_t; typedef struct { int listen_sock, epollfd; uint64_t nextTimestamp; uint64_t typeStamp; - uint64_t initialAhead; char *ip; + int saveIQfile; buffer_t buf[FD_SETSIZE]; + int rx_num_channels; + int tx_num_channels; + double sample_rate; + double tx_bw; } rfsimulator_state_t; +/* + Legacy study: + The parameters are: + gain&loss (decay, signal power, ...) + either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average + => don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE + will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop) + lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); + a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain + + multi_path (auto convolution, ISI, ...) + either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes + legacy: we regenerate each sub frame in UL, and each frame only in DL +*/ +void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig, + int rxAnt, + channel_desc_t *channelDesc, + int nbSamples, + uint64_t TS + ) { + // channelDesc->path_loss_dB should contain the total path gain + // so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...) + // UE and NB gain control to be added + // Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...) + const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0); + // Energy in one sample to calibrate input noise + //Fixme: modified the N0W computation, not understand the origin value + const double KT=1.38e-23*290; //Boltzman*temperature + // sampling rate is linked to acquisition band (the input pass band filter) + const double noise_figure_watt = KT*channelDesc->sampling_rate; + // Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ? + // the parameter "-s" is declared as SNR, but the input power is not well defined + // −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise) + const double rxGain= 132.24 - snr_dB; + // sqrt(4*noise_figure_watt) is the thermal noise factor (volts) + // fixme: the last constant is pure trial results to make decent noise + const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10; + // Fixme: we don't fill the offset length samples at begining ? + // anyway, in today code, channel_offset=0 + const int dd = abs(channelDesc->channel_offset); + const int nbTx=channelDesc->nb_tx; + + for (int i=0; i<((int)nbSamples-dd); i++) { + struct complex16 *out_ptr=after_channel_sig+dd+i; + struct complex rx_tmp= {0}; + + for (int txAnt=0; txAnt < nbTx; txAnt++) { + const struct complex *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)]; + + //const struct complex *channelModelEnd=channelModel+channelDesc->channel_length; + for (int l = 0; l<(int)channelDesc->channel_length; l++) { + // let's assume TS+i >= l + // fixme: the rfsimulator current structure is interleaved antennas + // this has been designed to not have to wait a full block transmission + // but it is not very usefull + // it would be better to split out each antenna in a separate flow + // that will allow to mix ru antennas freely + struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize]; + rx_tmp.x += tx16.r * channelModel[l].x - tx16.i * channelModel[l].y; + rx_tmp.y += tx16.i * channelModel[l].x + tx16.r * channelModel[l].y; + } //l + } + + out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0)); + out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0)); + out_ptr++; + } + + if ( (TS*nbTx)%CirSize+nbSamples <= CirSize ) + // Cast to a wrong type for compatibility ! + LOG_D(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n", + 10*log10((double)signal_energy((int32_t *)&input_sig[(TS*nbTx)%CirSize], nbSamples)), + 10*log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)), + channelDesc->path_loss_dB, + 10*log10(noise_per_sample)); +} + void allocCirBuf(rfsimulator_state_t *bridge, int sock) { buffer_t *ptr=&bridge->buf[sock]; AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); ptr->conn_sock=sock; + ptr->alreadyRead=false; + ptr->lastReceivedTS=0; ptr->headerMode=true; ptr->transferPtr=(char *)&ptr->th; - ptr->remainToTransfer=sizeof(transferHeader); + ptr->remainToTransfer=sizeof(samplesBlockHeader_t); int sendbuff=1000*1000*10; AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); struct epoll_event ev= {0}; ev.events = EPOLLIN | EPOLLRDHUP; ev.data.fd = sock; AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, ""); + // create channel simulation model for this mode reception + // snr_dB is pure global, coming from configuration paramter "-s" + // Fixme: referenceSignalPower should come from the right place + // but the datamodel is inconsistant + // legacy: RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower + // (must not come from ru[]->frame_parms as it doesn't belong to ru !!!) + // Legacy sets it as: + // ptr->channel_model->path_loss_dB = -132.24 + snr_dB - RC.ru[0]->frame_parms->pdsch_config_common.referenceSignalPower; + // we use directly the paramter passed on the command line ("-s") + // the value channel_model->path_loss_dB seems only a storage place (new_channel_desc_scm() only copy the passed value) + // Legacy changes directlty the variable channel_model->path_loss_dB place to place + // while calling new_channel_desc_scm() with path losses = 0 + ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, + AWGN, + bridge->sample_rate, + bridge->tx_bw, + 0.0, // forgetting_factor + 0, // maybe used for TA + 0); // path_loss in dB + random_channel(ptr->channel_model,false); } void removeCirBuf(rfsimulator_state_t *bridge, int sock) { AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); close(sock); free(bridge->buf[sock].circularBuf); + // Fixme: no free_channel_desc_scm(bridge->buf[sock].channel_model) implemented + // a lot of mem leaks + free(bridge->buf[sock].channel_model); memset(&bridge->buf[sock], 0, sizeof(buffer_t)); bridge->buf[sock].conn_sock=-1; } @@ -87,12 +196,11 @@ void socketError(rfsimulator_state_t *bridge, int sock) { LOG_W(HW,"Lost socket \n"); removeCirBuf(bridge, sock); - if (bridge->typeStamp==MAGICUE) + if (bridge->typeStamp==UE_MAGICDL_FDD) exit(1); } } - #define helpTxt "\ \x1b[31m\ rfsimulator: error: you have to run one UE and one eNB\n\ @@ -117,11 +225,18 @@ void setblocking(int sock, enum blocking_t active) { AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); } -static bool flushInput(rfsimulator_state_t *t); +static bool flushInput(rfsimulator_state_t *t, int timeout); + +void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { + if (t->saveIQfile != -1) { + if (write(t->saveIQfile, _buf, count) != count ) + LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno)); + } -void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { + AssertFatal(fd>=0 && _buf && count >0 && t, + "Bug: %d/%p/%zd/%p", fd, _buf, count, t); char *buf = _buf; - int l; + ssize_t l; setblocking(fd, notBlocking); while (count) { @@ -132,7 +247,9 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { continue; if(errno==EAGAIN) { - flushInput(t); + // The opposite side is saturated + // we read incoming sockets meawhile waiting + flushInput(t, 5); continue; } else return; @@ -145,7 +262,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { int server_start(openair0_device *device) { rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; - t->typeStamp=MAGICeNB; + t->typeStamp=ENB_MAGICDL_FDD; AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); int enable = 1; AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); @@ -168,7 +285,7 @@ sin_addr: int start_ue(openair0_device *device) { rfsimulator_state_t *t = device->priv; - t->typeStamp=MAGICUE; + t->typeStamp=UE_MAGICDL_FDD; int sock; AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); struct sockaddr_in addr = { @@ -200,14 +317,16 @@ sin_addr: return 0; } +uint64_t lastW=-1; int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { rfsimulator_state_t *t = device->priv; + LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp); for (int i=0; i<FD_SETSIZE; i++) { buffer_t *ptr=&t->buf[i]; if (ptr->conn_sock >= 0 ) { - transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp}; + samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp}; fullwrite(ptr->conn_sock,&header, sizeof(header), t); sample_t tmpSamples[nsamps][nbAnt]; @@ -223,21 +342,27 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi } } + lastW=timestamp; LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); + // Let's verify we don't have incoming data + // This is mandatory when the opposite side don't transmit + // This is mandatory when the opposite side don't transmit + flushInput(t, 0); + pthread_mutex_unlock(&Sockmutex); return nsamps; } -static bool flushInput(rfsimulator_state_t *t) { +static bool flushInput(rfsimulator_state_t *t, int timeout) { // Process all incoming events on sockets // store the data in lists struct epoll_event events[FD_SETSIZE]= {0}; - int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200); + int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout); if ( nfds==-1 ) { - if ( errno==EINTR || errno==EAGAIN ) + if ( errno==EINTR || errno==EAGAIN ) { return false; - else + } else AssertFatal(false,"error in epoll_wait\n"); } @@ -263,7 +388,7 @@ static bool flushInput(rfsimulator_state_t *t) { continue; } - int blockSz; + ssize_t blockSz; if ( b->headerMode) blockSz=b->remainToTransfer; @@ -272,7 +397,7 @@ static bool flushInput(rfsimulator_state_t *t) { b->remainToTransfer : b->circularBufEnd - 1 - b->transferPtr ; - int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT); + ssize_t sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT); if ( sz < 0 ) { if ( errno != EAGAIN ) { @@ -282,6 +407,7 @@ static bool flushInput(rfsimulator_state_t *t) { } else if ( sz == 0 ) continue; + LOG_D(HW, "Socket rcv %zd bytes\n", sz); AssertFatal((b->remainToTransfer-=sz) >= 0, ""); b->transferPtr+=sz; @@ -290,39 +416,44 @@ static bool flushInput(rfsimulator_state_t *t) { // check the header and start block transfer if ( b->headerMode==true && b->remainToTransfer==0) { - AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) || - (t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol"); + AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) || + (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol"); b->headerMode=false; b->alreadyRead=true; if ( b->lastReceivedTS != b->th.timestamp) { int nbAnt= b->th.nbAnt; - for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) - for (int a=0; a < nbAnt; a++) - b->circularBuf[(index*nbAnt+a)%CirSize]=0; + for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { + for (int a=0; a < nbAnt; a++) { + b->circularBuf[(index*nbAnt+a)%CirSize].r=0; + b->circularBuf[(index*nbAnt+a)%CirSize].i=0; + } + } LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); } b->lastReceivedTS=b->th.timestamp; + AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize), + "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS); b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize]; b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt); } if ( b->headerMode==false ) { + LOG_D(HW,"Set b->lastReceivedTS %ld\n", b->lastReceivedTS); b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt); - - if ( b->remainToTransfer==0) { - LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS); - + // First block in UE, resync with the eNB current TS if ( t->nextTimestamp == 0 ) t->nextTimestamp=b->lastReceivedTS-b->th.size; + if ( b->remainToTransfer==0) { + LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS); b->headerMode=true; b->transferPtr=(char *)&b->th; - b->remainToTransfer=sizeof(transferHeader); + b->remainToTransfer=sizeof(samplesBlockHeader_t); b->th.magic=-1; } } @@ -334,10 +465,10 @@ static bool flushInput(rfsimulator_state_t *t) { int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { if (nbAnt != 1) { - LOG_E(HW, "rfsimulator: only 1 antenna tested\n"); - exit(1); + LOG_W(HW, "rfsimulator: only 1 antenna tested\n"); } + pthread_mutex_lock(&Sockmutex); rfsimulator_state_t *t = device->priv; LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); // deliver data from received data @@ -350,13 +481,14 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo if ( first_sock == FD_SETSIZE ) { // no connected device (we are eNB, no UE is connected) - if (!flushInput(t)) { + if (!flushInput(t, 10)) { for (int x=0; x < nbAnt; x++) memset(samplesVoid[x],0,sampleToByte(nsamps,1)); t->nextTimestamp+=nsamps; LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp); *ptimestamp = t->nextTimestamp-nsamps; + pthread_mutex_unlock(&Sockmutex); return nsamps; } } else { @@ -365,12 +497,13 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo do { have_to_wait=false; - for ( int sock=0; sock<FD_SETSIZE; sock++) - if ( t->buf[sock].circularBuf && - t->buf[sock].alreadyRead && //>= t->initialAhead && + for ( int sock=0; sock<FD_SETSIZE; sock++) { + if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead ) + if ( t->buf[sock].lastReceivedTS == 0 || (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) { have_to_wait=true; break; + } } if (have_to_wait) @@ -378,7 +511,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ptr->lastReceivedTS, t->nextTimestamp+nsamps); */ - flushInput(t); + flushInput(t, 3); } while (have_to_wait); } @@ -391,12 +524,20 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo buffer_t *ptr=&t->buf[sock]; if ( ptr->circularBuf && ptr->alreadyRead ) { - for (int a=0; a<nbAnt; a++) { - sample_t *out=(sample_t *)samplesVoid[a]; - - for ( int i=0; i < nsamps; i++ ) - out[i]+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1; - } + bool reGenerateChannel=false; + + //fixme: when do we regenerate + // it seems legacy behavior is: never in UL, each frame in DL + if (reGenerateChannel) + random_channel(ptr->channel_model,0); + + for (int a=0; a<nbAnt; a++) + rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], + a, + ptr->channel_model, + nsamps, + t->nextTimestamp + ); } } @@ -406,10 +547,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo nsamps, *ptimestamp, t->nextTimestamp, signal_energy(samplesVoid[0], nsamps)); + pthread_mutex_unlock(&Sockmutex); return nsamps; } - - int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; @@ -434,10 +574,10 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } - - __attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + // to change the log level, use this on command line + // --log_config.hw_log_level debug //set_log(HW,OAILOG_DEBUG); rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); @@ -446,11 +586,28 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { exit(1); } - rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? - MAGICeNB: - MAGICUE; - LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE"); - device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ? + pthread_mutex_init(&Sockmutex, NULL); + + if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 || + strncasecmp(rfsimulator->ip,"server",3) == 0 ) + rfsimulator->typeStamp = ENB_MAGICDL_FDD; + else + rfsimulator->typeStamp = UE_MAGICDL_FDD; + + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE"); + char *saveF; + + if ((saveF=getenv("saveIQfile")) != NULL) { + rfsimulator->saveIQfile=open(saveF,O_APPEND| O_CREAT|O_TRUNC | O_WRONLY, 0666); + + if ( rfsimulator->saveIQfile != -1 ) + LOG_I(HW,"rfsimulator: will save written IQ samples in %s\n", saveF); + else + LOG_E(HW, "can't open %s for IQ saving (%s)\n", saveF, strerror(errno)); + } else + rfsimulator->saveIQfile = -1; + + device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ? server_start : start_ue; device->trx_get_stats_func = rfsimulator_get_stats; @@ -470,6 +627,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator->buf[i].conn_sock=-1; AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,""); - rfsimulator->initialAhead=openair0_cfg[0].sample_rate/1000; // One sub frame + // initialize channel simulation + rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels; + rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels; + rfsimulator->sample_rate=openair0_cfg->sample_rate; + rfsimulator->tx_bw=openair0_cfg->tx_bw; + randominit(0); + set_taus_seed(0); return 0; } diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c new file mode 100644 index 0000000000000000000000000000000000000000..888b5f6de0d2d1224ed99c0fe34d49f1900b312e --- /dev/null +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -0,0 +1,142 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#include <common/utils/simple_executable.h> + + +void fullwrite(int fd, void *_buf, int count) { + char *buf = _buf; + int l; + + while (count) { + l = write(fd, buf, count); + + if (l <= 0) { + if (errno==EINTR) + continue; + + if(errno==EAGAIN) { + continue; + } else { + AssertFatal(false,"Lost socket\n"); + } + } else { + count -= l; + buf += l; + } + } +} + +int server_start(short port) { + int listen_sock; + AssertFatal((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + int enable = 1; + AssertFatal(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: + htons(port), +sin_addr: + { s_addr: INADDR_ANY } + }; + bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); + AssertFatal(listen(listen_sock, 5) == 0, ""); + return accept(listen_sock,NULL,NULL); +} + +int client_start(char *IP, short port) { + int sock; + AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: + htons(port), +sin_addr: + { s_addr: INADDR_ANY } + }; + addr.sin_addr.s_addr = inet_addr(IP); + bool connected=false; + + while(!connected) { + LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + LOG_I(HW,"rfsimulator: connection established\n"); + connected=true; + } + + perror("simulated node"); + sleep(1); + } + + return sock; +} + +enum blocking_t { + notBlocking, + blocking +}; + +void setblocking(int sock, enum blocking_t active) { + int opts; + AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,""); + + if (active==blocking) + opts = opts & ~O_NONBLOCK; + else + opts = opts | O_NONBLOCK; + + AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); +} + +int main(int argc, char *argv[]) { + if(argc != 4) { + printf("Need parameters: source file, server or destination IP, TCP port\n"); + exit(1); + } + + int fd; + AssertFatal((fd=open(argv[1],O_RDONLY)) != -1, "file: %s", argv[1]); + off_t fileSize=lseek(fd, 0, SEEK_END); + int serviceSock; + + if (strcmp(argv[2],"server")==0) { + serviceSock=server_start(atoi(argv[3])); + } else { + client_start(argv[2],atoi(argv[3])); + } + + samplesBlockHeader_t header; + int bufSize=100000; + void *buff=malloc(bufSize); + + while (1) { + //Rewind the file to loop on the samples + if ( lseek(fd, 0, SEEK_CUR) >= fileSize ) + lseek(fd, 0, SEEK_SET); + + // Read one block and send it + setblocking(serviceSock, blocking); + AssertFatal(read(fd,&header,sizeof(header)), ""); + fullwrite(serviceSock, &header, sizeof(header)); + int dataSize=sizeof(sample_t)*header.size*header.nbAnt; + + if (dataSize>bufSize) + buff=realloc(buff,dataSize); + + AssertFatal(read(fd,buff,dataSize) == dataSize, ""); + fullwrite(serviceSock, buff, dataSize); + // Purge incoming samples + setblocking(serviceSock, notBlocking); + + while(recv(serviceSock,buff, bufSize, MSG_DONTWAIT) > 0) { + } + } + + return 0; +} + diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index f152e7c83dc7ff44ded52925883a7ac686121c47..dd91f540047e7108102f04bb6102216395ce60b7 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -34,9 +34,11 @@ #include "UTIL/OPT/opt.h" #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" +#include <dlfcn.h> static softmodem_params_t softmodem_params; char *parallel_config=NULL; char *worker_config=NULL; +double snr_dB=25; uint64_t get_softmodem_optmask(void) { return softmodem_params.optmask; diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 987db67b00a4084fb1ed951c6fe6766c2bdfc58c..b9a775509dba534ae9a410db1dda70da47328218 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -152,7 +152,6 @@ {"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \ - {"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \ } @@ -201,6 +200,7 @@ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ + {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ @@ -283,6 +283,7 @@ uint64_t get_pdcp_optmask(void); extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; +extern double snr_dB; extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index eb510e5ff21c996b56e2d5c9855152e3a415e0f0..d9b03ac5fdfbfd63bc0cb2cbb40dd9a69decbccd 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -132,8 +132,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int UE_scan = 1; int UE_scan_carrier = 0; -int snr_dB=25; - runmode_t mode = normal_txrx; FILE *input_fd=NULL;