Commit 9371c569 authored by laurent's avatar laurent

merge branch origin/channel-simulation-in-rfsimulator

parents 17d5bcd3 a5b30c07
dev 1 128-ues 256_QAM_demod 512-dataplane-bug-in-l2nfapi_nos1 FR2_NSA Fix_SA_SIB1 NCTU_OpinConnect_LDPC NR-PHY-MAC-IF-multi-UE NRPRACH_highSpeed_saankhya NRUE_usedlschparallel NR_10MHz NR_2port_CSIRS NR_CSIRS_tomerge NR_CSI_reporting NR_DCI_01 NR_DLUL_PF NR_DLUL_PF_4UL NR_DLUL_PF_rebased NR_DL_MIMO NR_DL_sched_fixes NR_DL_scheduler NR_F1C_F1U_extensions NR_FAPI_beamindex_SSB_RO NR_FAPI_beamindex_SSB_RO_SEMPROJ NR_FDD_FIX NR_FR2_RA NR_FR2_RRC_SSB NR_FR2_initsync_fixes NR_MAC_CE_GlobalEdge NR_MAC_Multi_Rach_GlobalEdge NR_MAC_Multi_Rach_GlobalEdge-old NR_MAC_SSB NR_MAC_SSB_RO_GlobalEdge NR_MAC_SSB_RO_UE_IDCC NR_MAC_SSB_RO_merge NR_MAC_TCI_UCI_GlobalEdge NR_MCS_BLER NR_NGAP NR_PUCCH_MultiUE NR_RA_cleanup NR_RA_updates NR_RRCConfiguration_FR2 NR_RRC_PDCP NR_RRC_PRACH_procedures NR_RRC_X2AP_AMBR_Change_Global_edge NR_RRC_X2AP_RemoveHardcodings_GlobalEdge NR_RRC_config_simplified NR_RRC_harq_b NR_SA_F1AP_5GRECORDS NR_SA_F1AP_5GRECORDS-USIM NR_SA_F1AP_5GRECORDS-wf-0623 NR_SA_F1AP_5GRECORDS_lts NR_SA_F1AP_RFSIMULATOR NR_SA_F1AP_RFSIMULATOR2 NR_SA_F1AP_RFSIMULATOR2_SRB NR_SA_F1AP_RFSIMULATOR3 NR_SA_F1AP_RFSIMULATOR3_tmp NR_SA_F1AP_RFSIMULATOR3_wf NR_SA_F1AP_RFSIMULATOR_w5GCN NR_SA_F1AP_dev NR_SA_NGAP_RRC NR_SA_NGAP_RRC_wk42 NR_SA_itti_sim_wk48 NR_SA_itti_sim_wk48_hs NR_SA_itti_sim_wk48_hs1 NR_SA_w5GCN_new_gtpu NR_SCHED_HARQ NR_SCHED_PDCCH_PUCCH_HARQ NR_SCHED_PDCCH_PUCCH_HARQ_rebased NR_SCHED_fixes NR_SRB_Config NR_UE_CONFIG_REQ_FIXES NR_UE_MAC_scheduler NR_UE_PUCCH_bugfixes NR_UE_RA_fixes NR_UE_SA NR_UE_UL_DCI_improvements NR_UE_dlsch_bugfix NR_UE_enable_parallelization NR_UE_rework_test NR_UE_reworking_UCI_procedures NR_UE_stability_fixes NR_UL_FAPI_programming NR_UL_SCFDMA_100MHz NR_UL_scheduler NR_UL_scheduler_rebased NR_UL_scheduling NR_Wireshark NR_beam_simulation NR_cleanup_PUCCH_resources NR_gNB_initial_MIB_fix NR_ipaccess_testing NR_mac_uci_functions_rework NR_msg2_phytest NR_multiplexing_HARQ_CSI_PUCCH NR_phytest_bugfixes NR_reworking_UL_antennaports NR_scheduling_CSIRS NR_scheduling_request NR_scheduling_request2 NR_scheduling_request3 NR_ue_dlsch_dmrs_cdm PBCHNRTCFIX PUSCH_TA_update RA_CI_test RFquality Saankhya_NRPRACH_HighSpeed Test_SA_5GREC UE_DL_DCI_hotfix add-dmrs-test add-ru-docker-image avxllr bandwidth-testing bch-fixes-bitmap benetel_5g_prach_fix benetel_config_file_fix benetel_dpdk20 benetel_driver_uldl_pf_merge benetel_driver_update benetel_fixes benetel_phase_rotation benetel_phase_rotation_old bsr-fix bugfix-free-ra-process bugfix-minor-remove-wrong-log bugfix-nr-bands bugfix-nr-ldpc-post-processing bugfix-nr-ldpc-size-typo bugfix-nr-pdcp-sn-size bugfix-nr-rate-matching-assertion bugfix-nr-t-reordering bugfix-x2-SgNBAdditionRequest bugfix_gnb_rt_stats_html bupt-sa-merge cce_indexing_fix cce_indexing_fix2 ci-deploy-asterix ci-deploy-docker-compose ci-fix-module-ul-iperf ci-new-docker-pipeline ci-rd-july-improvements ci-reduce-nb-vms ci-test ci-ul-iperf-from-trf-container ci_benetel_longrun_limits ci_benetel_test ci_fix_iperf_for_module ci_hotfix_module_ue_ip_address ci_improve_module_ctl ci_nsa_benetel ci_nsa_fixes ci_nsa_pipes_improve ci_nsa_test_integration_2021_wk19 ci_nsa_traces ci_nsa_uplink ci_phytest ci_quectel_support ci_sa_rfsim_test ci_solve_ul_for_module ci_test_5GREC ci_test_nsa_fix_quectel_nic ci_test_nsa_on_develop ci_test_ra_fr2 ci_testinfra_as_code ci_vm_resource_fix clean-5G-scope-round2 cleanup_softmodem_main constant_power debug-UL-5GRECORDS debug_UL_signal detached-w16-test develop develop-CBRA-v3 develop-CCE develop-NR_SA_F1AP_5GRECORDS develop-NR_SA_F1AP_5GRECORDS-abs develop-NR_SA_F1AP_5GRECORDS-hs develop-NR_SA_F1AP_5GRECORDS-hs1 develop-NR_SA_F1AP_5GRECORDS-lts develop-NR_SA_F1AP_5GRECORDS-lts-wf develop-NR_SA_F1AP_5GRECORDS-v3 develop-NR_SA_F1AP_5GRECORDS_100M develop-NR_SA_F1AP_5GRECORDS_LDPC_FPGA develop-NR_SA_F1AP_5GRECORDS_lfq_0607 develop-SA-CBRA develop-SA-CBRA-CUDU develop-SA-CBRA-Msg5 develop-SA-CBRA-lts develop-SA-CBRA-ulsch-lts develop-SA-RA develop-SnT develop-aw2sori develop-oriecpriupdates develop-sib1 develop-sib1-local develop-sib1-lts develop-sib1-update develop-sib1-update-test1 develop-sib1-update-ue develop-wf-du develop_inria_ci_deployment develop_inria_ci_deployment_gp develop_integration_2020_w19 develop_stable dfts_alternatives disable_CSI_measrep dlsch-all-dlslots dlsch_encode_mthread dlsch_parallel docker-improvements-2021-april docker-no-cache-option dongzhanyi-zte-develop dongzhanyi-zte-develop1 dongzhanyi-zte-develop2 enhance-rfsim episys-merge episys/nsa_baseline episys/nsa_development feature/make-s1-mme-port-configurable feature/make-s1-mme-port-configurable-with-astyle-fixes fedora-gen-kernel-fix fembms-enb-ue fft_bench_hotfix finalize-oaicn-integration firas fix-check fix-ci-tun fix-compile fix-itti-segv fix-nr-pdcp-timer fix-nr-rlc-range-nack fix-physim-deploy fix-quectel fix-realtime fix-retransmission-rbg fix-softmodem-restart fix-warnings fix-x2-without-gnb fix_NR_DLUL_PF fix_NR_DLUL_PF_benchmark fix_coreset_dmrs_idx fix_do_ra_data fix_nr_ulsim fix_pdsch_low_prb fix_rb_corruption fix_reestablishment fix_rfsim_mimo fix_rrc_x2_ticking fixes-CE-RLC-PDU-size fixes-mac-sched-nfapi fixes-mac-sched-tun fixes-tun fixgtpu flexran-apps flexran-repair-mme-mgmt flexran-rtc-repo-is-public fujitsu_lte_contribution fujitsu_lte_contribution-128 git-dashboard gnb-freerun-txru gnb-n300-fixes gnb-only-test gnb-realtime-hotfix gnb-realtime-quickfix gnb-threadpool hack-bch-no-sched-sf-0 hack-exit-gnb-when-no-enb-nsa harq-hotfix hotfix-minor-remove-nr-rlc-cppcheck-error hotfix-nr-rlc-tick hotfix-ocp-executable hotfix-ue-musim-compilation improve_nr_modulation improve_ue_stability integ-w13-test-rt-issue integration_2020_wk15 integration_2020_wk40 integration_2020_wk41 integration_2020_wk42_2 integration_2020_wk45 integration_2020_wk45_2 integration_2020_wk46 integration_2020_wk46_2 integration_2020_wk47 integration_2020_wk48 integration_2020_wk48_2 integration_2020_wk49 integration_2020_wk50 integration_2020_wk50_1 integration_2020_wk51 integration_2020_wk51_2 integration_2021_wk02 integration_2021_wk02_wMR988 integration_2021_wk04 integration_2021_wk05 integration_2021_wk06 integration_2021_wk06_MR978 integration_2021_wk06_b integration_2021_wk06_c integration_2021_wk08 integration_2021_wk08_2 integration_2021_wk08_MR963 integration_2021_wk09 integration_2021_wk09_b integration_2021_wk10 integration_2021_wk10_b integration_2021_wk11 integration_2021_wk12 integration_2021_wk12_b integration_2021_wk13_a integration_2021_wk13_b integration_2021_wk13_b_fix_tdas integration_2021_wk13_b_fixed integration_2021_wk13_c integration_2021_wk14_a integration_2021_wk15_a integration_2021_wk16 integration_2021_wk17_a integration_2021_wk17_b integration_2021_wk18_a integration_2021_wk18_b integration_2021_wk19 integration_2021_wk20_a integration_2021_wk22 integration_2021_wk23 integration_2021_wk27 integration_w5GC_CBRA_test inter-RRU-final inter-RRU-oairu inter-rru-UE itti-enhancement ldpc-decoder-codegen ldpc-decoder-codegen2 ldpc-offload ldpc_offload_t1 ldpc_short_codeword_fixes load_gnb lte-ulsch-bugfix lte_uplink_improvement mac-fixes-wk45_2 migrate-cpp-check-container migrate-vm-pipeline-to-bionic minor-fix-doc-basic-sim mosaic5g-oai-ran mosaic5g-oai-sim msg4_phy_0303_lfq multiple_ssb_sib1_bugfix nasmesh_kernel_5.8 new-gtpu nfapi-bugfix nfapi_nr_arch_mod nfapi_nr_develop nfapi_nr_develop_new ngap-dlul ngap-support ngap-w48-merge2 ngap-wf ngap-wf-1120 ngap-wf-1120-srb ngap-wf-1120-srb-gtp ngap-wf-1120-srb-gtp-hs ngap-wf-1120-srb-gtp-hs1 ngap-wf-1120-srb-gtp-hs2 ngap-wf-1120-srb-gtp-yhz ngap-wf-1203-yunsdr ngap-wf-liuyu ngap_lfq_1120 ngap_merge noCore nr-bsr-fix nr-dl-mimo-2layer nr-dmrs-fixes nr-mac-pdu-wireshark nr-mac-remove-ue-list nr-pdcp-benchmarking nr-pdcp-improvements nr-pdcp-nea2-security nr-pdcp-nia2-integrity nr-pdcp-small-bugfixes nr-pdcp-srb-integrity nr-ra-fix nr-rlc-am-bugfix-w44 nr-rlc-bugfix-w44 nr-stats-print nrPBCHTCFix nrPbchTcFix nrUE nrUE-hs nrUE-upper-layer nr_bsr nr_dl_dmrs_type2 nr_dl_pf nr_dl_pf2 nr_dl_ul_ptrs nr_fdd_if_fix nr_improve_chanest nr_polar_decoder_improvement nr_power_measurement_fixes nr_prach_fr2 nr_ue_msg3 nr_ue_pdcp_fix nr_ue_tti_cleanup nr_ul_pf nr_ul_scfdma nrue_msg2_reception nsa-ue nsa_remove_band_hardcodings oai-sim oairu oairu-dockerfile-support oc-docker-october-improvements openxg/develop pdcp-benchmark phy-asan-fixes physim-build-deploy physim-deploy-handle-error-cases polar8 prb_based_dl_channel_estimation ptrs_rrc_config pusch-mthread-scaling-fix pusch-retrans-fix-ue ra-dl-ul recursive-cmake remove_nos1_hack_pdcp remove_x2_gnb_hardcoding repair-TA revert_memcpy rh-ci-add-ue-parallelization rh_ci_add_runtime_stats rh_ci_add_uldlharq_stats rh_ci_fix_autoterminate rh_ci_fr1_update rh_ci_gsheet_rt_monitoring rh_ci_nsa2jenkins rh_ci_nsa_test_n310 rh_ci_oc rh_ci_phy_test_improve rh_ci_py rh_ci_ra_fr2 rh_ci_rfsim_ra rh_ci_test_benetel rh_ci_test_nsa rh_ci_test_nsa_wk16 rh_ci_test_nsa_wk17_b rh_ci_test_nsa_wk17b rh_ci_test_rfsim_sa rh_ci_ue_parallel rh_doc_update_3 rh_fr1_newjenkins rh_fr1_update rh_gnb_compile_fix rh_wk50_debug rlc-v2-bugfix-status-reporting rlc-v2-tick rlc_v2_coverity_fixes rohan_ulsim2RxFix rrc-enb-phy-testmode s1-subnormal_rewrite s1_subnormal s1_subnormal-robert s1ap-bugfix-rab_setup sa-demo sa-demo-hs sa-merge-rrc-srb sa-msg4 sa-msg4-rrc sa-msg4-rrc-yihz sa-msg4-rrc-yihz-hs sa_rrc_yihz sanitize-address sanitize-v1 sanitize-v1-tmp sarma_pvnp_oai scs_60_iisc sim-channels small-bugfixes-w40 small-config-change small_nr_bugfixes smallcleanup split73 t-gnb-tracer test-5GREC test-nsa-benetel test-panos test_nsa_gtpu_fix test_rt-fix_phy-test testing_2symb_pdcch testing_with_external_txdata tp-ota-test trx_thread_param ue-csi ue-dci-false-detection ue-fixes ue-fixes-ota ue-pdsch-pusch-parallel ue-race-fix ue_beam_selection ul-freq-iq-samps-to-file ul_dl_dci_same_slot ul_harq ulsch_decode_mthread ulsim_changes usrp_fix_adc_shift_and_pps_sync usrp_stop_cleanly usrp_x400 wf-sa-rrc wf_testc wireshark-T-hack-ueid wireshark-log-scheduling-requests wk11-with-phytest x2-endc-processing x2_handle_sctp_shutdown xiangwab xiangwan xw2 yihongzheng_srb zzs 2021.wk14_a 2021.wk13_d 2021.wk13_c 2021.w27 2021.w26 2021.w25 2021.w24 2021.w23 2021.w22 2021.w20 2021.w19 2021.w18_b 2021.w18_a 2021.w17_b 2021.w16 2021.w15 2021.w14 2021.w13_a 2021.w12 2021.w11 2021.w10 2021.w09 2021.w08 2021.w06 2021.w05 2021.w04 2021.w02 2020.w51_2 2020.w51 2020.w50 2020.w49 2020.w48_2 2020.w48 2020.w47 2020.w46_2 2020.w46 2020.w45_2 2020.w45 2020.w44 2020.w42_2 2020.w42 2020.w41 2020.w39 2020.w38 2020.w37 2020.w36 2020.w34 2020.w33 2020.w31 2020.w30 2020.w29 2020.w28 2020.w26 2020.w25 2020.w24 2020.w23 2020.w22 2020.w19 2020.w17 benetel_phase_rotation benetel_gnb_rel_2.0 benetel_gnb_rel_1.0 benetel_enb_rel_2.0 benetel_enb_rel_1.0
No related merge requests found
...@@ -519,6 +519,9 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4 ...@@ -519,6 +519,9 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4
add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU") add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU")
if (NOT ${RF_BOARD} STREQUAL "None")
add_definitions(-DMANAGED_RF=1)
endif()
add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET") add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
...@@ -627,8 +630,6 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE ...@@ -627,8 +630,6 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
add_library(tcp_bridge_oai MODULE ${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") set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c)
########################################################## ##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
...@@ -2010,6 +2011,11 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_ ...@@ -2010,6 +2011,11 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_
target_link_libraries(enbscope ${XFORMS_LIBRARIES}) target_link_libraries(enbscope ${XFORMS_LIBRARIES})
target_link_libraries(uescope ${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}") 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 #include T directory even if the T is off because T macros are in the code
...@@ -2053,6 +2059,25 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) ...@@ -2053,6 +2059,25 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
################################# #################################
# add executables for operation # 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 # lte-softmodem is both eNB and UE implementation
################################################### ###################################################
......
...@@ -450,7 +450,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { ...@@ -450,7 +450,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double)); config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double));
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
*(cfgoptions->u64ptr)=cfgoptions->defdblval; *(cfgoptions->dblptr)=cfgoptions->defdblval;
status=1; status=1;
printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr));
} }
......
int T_stdout;
void exit_function(const char *file, const char *function, const int line, const char *s) {
}
#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
...@@ -42,35 +42,35 @@ ...@@ -42,35 +42,35 @@
int set_device(openair0_device *device) { int set_device(openair0_device *device) {
switch (device->type) { switch (device->type) {
case EXMIMO_DEV: 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; break;
case USRP_B200_DEV: 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; break;
case USRP_X300_DEV: 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; break;
case BLADERF_DEV: 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; break;
case LMSSDR_DEV: 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; break;
case IRIS_DEV: 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; break;
case NONE_DEV: 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; break;
default: 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; return -1;
} }
...@@ -80,17 +80,17 @@ int set_device(openair0_device *device) { ...@@ -80,17 +80,17 @@ int set_device(openair0_device *device) {
int set_transport(openair0_device *device) { int set_transport(openair0_device *device) {
switch (device->transp_type) { switch (device->transp_type) {
case ETHERNET_TP: case ETHERNET_TP:
printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); LOG_I(HW,"[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0; return 0;
break; break;
case NONE_TP: case NONE_TP:
printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); LOG_I(HW,"[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0; return 0;
break; break;
default: 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; return -1;
break; break;
} }
...@@ -119,7 +119,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param ...@@ -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); ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
if (ret < 0) { 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 { } else {
ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); 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 ...@@ -135,7 +135,7 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf
if ( rc >= 0) { if ( rc >= 0) {
if ( set_device(device) < 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; return -1;
} }
} }
...@@ -149,7 +149,7 @@ int openair0_transport_load(openair0_device *device, openair0_config_t *openair0 ...@@ -149,7 +149,7 @@ int openair0_transport_load(openair0_device *device, openair0_config_t *openair0
if ( rc >= 0) { if ( rc >= 0) {
if ( set_transport(device) < 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; return -1;
} }
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#define COMMON_LIB_H #define COMMON_LIB_H
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <openair1/PHY/TOOLS/tools_defs.h>
/* name of shared library implementing the radio front end */ /* name of shared library implementing the radio front end */
#define OAI_RF_LIBNAME "oai_device" #define OAI_RF_LIBNAME "oai_device"
...@@ -83,9 +84,6 @@ typedef enum { ...@@ -83,9 +84,6 @@ typedef enum {
*/ */
/*!\brief RF device types /*!\brief RF device types
*/ */
#ifdef OCP_FRAMEWORK
#include <enums.h>
#else
typedef enum { typedef enum {
MIN_RF_DEV_TYPE = 0, MIN_RF_DEV_TYPE = 0,
/*!\brief device is ExpressMIMO */ /*!\brief device is ExpressMIMO */
...@@ -109,7 +107,6 @@ typedef enum { ...@@ -109,7 +107,6 @@ typedef enum {
MAX_RF_DEV_TYPE MAX_RF_DEV_TYPE
} dev_type_t; } dev_type_t;
#endif
/*!\brief transport protocol types /*!\brief transport protocol types
*/ */
...@@ -218,14 +215,6 @@ typedef struct { ...@@ -218,14 +215,6 @@ typedef struct {
int iq_rxrescale; int iq_rxrescale;
//! Configuration file for LMS7002M //! Configuration file for LMS7002M
char *configFilename; char *configFilename;
//! remote IP/MAC addr for Ethernet interface
char *remote_addr;
//! remote port number for Ethernet interface
unsigned int remote_port;
//! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
char *my_addr;
//! local port number for Ethernet interface (eNB/BBU, UE)
unsigned int my_port;
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
unsigned short sf_mode; // 1=record, 2=replay unsigned short sf_mode; // 1=record, 2=replay
char sf_filename[1024]; // subframes file path char sf_filename[1024]; // subframes file path
...@@ -235,13 +224,6 @@ typedef struct { ...@@ -235,13 +224,6 @@ typedef struct {
unsigned int sf_write_delay; // write delay in replay mode unsigned int sf_write_delay; // write delay in replay mode
unsigned int eth_mtu; // ethernet MTU unsigned int eth_mtu; // ethernet MTU
#endif #endif
//! number of samples per tti
unsigned int samples_per_tti;
//! the sample rate for receive.
double rx_sample_rate;
//! the sample rate for transmit.
double tx_sample_rate;
} openair0_config_t; } openair0_config_t;
/*! \brief RF mapping */ /*! \brief RF mapping */
...@@ -415,7 +397,7 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_ ...@@ -415,7 +397,7 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) #define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
#define sample_t uint32_t // 2*16 bits complex number #define sample_t struct complex16 // 2*16 bits complex number
typedef struct { typedef struct {
uint64_t magic; // Magic value (see defines above) uint64_t magic; // Magic value (see defines above)
...@@ -452,7 +434,7 @@ openair0_timestamp get_usrp_time(openair0_device *device); ...@@ -452,7 +434,7 @@ openair0_timestamp get_usrp_time(openair0_device *device);
* \returns 0 in success * \returns 0 in success
*/ */
int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg); int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg);
#define gettid() syscall(__NR_gettid)
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
......
## General #General
This is a RF simulator that allows to test OAI without a RF board. This is a RF simulator that allows to test OAI without a RF board.
It replaces a actual RF board driver. 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) 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 After any regular build, you can compile the driver
```bash ```bash
cd <the_compilation_dir_from_bouild_oai_script>/build cd <the_compilation_dir_from_bouild_oai_script>/build
...@@ -18,35 +30,21 @@ Then, you can use it freely ...@@ -18,35 +30,21 @@ Then, you can use it freely
# Usage # Usage
Setting the env variable RFSIMULATOR enables the RF board simulator 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 ## 4G case
For the UE, it should be set to the IP address of the eNB For the UE, it should be set to the IP address of the eNB
example: example:
```bash ```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 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 If you reach 'RA not active' on UE, be careful to generate a valid SIM
```bash ```bash
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . $OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
``` ```
This simulator can also be used with the `--noS1` option, in this case you must run the eNodeB and the UE on different PCs.
## 5G case ## 5G case
After regular build, add the simulation driver After regular build, add the simulation driver
(don't use ./build_oai -w SIMU until we merge 4G and 5G branches) (don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
```bash ```bash
...@@ -55,7 +53,7 @@ make rfsimulator ...@@ -55,7 +53,7 @@ make rfsimulator
``` ```
### Launch gNB in one window ### Launch gNB in one window
```bash ```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 ### Launch UE in another window
```bash ```bash
...@@ -64,8 +62,40 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 ...@@ -64,8 +62,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 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 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
\ No newline at end of file
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
copyleft: OpenAirInterface Software Alliance and it's licence copyleft: OpenAirInterface Software Alliance and it's licence
*/ */
/*
* Open issues and limitations
* The read and write should be called in the same thread, that is not new USRP UHD design
* When the opposite side switch from passive reading to active R+Write, the synchro is not fully deterministic
*/
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
...@@ -21,61 +27,175 @@ ...@@ -21,61 +27,175 @@
#include "common_lib.h" #include "common_lib.h"
#include <openair1/PHY/defs_eNB.h> #include <openair1/PHY/defs_eNB.h>
#include "openair1/PHY/defs_UE.h" #include "openair1/PHY/defs_UE.h"
#include <openair1/SIMULATION/TOOLS/sim.h>
#define PORT 4043 //TCP port for this simulator #define PORT 4043 //TCP port for this simulator
#define CirSize 3072000 // 100ms is enough #define CirSize 3072000 // 100ms is enough
#define MaxBlock 30000
#define sample_t uint32_t // 2*16 bits complex number
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
#define sample_t uint32_t // 2*16 bits complex number #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 { typedef struct buffer_s {
int conn_sock; int conn_sock;
bool readEnabled; bool alreadyRead;
uint64_t lastReceivedTS; uint64_t lastReceivedTS;
uint64_t lastWroteTS;
bool headerMode; bool headerMode;
samplesBlockHeader_t th; samplesBlockHeader_t th;
char *transferPtr; char *transferPtr;
uint64_t remainToTransfer; uint64_t remainToTransfer;
int nbAnt; char *circularBufEnd;
sample_t *circularBuf; sample_t *circularBuf;
channel_desc_t *channel_model;
} buffer_t; } buffer_t;
typedef struct { typedef struct {
int listen_sock, epollfd; int listen_sock, epollfd;
uint64_t nextTimestamp; uint64_t nextTimestamp;
uint64_t typeStamp; uint64_t typeStamp;
uint64_t initialAhead;
char *ip; char *ip;
int saveIQfile; int saveIQfile;
buffer_t buf[FD_SETSIZE]; buffer_t buf[FD_SETSIZE];
int rx_num_channels;
int tx_num_channels;
double sample_rate;
double tx_bw;
} rfsimulator_state_t; } 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));
printf("in: %d, out %d= %f*%f + %f*%f\n",
input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , 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) { void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
buffer_t *ptr=&bridge->buf[sock]; buffer_t *ptr=&bridge->buf[sock];
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
ptr->conn_sock=sock; ptr->conn_sock=sock;
ptr->alreadyRead=false;
ptr->lastReceivedTS=0;
ptr->headerMode=true; ptr->headerMode=true;
ptr->transferPtr=(char *)&ptr->th; ptr->transferPtr=(char *)&ptr->th;
ptr->remainToTransfer=sizeof(samplesBlockHeader_t); ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
int sendbuff=1000*1000*10; int sendbuff=1000*1000*10;
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
int tcp_maxseg = 1400;
AssertFatal ( setsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, &tcp_maxseg,sizeof(tcp_maxseg)) == 0, "");
struct epoll_event ev= {0}; struct epoll_event ev= {0};
ev.events = EPOLLIN | EPOLLRDHUP; ev.events = EPOLLIN | EPOLLRDHUP;
ev.data.fd = sock; ev.data.fd = sock;
AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, ""); 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) { void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
close(sock); close(sock);
free(bridge->buf[sock].circularBuf); 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)); memset(&bridge->buf[sock], 0, sizeof(buffer_t));
bridge->buf[sock].conn_sock=-1; bridge->buf[sock].conn_sock=-1;
} }
...@@ -90,7 +210,6 @@ void socketError(rfsimulator_state_t *bridge, int sock) { ...@@ -90,7 +210,6 @@ void socketError(rfsimulator_state_t *bridge, int sock) {
} }
} }
#define helpTxt "\ #define helpTxt "\
\x1b[31m\ \x1b[31m\
rfsimulator: error: you have to run one UE and one eNB\n\ rfsimulator: error: you have to run one UE and one eNB\n\
...@@ -115,16 +234,18 @@ void setblocking(int sock, enum blocking_t active) { ...@@ -115,16 +234,18 @@ void setblocking(int sock, enum blocking_t active) {
AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); 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, int count, rfsimulator_state_t *t) { void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
if (t->saveIQfile != -1) { if (t->saveIQfile != -1) {
if (write(t->saveIQfile, _buf, count) != count ) if (write(t->saveIQfile, _buf, count) != count )
LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno)); LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno));
} }
AssertFatal(fd>=0 && _buf && count >0 && t,
"Bug: %d/%p/%zd/%p", fd, _buf, count, t);
char *buf = _buf; char *buf = _buf;
int l; ssize_t l;
setblocking(fd, notBlocking); setblocking(fd, notBlocking);
while (count) { while (count) {
...@@ -135,7 +256,9 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { ...@@ -135,7 +256,9 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
continue; continue;
if(errno==EAGAIN) { if(errno==EAGAIN) {
flushInput(t); // The opposite side is saturated
// we read incoming sockets meawhile waiting
flushInput(t, 5);
continue; continue;
} else } else
return; return;
...@@ -199,109 +322,56 @@ sin_addr: ...@@ -199,109 +322,56 @@ sin_addr:
setblocking(sock, notBlocking); setblocking(sock, notBlocking);
allocCirBuf(t, sock); allocCirBuf(t, sock);
t->buf[sock].readEnabled=true; // UE will start blocking on read t->buf[sock].alreadyRead=true; // UE will start blocking on read
return 0; return 0;
} }
uint64_t lwrote; uint64_t lastW=-1;
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
rfsimulator_state_t *t = device->priv; rfsimulator_state_t *t = device->priv;
// We do small blocks because the UE and the eNB are not aligned LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
// So large blocks can lead to deadlock (each side waits a incoming block completed)
int curBeg=0;
do {
int sizeToSend=min(nsamps-curBeg,MaxBlock);
for (int i=0; i<FD_SETSIZE; i++) { for (int i=0; i<FD_SETSIZE; i++) {
buffer_t *ptr=&t->buf[i]; buffer_t *ptr=&t->buf[i];
if (ptr->conn_sock >= 0 ) { if (ptr->conn_sock >= 0 ) {
samplesBlockHeader_t header= {t->typeStamp, sizeToSend, nbAnt, timestamp+curBeg}; samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
fullwrite(ptr->conn_sock,&header, sizeof(header), t); fullwrite(ptr->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[sizeToSend][nbAnt]; sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; a<nbAnt; a++) { for(int a=0; a<nbAnt; a++) {
sample_t *in=((sample_t *)samplesVoid[a]) + curBeg; sample_t *in=(sample_t *)samplesVoid[a];
for(int s=0; s<sizeToSend; s++) for(int s=0; s<nsamps; s++)
tmpSamples[s][a]=in[s]; tmpSamples[s][a]=in[s];
}
if (ptr->conn_sock >= 0 ) {
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(sizeToSend,nbAnt), t);
ptr->lastWroteTS=timestamp+curBeg+sizeToSend;
}
} }
}
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
sizeToSend, timestamp+curBeg, timestamp+curBeg+sizeToSend,
signal_energy(samplesVoid[0]+curBeg, sizeToSend) );
curBeg+=sizeToSend;
} while ( curBeg < nsamps ) ;
return nsamps;
}
static void oneTransferDone(rfsimulator_state_t *t, buffer_t *b) { if (ptr->conn_sock >= 0 )
// check the header and start block transfer fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
if ( b->headerMode==true) {
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;
if ( b->lastReceivedTS != b->th.timestamp && b->readEnabled && b->lastReceivedTS ) {
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;
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
} }
if ( b->readEnabled && b->lastReceivedTS && b->lastWroteTS)
AssertFatal( fabs((double)b->lastReceivedTS - (double)b->lastWroteTS) < (double)CirSize,
"Difference between Rx/Tx timestamps impossible, Rx: %lu, T:%lu\n",
b->lastReceivedTS, b->lastWroteTS);
else
printf("diff: %f\n", abs((double)b->lastReceivedTS - (double)b->lastWroteTS)/1000.0);
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
} else {
LOG_I(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
// in NB case, the UE started to write, since this event, we will wait it's data
// This is needed because the UE doesn't write in initial sync mode
// in UE case, the UE is already in this state (at connection time)
b->readEnabled=true;
b->lastReceivedTS=b->th.timestamp+b->th.size;
// First block in UE, resync with the eNB current TS
if ( t->nextTimestamp == 0 ) {
t->nextTimestamp=b->lastReceivedTS-b->th.size;
LOG_I(HW,"Ue synchro on NB timestamp: %lu\n", t->nextTimestamp);
}
b->headerMode=true;
b->transferPtr=(char *)&b->th;
b->remainToTransfer=sizeof(samplesBlockHeader_t);
b->th.magic=-1;
} }
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 // Process all incoming events on sockets
// store the data in lists // store the data in lists
struct epoll_event events[FD_SETSIZE]= {0}; struct epoll_event events[FD_SETSIZE]= {0};
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 2); int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout);
if ( nfds==-1 ) { if ( nfds==-1 ) {
if ( errno==EINTR || errno==EAGAIN ) if ( errno==EINTR || errno==EAGAIN ) {
return false; return false;
else } else
AssertFatal(false,"error in epoll_wait\n"); AssertFatal(false,"error in epoll_wait\n");
} }
...@@ -327,17 +397,16 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -327,17 +397,16 @@ static bool flushInput(rfsimulator_state_t *t) {
continue; continue;
} }
int blockSz; ssize_t blockSz;
char * circularBufEnd=((char *)b->circularBuf)+sampleToByte(CirSize,1);
if ( b->headerMode) if ( b->headerMode)
blockSz=b->remainToTransfer; blockSz=b->remainToTransfer;
else else
blockSz= b->transferPtr+b->remainToTransfer < circularBufEnd ? blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ?
b->remainToTransfer : b->remainToTransfer :
circularBufEnd - 1 - b->transferPtr ; 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 ( sz < 0 ) {
if ( errno != EAGAIN ) { if ( errno != EAGAIN ) {
...@@ -347,14 +416,55 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -347,14 +416,55 @@ static bool flushInput(rfsimulator_state_t *t) {
} else if ( sz == 0 ) } else if ( sz == 0 )
continue; continue;
LOG_D(HW, "Socket rcv %zd bytes\n", sz);
AssertFatal((b->remainToTransfer-=sz) >= 0, ""); AssertFatal((b->remainToTransfer-=sz) >= 0, "");
b->transferPtr+=sz; b->transferPtr+=sz;
if (b->transferPtr==circularBufEnd - 1) if (b->transferPtr==b->circularBufEnd - 1)
b->transferPtr=(char *)b->circularBuf; b->transferPtr=(char *)b->circularBuf;
if ( b->remainToTransfer==0) { // check the header and start block transfer
oneTransferDone(t,b); if ( b->headerMode==true && b->remainToTransfer==0) {
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].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);
// 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(samplesBlockHeader_t);
b->th.magic=-1;
}
} }
} }
} }
...@@ -364,10 +474,10 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -364,10 +474,10 @@ static bool flushInput(rfsimulator_state_t *t) {
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
if (nbAnt != 1) { if (nbAnt != 1) {
LOG_E(HW, "rfsimulator: only 1 antenna tested\n"); LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
exit(1);
} }
pthread_mutex_lock(&Sockmutex);
rfsimulator_state_t *t = device->priv; 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); LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
// deliver data from received data // deliver data from received data
...@@ -380,13 +490,14 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -380,13 +490,14 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
if ( first_sock == FD_SETSIZE ) { if ( first_sock == FD_SETSIZE ) {
// no connected device (we are eNB, no UE is connected) // no connected device (we are eNB, no UE is connected)
if (!flushInput(t)) { if (!flushInput(t, 10)) {
for (int x=0; x < nbAnt; x++) for (int x=0; x < nbAnt; x++)
memset(samplesVoid[x],0,sampleToByte(nsamps,1)); memset(samplesVoid[x],0,sampleToByte(nsamps,1));
t->nextTimestamp+=nsamps; t->nextTimestamp+=nsamps;
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp); LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
*ptimestamp = t->nextTimestamp-nsamps; *ptimestamp = t->nextTimestamp-nsamps;
pthread_mutex_unlock(&Sockmutex);
return nsamps; return nsamps;
} }
} else { } else {
...@@ -395,20 +506,21 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -395,20 +506,21 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
do { do {
have_to_wait=false; have_to_wait=false;
for ( int sock=0; sock<FD_SETSIZE; sock++) for ( int sock=0; sock<FD_SETSIZE; sock++) {
if ( t->buf[sock].circularBuf && if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead )
t->buf[sock].readEnabled && if ( t->buf[sock].lastReceivedTS == 0 ||
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) { (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
have_to_wait=true; have_to_wait=true;
break; break;
} }
}
if (have_to_wait) if (have_to_wait)
/*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n", /*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n",
ptr->lastReceivedTS, ptr->lastReceivedTS,
t->nextTimestamp+nsamps); t->nextTimestamp+nsamps);
*/ */
flushInput(t); flushInput(t, 3);
} while (have_to_wait); } while (have_to_wait);
} }
...@@ -416,17 +528,25 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -416,17 +528,25 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
for (int a=0; a<nbAnt; a++) for (int a=0; a<nbAnt; a++)
memset(samplesVoid[a],0,sampleToByte(nsamps,1)); memset(samplesVoid[a],0,sampleToByte(nsamps,1));
// Add all input signal in the output buffer // Add all input nodes signal in the output buffer
for (int sock=0; sock<FD_SETSIZE; sock++) { for (int sock=0; sock<FD_SETSIZE; sock++) {
buffer_t *ptr=&t->buf[sock]; buffer_t *ptr=&t->buf[sock];
if ( ptr->circularBuf && ptr->readEnabled ) { if ( ptr->circularBuf && ptr->alreadyRead ) {
for (int a=0; a<nbAnt; a++) { bool reGenerateChannel=false;
sample_t *out=(sample_t *)samplesVoid[a];
//fixme: when do we regenerate
for ( int i=0; i < nsamps; i++ ) // it seems legacy behavior is: never in UL, each frame in DL
out[i]+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1; 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
);
} }
} }
...@@ -436,10 +556,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -436,10 +556,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
nsamps, nsamps,
*ptimestamp, t->nextTimestamp, *ptimestamp, t->nextTimestamp,
signal_energy(samplesVoid[0], nsamps)); signal_energy(samplesVoid[0], nsamps));
pthread_mutex_unlock(&Sockmutex);
return nsamps; return nsamps;
} }
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
abort(); abort();
return 0; return 0;
...@@ -464,11 +583,11 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf ...@@ -464,11 +583,11 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf
int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
return 0; return 0;
} }
__attribute__((__visibility__("default"))) __attribute__((__visibility__("default")))
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
set_log(HW,OAILOG_DEBUG); // to change the log level, use this on command line
// --log_config.hw_log_level debug
// (for phy layer, replace "hw" by "phy"
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) { if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) {
...@@ -476,10 +595,15 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -476,10 +595,15 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
exit(1); exit(1);
} }
rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? pthread_mutex_init(&Sockmutex, NULL);
ENB_MAGICDL_FDD:
UE_MAGICDL_FDD; if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 ||
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "eNB" : "UE"); 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; char *saveF;
if ((saveF=getenv("saveIQfile")) != NULL) { if ((saveF=getenv("saveIQfile")) != NULL) {
...@@ -512,6 +636,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -512,6 +636,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->buf[i].conn_sock=-1; rfsimulator->buf[i].conn_sock=-1;
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -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; return 0;
} }
/*
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;
}
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
static softmodem_params_t softmodem_params; static softmodem_params_t softmodem_params;
char *parallel_config=NULL; char *parallel_config=NULL;
char *worker_config=NULL; char *worker_config=NULL;
double snr_dB=25;
uint64_t get_softmodem_optmask(void) { uint64_t get_softmodem_optmask(void) {
return softmodem_params.optmask; return softmodem_params.optmask;
......
...@@ -150,7 +150,6 @@ ...@@ -150,7 +150,6 @@
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \ {"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}, \ {"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}, \ {"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}, \ {"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} \ {"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \
} }
...@@ -197,6 +196,7 @@ ...@@ -197,6 +196,7 @@
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"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}, \ {"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_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}, \ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
...@@ -277,6 +277,7 @@ uint64_t get_pdcp_optmask(void); ...@@ -277,6 +277,7 @@ uint64_t get_pdcp_optmask(void);
extern pthread_cond_t sync_cond; extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex; extern pthread_mutex_t sync_mutex;
extern int sync_var; extern int sync_var;
extern double snr_dB;
extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
......
...@@ -131,7 +131,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; ...@@ -131,7 +131,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
int UE_scan = 1; int UE_scan = 1;
int UE_scan_carrier = 0; int UE_scan_carrier = 0;
int snr_dB=25;
runmode_t mode = normal_txrx; runmode_t mode = normal_txrx;
...@@ -810,7 +809,7 @@ int main( int argc, char **argv ) { ...@@ -810,7 +809,7 @@ int main( int argc, char **argv ) {
//p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
if (IS_SOFTMODEM_SIML1 ) { if (IS_SOFTMODEM_SIML1 ) {
init_ocm((double)snr_dB,0); init_ocm(snr_dB,0);
PHY_vars_UE_g[0][0]->no_timing_correction = 1; PHY_vars_UE_g[0][0]->no_timing_correction = 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment