Commit 082dff13 authored by navid's avatar navid

* add RF interface to the rrh gateway

* update the openair0_init for all targets
* add a tuning function for the ethernet



git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7830 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 471efb41
dev 1 128-ues 207-feature-ued-platform-support 256_QAM_demod 2cw_fairRRscd 340-fix-beamforming-for-multiple-antenna 342-isip-pcie-lib 375-syrtem-sdr-platform 383-ulsch-scheduler-optimization 387-fraunhofer-iis-transmission-mode-4 401-bug-related-to-nr-pucch-format-2-generator 408-reworked 408-ue-main-threads 445-LDPC-implementation-on-GPU 459-pusch-based-ta-updates 464-ru_beamforming_in_gpu 464-ru_beamforming_in_gpu-CPUsubfunction 472-add-pusch-dmrs-modes 481-ldpc-decoder-on-gpu 5g_fapi_scf Fix_SA_SIB1 LTE-sidelink LTE_TRX_on_single_port NCTU_CS_ISIP NCTU_CS_ISIP_CPU NCTU_CS_ISIP_GPU NCTU_OpinConnect_LDPC NR-PHY-MAC-IF-multi-UE NRPRACH_highSpeed_saankhya NRUE_usedlschparallel NR_10MHz 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_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_PDCP_noS1 NR_PUCCH_MultiUE NR_RA_cleanup NR_RA_updates NR_RRCConfiguragion_FR2 NR_RRCConfiguration NR_RRCConfiguration_FR2 NR_RRCConfiguration_S1U NR_RRCConfiguration_merge_develop NR_RRCConfiguration_sync_source NR_RRCConfiguration_trx_thread NR_RRC_CP_bugfix NR_RRC_PDCP NR_RRC_PRACH_procedures NR_RRC_PRACH_procedures_todevelop NR_RRC_PUSCH NR_RRC_TA NR_RRC_X2AP_AMBR_Change_Global_edge NR_RRC_X2AP_RemoveHardcodings_GlobalEdge NR_RRC_config_simplified NR_RRC_harq NR_RRC_harq_b NR_RRC_harq_hacks NR_RRC_harq_newdcipdu NR_SA_F1AP_5GRECORDS 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 NR_SCHED_HARQ NR_SCHED_PDCCH_PUCCH_HARQ NR_SCHED_PDCCH_PUCCH_HARQ_rebased NR_SCHED_fixes NR_SRB_Config NR_TRX_on_single_port NR_TRX_on_single_port2 NR_UE_CONFIG_REQ_FIXES NR_UE_MAC_scheduler NR_UE_RA_fixes NR_UE_SA NR_UE_UL_DCI_improvements NR_UE_dlsch_bugfix NR_UE_enable_parallelization 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_beamforming_test NR_gNB_SCF_Indication NR_ipaccess_testing NR_mac_uci_functions_rework NR_msg2_phytest NR_scheduling_CSIRS NR_scheduling_request NR_scheduling_request2 NR_scheduling_request3 NR_test_S1U_RRC_PRACH_procedures NR_ue_dlsch_dmrs_cdm New-Merge-sidelink-develop OpInConnect_ISIP PBCHNRTCFIX PUSCH_TA_update PerfumeOldTdd RA_CI_test RFquality RRC-measurements-merge2develop Saankhya_NRPRACH_HighSpeed UE_DL_DCI_hotfix UpdateRANRemoteUEReport add-dmrs-test add_iris_hw addoptions_nr_USRPdevice bch-fixes-bitmap benetel_5g_prach_fix benetel_config_file_fix benetel_driver_uldl_pf_merge benetel_driver_update benetel_fixes benetel_phase_rotation benetel_phase_rotation_old block_mmse_receiver_with_whitenning bsr-fix bugfix-find-uci 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-pdcch_order bugfix-x2-SgNBAdditionRequest bupt-sa-merge cce_indexing_fix cce_indexing_fix2 ci-deploy-asterix ci-deploy-docker-compose ci-new-docker-pipeline ci-rd-july-improvements ci-reduce-nb-vms ci-test ci-ul-iperf-from-trf-container ci-yacine ci_benetel_test ci_phytest ci_quectel_support ci_test_ra_fr2 ci_vm_resource_fix clean-5G-scope-round2 cleanup_softmodem_main constant_power container_fix container_v1.2.2 debug_branch_init_sync develop develop-CBRA-v3 develop-FeMBMS develop-NR_SA_F1AP_5GRECORDS develop-NR_SA_F1AP_5GRECORDS-v3 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-aarch64build develop-ci develop-ci-fju develop-large-scale-emulations develop-m2ap develop-multi-RRUs develop-nb-iot develop-nb-iot-RRC develop-nb-iot-merge develop-nb-iot-merge-w-conflicts develop-nb-iot-ntust develop-nr develop-nr-adding-2018-09-asn1 develop-nr-fr2 develop-nr-fr2-rework develop-nr_cppcheck develop-oriecpriupdates develop-sib1 develop-sib1-local develop-sib1-lts develop-sib1-update develop-sib1-update-test1 develop-sib1-update-ue develop-sidekiq develop-vco3 develop_ci develop_inria_ci_deployment develop_inria_ci_deployment_gp develop_inria_ci_deployment_gp_b4merge develop_integration_2019_w44 develop_integration_2020_w15 develop_integration_2020_w19 develop_integration_w08 develop_jenkins_replay develop_stable dfts_alternatives disable_CSI_measrep dlsch-all-dlslots dlsch_encode_mthread dlsch_parallel dlsim-autotests docker-improvements-2021-april docker-no-cache-option documentation docupdate_tools dongzhanyi-zte-0001 dongzhanyi-zte-develop dongzhanyi-zte-develop2 dreibh/apt-auth-fix dreibh/device-load-fix dreibh/device-load-fix-develop-branch dreibh/doxygen-fix dual-connectivity dummy edrx enhance-rfsim enhancement-149-iqtxshift episys-merge episys/nsa_development extend_sharedlibusage extend_sharedlibusage2 fapi_for_dmrs_and_ptrs feat-mac-sock feature-15-carrier_aggregation feature-21-TM7 feature-230-tm3_scheduler feature-247-tm89 feature-247-tm89-fixes feature-247-tm89-rebased feature-278-physical-layer-GPU-version feature-309-phy_procedures_eNB_TX_split_to_multi_threading feature-31-ff-scheduler-api feature-330-turbo_decoder_gpu feature-368-channel-simulator feature-39-X2-handover feature-4g-sched feature-68-enb-agent feature-flexran-cm-s1ap feature-nr-4g-nfapi-modifications feature-pdcp-task feature-send-rrc-message-for-wireshark-logging feature-support-clang-format feature/make-s1-mme-port-configurable feature/make-s1-mme-port-configurable-with-astyle-fixes feature_tm3 fembms-enb-ue fft_bench_hotfix finalize-oaicn-integration firas fix-ci-tun fix-clock-source fix-dirty-ue-same-machine fix-itti fix-itti-segv fix-l2-sim fix-limeSDR-compile fix-nr-pdcp-timer fix-nr-rlc-range-nack fix-quectel fix-realtime fix-segfault-flexran-isolated 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_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-improvements flexran-repair-mme-mgmt flexran-report-split fr2-hw-test fujitsu_lte_contribution fujitsu_lte_contribution-128 gNB-nrUE-USRP gNB_mwc18_integration generate_push_ptrs git-dashboard gnb-freerun-txru gnb-n300-fixes gnb-only-test gnb-realtime-hotfix gnb-realtime-quickfix gnb-threadpool 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 hotfix_usrp_lib improve_build_nr_lte_merge improve_nr_modulation improve_ue_stability initial-nfapi-PNF-fixes integ-w13-test-rt-issue integration-develop-nr-2019w45 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_w5GC_CBRA_test inter-RRU inter-RRU-final inter-RRU-nr inter-RRU-oairu inter-rru-UE interoperability-test isip-turbo-decoder-dynamic isip-turbo-decoder-parallel isip_nr issue271_simulator issue392-simplify-s1-nos1step2_01 issue416_nfapicleanup issue_345_l2_fapi_simulator itti-enhancement l2-fixes large_scale_simulations ldpc-dec-layering ldpc-decoder-codegen ldpc-decoder-codegen2 ldpc-decoder-improvements ldpc-offload ldpc_short_codeword_fixes load_gnb lte-m-ue_type lte-ulsch-bugfix lte_uplink_improvement mac-fixes-wk45_2 mac-monitoring main_python master mbms-fix-develop-nr merging-2019-w51-to-develop-nr mex_mmse_receiver migrate-cpp-check-container minor-fix-doc-basic-sim mobipass-hack modify_fairRRscd_parallel mosaic5g-oai-ran mosaic5g-oai-sim msg4_phy_0303_lfq mu_allocate multi-L1 multi-RRUs multiple_ssb_sib1_bugfix nasmesh_kernel_5.8 new-gtpu new_nos1 new_pdcp new_rlc new_rlc_2020 new_rlc_in_mbms nfapi-L2-emulator nfapi-bugfix nfapi_improvement 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-coreset-bug-fix nr-dl-mimo-2layer nr-dlsch-multi-thread nr-dlsch-thread nr-dmrs-fixes nr-dual-connectivity nr-interdigital-test nr-ip-uplink-noS1 nr-mac-pdu-wireshark nr-mac-remove-ue-list nr-multiple-ssb nr-pdcp nr-pdcp-improvements nr-pdcp-nea2-security nr-pdcp-nia2-integrity nr-pdcp-srb-integrity nr-pdsch-extraction-bugfix nr-physim-update nr-ra-fix nr-rlc-am-bugfix-w44 nr-rlc-bugfix-w44 nr-ssb-measurements nr-stats-print nr-timing-measurement nr-timing-measurement-merge nr-ue-buffer-status nr-ue-slot-based nr-uldci nrPBCHTCFix nrPbchTcFix nrUE nrUE-hs nrUE-upper-layer nr_beamforming nr_bsr nr_ci_dlsim nr_csi_newbranch nr_dci_procedures nr_demo_wsa2019 nr_dl_dmrs_type2 nr_dl_pf nr_dl_pf2 nr_dl_ul_ptrs nr_dlsch_parallel_measurements nr_dlsim_plot nr_fapi_for_push_tmp nr_fdd_if_fix nr_fix_easycppcheck nr_flexible_NRBDL nr_improve_build_procedures nr_increase_tp nr_mib_vsa_test nr_pdcch_testing nr_pdcch_updates nr_pdsch_integration nr_polar_decoder_improvement nr_power_measurement_fixes nr_prach nr_prach_fr2 nr_pucch nr_pucch2 nr_segmentation_fixes nr_sim_fix nr_tdd_configuration nr_ue_msg3 nr_ue_pdcp_fix nr_ue_tti_cleanup nr_ul_pf nr_ul_scfdma nr_vcd nrue-multi-thread nrue_msg2_reception nsa-ue nsa_remove_band_hardcodings oai-sim oai-ubuntu-docker oai-ubuntu-docker-for-lmssdr oai_ue_mwc18_integration oairu oairu-dockerfile-support oc-docker-october-improvements ocp_simulator openxg/develop pdcp-benchmark pdsch-ch-est physim-build-deploy polar8 prb_based_dl_channel_estimation preprocessor_refactor-2 ptrs_rrc_config pucch2ab pucchsim-multiue pusch-mthread-scaling-fix pusch-retrans-fix-ue ra-dl-ul rau_rru_reciprocity_measurements recode_itti_from_scratch recursive-cmake reduce_memory_footprint release_v1_2_0_candidate remove-ci-workaround remove_nos1_hack_pdcp remove_x2_gnb_hardcoding repair-TA revert-f5c94279 revert-itti 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_ue_parallel rh_doc_update_3 rh_fr1_newjenkins rh_fr1_update rh_gnb_compile_fix rh_wk50_debug rhel77-build rlc-v2-bugfix-status-reporting rlc-v2-tick rlc_v2_coverity_fixes rohan_ulsim2RxFix rrc-enb-phy-testmode rru-txwrite-modification ru-parallel-beamforming ru_rau_enhancement ru_rau_enhancement-external-timing runel runel-reverse-test 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 schedule-si-fix signal-delay sim-channels small-bugfixes-w40 small-config-change small_nr_bugfixes smallcleanup softmodem_cleanup split73 t-gnb-tracer tcri test-panos test-x310-perf test_nsa_gtpu_fix test_rt-fix_phy-test testing_2symb_pdcch testing_with_external_txdata thread-pool tm7-iris tools_5Gadapt tp-ota-test trx_thread_param trx_write_thread ue-csi ue-dci-false-detection ue-fixes ue-fixes-ota ue-pdsch-pusch-parallel ue-race-fix ue-updates-runel-test ue_adjust_gain ue_beam_selection ue_dlsch-multi-threading ue_dlsch_decoding_ldpc_offload ue_nfapi_mch ues_test_tmp uhd_priority_set_cleanup ul-freq-iq-samps-to-file ul_dl_dci_same_slot ul_harq ulsch_decode_mthread ulsim_changes update-to-2019-march-june-release usrp_fix_adc_shift_and_pps_sync usrp_gpio_test usrp_x400 wf-sa-rrc wireshark-T-hack-ueid wireshark-log-scheduling-requests wk11-with-phytest workaround-rebased workaround-restart-not-working x2-endc-processing x2-ho x2-ka-test x2_neighbor_6cells x2_tdd xiangwab xiangwan xw2 yihongzheng_srb zzs 2021.wk14_a 2021.wk13_d 2021.wk13_c 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 2020.w16 2020.w15 2020.w11 2020.w09 2020.w06 2020.w05 2020.w04 2020.w03 2019.w51 2019.w44 2019.w41 2019.w36 2019.w30 2019.w28 2019.w27 2019.w25 2019.w23 2019.w21 2019.w17 2019.w15 2019.w13 2019.w11 2019.w10 2019.w09 2019.w08 2019.w07 2019.w06 2019.w04 2019.w03 2018.w51 2018.w48 2018.w47 2018.w46 2018.w44 2018.w41 2018.w40 2018.w39 2018.w36 2018.w33 2018.w31 2018.w29 2018.w25 2018.w19 2018.w15 2018.w12 2018.w11 2018.w10 2018.w09 2018.w08 2018.w07 2018.w06 2018.w05 2018.w04 2018.w03 2018.w02 2017.w48 2017.w46 2017.w43 2017.w42 2017.w34 2017.w30 2017.w25 2017.w24 2017.w22 2017.w20 2017.w19 2017.w15 2017.w14 2017.w13 2017.w12 2017.w11 2017.w10 2017.w09 2017.w08 2017.w07 2017.w06 2017.w05 2017.w04 2017.w03 2017.w02 2017.w01 2016.w50 2016.w49 v1.2.2 v1.2.1 v1.2.0 v1.1.1 v1.1.0 v1.0.3 v1.0.2 v1.0.1 v1.0.0 v1B0.8 v1B0.7 v1B0.6 v1B0.5 v1B0.4 v1B0.3 v1B0.2 v1B0.1 v0.6.1 v0.6.1_tdd v0.6 v0.5.2 v0.5.1_tdd v0.5 v0.4 v0.3 v0.2 v0.1 testing-cmw500 osa-etsi-ws-ue osa-etsi-ws-try2 osa-etsi-ws-try1 osa-etsi-ws-gNB oai_nr_sync nr-ip-over-lte nr-ip-over-lte-v.1.5 nr-ip-over-lte-v.1.4 nr-ip-over-lte-v.1.3 nr-ip-over-lte-v.1.2 nr-ip-over-lte-v.1.1 nr-ip-over-lte-v.1.0 develop-nr-pdcch develop-nr-2020w03 develop-nr-2020w02 develop-nr-2019w51 develop-nr-2019w50 develop-nr-2019w48 develop-nr-2019w47 develop-nr-2019w45 develop-nr-2019w43 develop-nr-2019w42 develop-nr-2019w40 develop-nr-2019w28 develop-nr-2019w23 benetel_phase_rotation benetel_gnb_rel_1.0 benetel_enb_rel_1.0
No related merge requests found
......@@ -392,7 +392,7 @@ elseif (${RF_BOARD} STREQUAL "ETHERNET")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
)
set(LOWLATENCY False)
set(LOWLATENCY True)
elseif (${RF_BOARD} STREQUAL "CPRIGW")
set(HW_SOURCE ${HW_SOURCE}
......@@ -1558,6 +1558,7 @@ add_executable(lte-softmodem
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIRCN_DIR}/NAS/UE/nas_ue_task.c
${GTPU_need_ITTI}
......@@ -1591,6 +1592,7 @@ add_executable(lte-softmodem-nos1
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
#${OPENAIR2_DIR}/RRC/NAS/nas_config.c # enable if you want rrc to mount ip interface
#${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
......@@ -1726,6 +1728,7 @@ add_executable(rrh_gw
${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${HW_SOURCE}
)
......
......@@ -92,6 +92,8 @@ const char* eurecomVariablesNames[] = {
"diff2",
"hw_subframe",
"hw_frame",
"hw_subframe_rx",
"hw_frame_rx",
"txcnt",
"rxcnt",
"trx_ts",
......@@ -103,6 +105,8 @@ const char* eurecomVariablesNames[] = {
"hw_cnt_tx",
"lhw_cnt_tx",
"pck_rx",
"pck_tx",
"cnt",
"dummy_dump",
"itti_send_msg",
"itti_poll_msg",
......@@ -150,6 +154,8 @@ const char* eurecomFunctionsNames[] = {
"eNB_rx_sleep",
"eNB_tx_sleep",
"eNB_proc_sleep",
"trx_read_rf",
"trx_write_rf",
/* PHY signals */
"ue_synch",
......
......@@ -64,6 +64,8 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_DIFF,
VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME,
VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME,
VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX,
VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX,
VCD_SIGNAL_DUMPER_VARIABLES_TXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS,
......@@ -75,6 +77,8 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_CNT,
VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG,
......@@ -117,7 +121,6 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RX,
/* RRH signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX,
......@@ -125,6 +128,8 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF,
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF,
/* PHY signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,
......
......@@ -185,7 +185,7 @@ int trx_brf_set_gains(openair0_device* device) {
}
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) {
int status;
int card=0;
......
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file common_lib.c
* \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include "common_lib.h"
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
#ifdef ETHERNET
device->type=ETH_IF;
device->func_type = BBU_FUNC;
openair0_dev_init_eth(device, openair0_cfg);
printf(" openair0_dev_init_eth ...\n");
#elif EXMIMO
device->type=EXMIMO_IF;
openair0_dev_init_exmimo(device, openair0_cfg);
printf("openair0_dev_init_exmimo...\n");
#elif OAI_USRP
device->type=USRP_IF;
openair0_dev_init_usrp(device, openair0_cfg);
printf("openair0_dev_init_usrp ...\n");
#elif OAI_BLADERF
device->type=BLADERF_IF;
openair0_dev_init_bladerf(device, openair0_cfg);
printf(" openair0_dev_init_bladerf ...\n");
#endif
}
......@@ -134,7 +134,13 @@ typedef struct {
/*!\brief device type */
/*!\brief interface types that apply to modules (RRH_BBU/RRH_UE) created in RRH (rrh_gw.c)
and are defined with respect to the RF device that is present in RRH
-RRH_BBU modules have two devices, one is by default ETHERNET (will have ETH_IF) and the other one is a
RF device (EXMIMO,USRP,BLADERF) or no device (NONE_IF).
-RRH_UE modules have two devices one is by default ETHERNET (will have ETH_IF)
and the other one by default not present so it will have NONE_IF
*/
typedef enum {
MIN_DEV_TYPE = 0,
/*!\brief device is ETH */
......@@ -152,7 +158,7 @@ typedef enum {
} dev_type_t;
/*!\brief type */
/*!\brief openair0 device host type */
typedef enum {
MIN_FUNC_TYPE = 0,
/*!\brief device functions within a BBU */
......@@ -264,23 +270,20 @@ extern "C"
#endif
/*! \brief Initialize Openair RF target. It returns 0 if OK */
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
//int openair0_stop(int card);
//ETHERNET
/*! \brief Initialize Openair ETHERNET target. It returns 0 if OK */
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
//int openair0_stop_eth(int card);
//int openair0_set_gains_eth(openair0_device* device, openair0_config_t *openair0_cfg);
//int openair0_set_frequencies_eth(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
//USPRP
//USRP
/*! \brief Get the current timestamp of USRP */
openair0_timestamp get_usrp_time(openair0_device *device);
openair0_timestamp get_usrp_time(openair0_device *device);
/*! \brief Set the RX frequency of USRP RF TARGET */
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);
//extern
/*! \brief Initialize Openair ETHERNET target. It returns 0 if OK */
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg);
/*@}*/
#ifdef __cplusplus
......
......@@ -26,7 +26,7 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \fileethernet_lib.c
/*! \file ethernet_lib.c
* \brief API to stream I/Q samples over standard ethernet
* \author Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
* \date 2015
......@@ -52,221 +52,76 @@
#include "common_lib.h"
#include "ethernet_lib.h"
//#define DEBUG 1
int num_devices_eth = 0;
int dest_addr_len[MAX_INST];
char sendbuf[MAX_INST][BUF_SIZ]; /*TODO*/
/* Initialization of UDP Socket to communicate with one destination */
int ethernet_socket_init(openair0_device *device) {
int i = 0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
// struct sockaddr_in *dest = &dest_addr[Mod_id];
char str[INET_ADDRSTRLEN];
const char *dest_ip;
int dest_port;
if (device->func_type == RRH_FUNC ){
dest_ip = device->openair0_cfg.my_ip;
dest_port = device->openair0_cfg.my_port;
printf("[RRH] ip addr %s port %d\n",dest_ip, dest_port);
} else {
dest_ip = device->openair0_cfg.remote_ip;
dest_port = device->openair0_cfg.remote_port;
printf("[BBU] ip addr %s port %d\n",dest_ip, dest_port);
}
/* Open RAW socket to send on */
if ((eth->sockfd[Mod_id] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("ETHERNET: Error opening socket");
exit(0);
}
/* initialize destination address */
for (i=0; i< MAX_INST; i++)
bzero((void *)&(eth->dest_addr[i]), sizeof(eth->dest_addr[i]));
// bzero((void *)dest,sizeof(struct sockaddr_in));
eth->dest_addr[Mod_id].sin_family = AF_INET;
inet_pton(AF_INET,dest_ip,&(eth->dest_addr[Mod_id].sin_addr.s_addr));
eth->dest_addr[Mod_id].sin_port=htons(dest_port);
dest_addr_len[Mod_id] = sizeof(struct sockaddr_in);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
/* if RRH, then I am the server, so bind */
if (device->func_type == RRH_FUNC ){
if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&eth->dest_addr[Mod_id], dest_addr_len[Mod_id])<0) {
perror("ETHERNET: Cannot bind to socket");
exit(0);
}else {
printf("[RRH] binding mod_%d to %s:%d\n",Mod_id,str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
}else {
printf("[BBU] Connecting to %s:%d\n",str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
return 0;
}
void ethernet_socket_opt (openair0_device *device){
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id=device->Mod_id;
int sndbuf_size=0, rcvbuf_size=0;
socklen_t optlen;
/* chang the MTU of the eth interface */
struct ifreq ifr;
optlen = sizeof(int);
if (getsockopt(eth->sockfd[Mod_id],
SOL_SOCKET,
SO_SNDBUF,
&sndbuf_size,&optlen))
printf("error:getsockopt()\n");
if (getsockopt(eth->sockfd[Mod_id],
SOL_SOCKET,
SO_RCVBUF,
&rcvbuf_size,&optlen))
printf("error:getsockopt()\n");
printf( "sndbuf_size= %d bytes rcvbuf_size= %d bytes\n", sndbuf_size,
rcvbuf_size);
ifr.ifr_addr.sa_family = AF_INET;
//iap->ifa_name is bond1:xx
strncpy(ifr.ifr_name, DEFAULT_IF, sizeof(ifr.ifr_name));
ifr.ifr_mtu = device->openair0_cfg.samples_per_packet*5;
if (ioctl(eth->sockfd[Mod_id], SIOCSIFMTU, (caddr_t)&ifr) < 0 )
perror ("Can't set the MTU");
else
printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu);
}
int trx_eth_set_dev_conf(openair0_device *device) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
void *msg;
ssize_t msg_len;
/* send to RRH (server) required configuration parameters:
-number of downlink RBs (so that frame/packet size can be set accordingly)
-rx_num_0channels
-tx_num_channels
-rx_freq
-tx_freq
-rxg_mode[4]
-rx_gain
-tx_gain
-rx_bw
-tx_bw
-autocal */
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
memcpy(msg,(void*)&device->openair0_cfg,msg_len);
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1){
perror("ETHERNET: ");
exit(0);
}
return 0;
}
int trx_eth_get_dev_conf(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str[INET_ADDRSTRLEN];
void *msg;
ssize_t msg_len;
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
/* receive from client (lte-softmodem) */
if (recvfrom(eth->sockfd[Mod_id],
msg,
msg_len,
0,
(struct sockaddr *)&eth->dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1){
perror("ETHERNET: ");
exit(0);
}
memcpy((void*)&device->openair0_cfg,msg,msg_len);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
device->openair0_cfg.remote_port =ntohs(eth->dest_addr[Mod_id].sin_port);
device->openair0_cfg.remote_ip=str;
//ethernet_socket_opt (device);
// printf("[RRH] write mod_%d %d to %s:%d\n",Mod_id,eth->sockfd[Mod_id],str,ntohs(eth->dest_addr[Mod_id].sin_port));
return 0;
}
int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1){
perror("ETHERNET: ");
exit(0);
/*! \fn static int eth_socket_init(openair0_device *device)
* \brief initialization of UDP Socket to communicate with one destination
* \param[in] *device openair device for which the socket will be created
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
static int eth_socket_init(openair0_device *device);
/*! \fn static int eth_set_dev_conf(openair0_device *device)
* \brief
* \param[in] *device openair device
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
static int eth_set_dev_conf(openair0_device *device);
/*! \fn static int eth_get_dev_conf(openair0_device *device)
* \brief
* \param[in] *device openair device
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
static int eth_get_dev_conf(openair0_device *device);
int trx_eth_start(openair0_device *device) {
/* initialize socket */
if (eth_socket_init(device)!=0) {
return -1;
}
return 0;
}
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
/* receive from client (lte-softmodem) */
if (recvfrom(eth->sockfd[Mod_id],
msg,
msg_len,
0,
(struct sockaddr *)&eth->dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1){
perror("ETHERNET: ");
exit(0);
/* RRH gets openair0 device configuration BBU sets openair0 device configuration*/
if (device->func_type == BBU_FUNC) {
return eth_set_dev_conf(device);
} else {
return eth_get_dev_conf(device);
}
return 0;
}
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id) {
int trx_eth_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int n_written;
int n_written=0,i;
uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
int sendto_flag =0;
sendto_flag|=MSG_DONTWAIT;
/* buff[antenna_id] points to the position in tx buffer where the payload to be sent is
for (i=0;i<cc;i++) {
/* buff[i] points to the position in tx buffer where the payload to be sent is
buff2 points to the position in tx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[antenna_id]-header_size); // (void*)((unsigned char *)buff[antenna_id]-header_size);
void *buff2 = (void*)(buff[i]-header_size);
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
......@@ -274,13 +129,13 @@ int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, v
n_written = 0;
*(int16_t *)(buff2 + sizeof(int16_t))=1+(antenna_id<<1);
*(int16_t *)(buff2 + sizeof(int16_t))=1+(i<<1);
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
/* printf("[RRH]write mod_%d %d , len %d, buff %p antenna %d\n",
Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
while(n_written < nsamps) {
while(n_written < nsamps) {
/* Send packet */
if ((n_written += sendto(eth->sockfd[Mod_id],
buff2,
......@@ -293,40 +148,44 @@ while(n_written < nsamps) {
}
}
/* printf("Buffer head TX: nu=%d an_id=%d ts%d byte_send=%d \n", *(int16_t *)buff2,
#if DEBUG
printf("Buffer head TX: nu=%d an_id=%d ts%d samples_send=%d i=%d data=%x\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
n_written>>2);*/
n_written>>2,i,*(int32_t *)(buff2 + 20*sizeof(int32_t)));
#endif
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
}
return n_written;
}
int trx_eth_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int antenna_id) {
int bytes_received;
int block_cnt;
int ret;
int bytes_received=0;
int block_cnt=0;
int ret=0,i;
uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
/* buff[antenna_id] points to the position in rx buffer where the payload to be received will be placed
for (i=0;i<cc;i++) {
/* buff[i] points to the position in rx buffer where the payload to be received will be placed
buff2 points to the position in rx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[antenna_id]-header_size);
void *buff2 = (void*)(buff[i]-header_size);
/* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
bytes_received=0;
block_cnt=0;
ret=0;
/* printf("[RRH] read mod_%d %d,len %d, buff %p antenna %d\n",
Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
......@@ -353,11 +212,14 @@ int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,voi
bytes_received+=ret;
}
}
/*
printf("Buffer head RX: nu=%d an_id=%d ts%d byte_recv=%d\n", *(int16_t *)buff2,
#if DEBUG
printf("Buffer head RX: nu=%d an_id=%d ts%d samples_recv=%d i=%d data=%x\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
ret>>2);*/
ret>>2,i,*(int32_t *)(buff2 + 20*sizeof(int32_t)));
#endif
/* store the timestamp value from packet's header */
*timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
......@@ -365,38 +227,122 @@ int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,voi
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
// printf("Received %d samples, timestamp = %d\n",bytes_received>>2,*(int32_t*)timestamp);
}
return nsamps;
}
int trx_eth_start(openair0_device *device){
void trx_eth_end(openair0_device *device) {
if (ethernet_socket_init(device)!=0) {
return -1;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
/*destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
if ( close(eth->sockfd[Mod_id]) <0 ) {
perror("ETHERNET: Failed to close socket");
exit(0);
} else {
printf("[RRH] socket for mod_id %d has been successfully closed.\n",Mod_id);
}
if (device->func_type == BBU_FUNC ) {
return trx_eth_set_dev_conf(device);
}
int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
/* BBU sends a message to RRH */
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
else{
return trx_eth_get_dev_conf(device);
return 0;
}
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
/* RRH receives from BBU a message */
if (recvfrom(eth->sockfd[Mod_id],
msg,
msg_len,
0,
(struct sockaddr *)&eth->dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
return(0);
return 0;
}
int trx_eth_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int antenna_id, int flags) {
return ethernet_write_data(device,timestamp,buff,nsamps,antenna_id);
static int eth_set_dev_conf(openair0_device *device) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
void *msg;
ssize_t msg_len;
/* a BBU client sents to RRH a set of configuration parameters (openair0_config_t)
so that RF front end is configured appropriately and
frame/packet size etc. can be set */
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
memcpy(msg,(void*)&device->openair0_cfg,msg_len);
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
return 0;
}
int trx_eth_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int antenna_id) {
return(ethernet_read_data(device,ptimestamp,buff,nsamps,antenna_id));
static int eth_get_dev_conf(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str[INET_ADDRSTRLEN];
void *msg;
ssize_t msg_len;
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
/* RRH receives from BBU openair0_config_t */
if (recvfrom(eth->sockfd[Mod_id],
msg,
msg_len,
0,
(struct sockaddr *)&eth->dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
memcpy((void*)&device->openair0_cfg,msg,msg_len);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
device->openair0_cfg.remote_port =ntohs(eth->dest_addr[Mod_id].sin_port);
device->openair0_cfg.remote_ip=str;
/*apply additional configuration*/
//ethernet_tune (device, RING_PAR);
// printf("[RRH] write mod_%d %d to %s:%d\n",Mod_id,eth->sockfd[Mod_id],str,ntohs(eth->dest_addr[Mod_id].sin_port));
return 0;
}
int trx_eth_stop(int card) {
return(0);
}
......@@ -409,48 +355,173 @@ int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg)
return(0);
}
int trx_eth_get_stats(openair0_device* device) {
return(0);
}
int trx_eth_reset_stats(openair0_device* device) {
return(0);
}
int openair0_set_gains(openair0_device* device,
openair0_config_t *openair0_cfg) {
return(0);
}
static int eth_socket_init(openair0_device *device) {
int i = 0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str[INET_ADDRSTRLEN];
const char *dest_ip;
int dest_port=0;
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) {
if (device->func_type == RRH_FUNC ) {
dest_ip = device->openair0_cfg.my_ip;
dest_port = device->openair0_cfg.my_port;
printf("[RRH] ip addr %s port %d\n",dest_ip, dest_port);
} else {
dest_ip = device->openair0_cfg.remote_ip;
dest_port = device->openair0_cfg.remote_port;
printf("[BBU] ip addr %s port %d\n",dest_ip, dest_port);
}
return(0);
}
/* Open RAW socket to send on */
if ((eth->sockfd[Mod_id] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("ETHERNET: Error opening socket");
exit(0);
}
/* initialize destination address */
for (i=0; i< MAX_INST; i++) {
bzero((void *)&(eth->dest_addr[i]), sizeof(eth->dest_addr[i]));
}
// bzero((void *)dest,sizeof(struct sockaddr_in));
eth->dest_addr[Mod_id].sin_family = AF_INET;
inet_pton(AF_INET,dest_ip,&(eth->dest_addr[Mod_id].sin_addr.s_addr));
eth->dest_addr[Mod_id].sin_port=htons(dest_port);
dest_addr_len[Mod_id] = sizeof(struct sockaddr_in);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
/* if RRH, then I am the server, so bind */
if (device->func_type == RRH_FUNC ) {
if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&eth->dest_addr[Mod_id], dest_addr_len[Mod_id])<0) {
perror("ETHERNET: Cannot bind to socket");
exit(0);
} else {
printf("[RRH] binding mod_%d to %s:%d\n",Mod_id,str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
} else {
printf("[BBU] Connecting to %s:%d\n",str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
return 0;
}
void trx_eth_end(openair0_device *device) {
int ethernet_tune(openair0_device *device , eth_opt_t option) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
/*destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
if ( close(eth->sockfd[Mod_id]) <0 ) {
perror("ETHERNET: Failed to close socket");
exit(0);
}else {
printf("[RRH] socket for mod_id %d has been successfully closed.",Mod_id);
int Mod_id=device->Mod_id;
unsigned int sndbuf_size=0, rcvbuf_size=0;
struct timeval snd_timeout, rcv_timeout;
struct ifreq ifr;
char system_cmd[256];
char* if_name=DEFAULT_IF;
/****************** socket level options ************************/
if (option== SND_BUF_SIZE) { /* transmit socket buffer size */
if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET,
SO_SNDBUF,
&sndbuf_size,sizeof(sndbuf_size))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "sndbuf_size= %d bytes\n", sndbuf_size);
}
} else if (option== RCV_BUF_SIZE) { /* receive socket buffer size */
if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET,
SO_RCVBUF,
&rcvbuf_size,sizeof(rcvbuf_size))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "rcvbuf_size= %d bytes\n", rcvbuf_size);
}
} else if (option==RCV_TIMEOUT) {
rcv_timeout.tv_sec = 0;
rcv_timeout.tv_usec = 180;//less than rt_period
if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET,
SO_RCVTIMEO,
(char *)&rcv_timeout,sizeof(rcv_timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "rcv_timeout= %d usecs\n", rcv_timeout.tv_usec);
}
} else if (option==SND_TIMEOUT) {
snd_timeout.tv_sec = 0;
snd_timeout.tv_usec = 180;//less than rt_period
if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET,
SO_SNDTIMEO,
(char *)&snd_timeout,sizeof(snd_timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "snd_timeout= %d usecs\n", snd_timeout.tv_usec);
}
}
/******************* interface level options *************************/
else if (option==MTU_SIZE) { /* change MTU of the eth interface */
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
ifr.ifr_mtu =8960;
if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the MTU");
else
printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu);
} else if (option==TX_Q_LEN) { /* change TX queue length of eth interface */
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
ifr.ifr_qlen =3000 ;
if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the txqueuelen");
else
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",DEFAULT_IF,ifr.ifr_qlen);
/******************* device level options *************************/
} else if (option==COALESCE_PAR) {
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs 3",DEFAULT_IF) > 0) {
system(system_cmd);
printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set coalesce parameters\n");
}
} else if (option==PAUSE_PAR ) {
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",DEFAULT_IF) > 0) {
system(system_cmd);
printf("[ETHERNET] Pause parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set pause parameters\n");
}
} else if (option==RING_PAR ) {
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx 4096 tx 4096",DEFAULT_IF) > 0) {
system(system_cmd);
printf("[ETHERNET] Ring parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set ring parameters\n");
}
}
return 0;
}
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg){
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg) {
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
int card = 0;
......
......@@ -48,7 +48,7 @@
#include <netinet/ether.h>
#define MAX_INST 4
#define DEFAULT_IF "eth0"
#define DEFAULT_IF "lo"
#define BUF_SIZ 8960 /*Jumbo frame size*/
typedef struct {
......@@ -103,21 +103,51 @@ struct eth_meta_data{
};
/*!\brief packet header */
typedef struct {
/* packet's timestamp */
/*!\brief packet's timestamp */
openair0_timestamp timestamp;
/* variable declared for alignment purposes (sample size=32 bit) */
/*!\brief variable declared for alignment purposes (sample size=32 bit) */
int16_t not_used;
/* antenna port used to resynchronize*/
/*!\brief antenna port used to resynchronize */
int16_t antenna_id;
} header_t;
int ethernet_socket_init(openair0_device *device);
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id);
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int antenna_id);
void ethernet_socket_opt (openair0_device *device);
/*!\brief different options for ethernet tuning in socket and driver level */
typedef enum {
MIN_OPT = 0,
/*!\brief socket send buffer size in bytes */
SND_BUF_SIZE,
/*!\brief socket receive buffer size in bytes */
RCV_BUF_SIZE,
/*!\brief receiving timeout */
RCV_TIMEOUT,
/*!\brief sending timeout */
SND_TIMEOUT,
/*!\brief maximun transmission unit size in bytes */
MTU_SIZE,
/*!\brief TX queue length */
TX_Q_LEN,
/*!\brief RX/TX ring parameters of ethernet device */
RING_PAR,
/*!\brief interruptions coalesence mechanism of ethernet device */
COALESCE_PAR,
/*!\brief pause parameters of ethernet device */
PAUSE_PAR,
MAX_OPT
} eth_opt_t;
/*! \fn int ethernet_tune (openair0_device *device, eth_opt_t option)
* \brief this function allows you to configure certain ethernet parameters in socket or device level
* \param[in] openair0 device which bears the socket
* \param[in] name of parameter to configure
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int ethernet_tune (openair0_device *device, eth_opt_t option);
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc) ;
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int cc);
......@@ -247,7 +247,7 @@ int openair0_stop_without_reset(int card)
#define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX)
#define RF_MODE_BASE (LNA1ON + RFBBNORM)
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg) {
// Initialize card
// exmimo_config_t *p_exmimo_config;
......
......@@ -154,7 +154,6 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc)
{
usrp_state_t *s = (usrp_state_t*)device->priv;
int samples_received=0,i,j;
int nsamps2; // aligned to upper 32 or 16 byte boundary
......@@ -188,25 +187,20 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
for (int j=0; j<nsamps2; j++) {
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4);
#else
((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4);
#endif
#elif defined(__arm__)
((int16x8_t*)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4);
#endif
}
}
if (samples_received < nsamps) {
printf("[recv] received %d samples out of %d\n",samples_received,nsamps);
}
//handle the error code
switch(s->rx_md.error_code){
case uhd::rx_metadata_t::ERROR_CODE_NONE:
......@@ -225,6 +219,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
s->rx_count += nsamps;
s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
*ptimestamp = s->rx_timestamp;
return samples_received;
}
......@@ -334,7 +329,7 @@ int trx_usrp_reset_stats(openair0_device* device) {
}
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg)
int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg)
{
uhd::set_thread_priority_safe(1.0);
usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t));
......@@ -499,6 +494,5 @@ int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cf
s->tx_forward_nsamps = 90;
if(is_equal(s->sample_rate, (double)7.68e6))
s->tx_forward_nsamps = 50;
return 0;
}
......@@ -89,15 +89,8 @@ void *rrh_UE_thread_status;
void *rx_ue[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_rx
void *tx_ue[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_tx
/*! \fn void create_UE_trx_threads( openair0_device *dev_ue, uint8_t RT_flag,uint8_t NRT_flag)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void create_UE_trx_threads( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) {
void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) {
int i;
int error_code_UE, error_code_proc_UE;
......
......@@ -28,7 +28,7 @@
*******************************************************************************/
/*! \file eNB_transport_IQ.c
* \brief eNB transport IQ sampels
* \brief eNB transport IQ samples
* \author Katerina Trilyraki, Navid Nikaein, Raymond Knopp
* \date 2015
* \version 0.1
......@@ -53,92 +53,120 @@
#define PRINTF_PERIOD 3750
#define HEADER_SIZE ((sizeof(int32_t) + sizeof(openair0_timestamp))>>2)
//#undef LOWLATENCY
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void *rrh_eNB_rx_thread(void *);
void *rrh_eNB_tx_thread(void *);
void *rrh_proc_eNB_thread(void *);
void *rrh_eNB_thread(void *);
void set_rt_period( openair0_config_t openair0_cfg);
void check_dev_config( rrh_module_t *mod_enb);
pthread_t main_rrh_eNB_thread;
pthread_attr_t attr, attr_proc;
struct sched_param sched_param_rrh;
pthread_cond_t sync_eNB_cond[4];
pthread_mutex_t sync_eNB_mutex[4];
pthread_mutex_t sync_trx_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t sync_trx_cond=PTHREAD_COND_INITIALIZER;
openair0_timestamp nrt_eNB_counter[4]= {0,0,0,0};
int32_t overflow_rx_buffer_eNB[4]= {0,0,0,0};
int32_t nsamps_eNB[4]= {0,0,0,0};
int32_t eNB_tx_started=0,eNB_rx_started=0;
int32_t counter_eNB_rx[4]= {0,0,0,0};
int32_t counter_eNB_tx[4]= {0,0,0,0};
uint8_t RT_flag_eNB,NRT_flag_eNB;
int32_t **tx_buffer_eNB, **rx_buffer_eNB;
void *rrh_eNB_thread_status;
int sync_eNB_rx[4]= {-1,-1,-1,-1};
unsigned int sync_trx=0;
int32_t **tx_buffer_eNB;
int32_t **rx_buffer_eNB;
void **rx_eNB; //was fixed to 2 ant
void **tx_eNB; //was fixed to 2 ant
int sync_eNB_rx[4]= {-1,-1,-1,-1};
openair0_timestamp timestamp_eNB_tx[4]= {0,0,0,0},timestamp_eNB_rx[4]= {0,0,0,0};
openair0_timestamp timestamp_eNB_tx[4]= {0,0,0,0};// all antennas must have the same ts
openair0_timestamp timestamp_eNB_rx[4]= {0,0,0,0};
openair0_timestamp timestamp_rx=0,timestamp_tx=0;
unsigned int rx_pos=0, next_rx_pos=0;
unsigned int tx_pos=0, prev_tx_pos=0;
unsigned int tx_pos=0, tx_pos_rf=0, prev_tx_pos=0;
unsigned int rt_period=0;
struct itimerspec timerspec;
pthread_mutex_t timer_mutex;
/*! \fn void create_eNB_trx_threads( rrh_module_t *dev_enb, uint8_t RT_flag,uint8_t NRT_flag)
/*! \fn void *rrh_eNB_rx_thread(void *arg)
* \brief this function
* \param[in]
* \return none
* \note
* @ingroup _oai
*/
void *rrh_eNB_rx_thread(void *);
/*! \fn void *rrh_eNB_tx_thread(void *arg)
* \brief this function
* \param[in]
* \return none
* \note
* @ingroup _oai
*/
void *rrh_eNB_tx_thread(void *);
/*! \fn void *rrh_eNB_thread(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \return none
* \note
* @ingroup _oai
*/
void *rrh_eNB_thread(void *);
/*! \fn void check_dev_config( rrh_module_t *mod_enb)
* \brief this function
* \param[in] *mod_enb
* \return none
* \note
* @ingroup _oai
*/
void create_eNB_trx_threads( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag){
static void check_dev_config( rrh_module_t *mod_enb);
/*! \fn void calc_rt_period_ns( openair0_config_t openair0_cfg)
* \brief this function
* \param[in] openair0_cfg
* \return none
* \note
* @ingroup _oai
*/
static void calc_rt_period_ns( openair0_config_t openair0_cfg);
void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) {
//int i;
int error_code_eNB;
pthread_t main_rrh_eNB_thread;
pthread_attr_t attr;
struct sched_param sched_param_rrh;
RT_flag_eNB=RT_flag;
NRT_flag_eNB=NRT_flag;
pthread_attr_init(&attr);
sched_param_rrh.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr,&sched_param_rrh);
pthread_attr_setschedpolicy(&attr,SCHED_FIFO);
/*for (i=0; i<4; i++) {
pthread_mutex_init(&sync_eNB_mutex[i],NULL);
pthread_cond_init(&sync_eNB_cond[i],NULL);
}*/
/* handshake with client to exchange parameters */
mod_enb->eth_dev.trx_start_func(&mod_enb->eth_dev);//change port make it plus_id
/* if a RF iterface is added to RRH module get the configuration parameters sent from eNB */
if (mod_enb->devs->type != NONE_IF ) {
memcpy((void*)&mod_enb->devs->openair0_cfg,(void *)&mod_enb->eth_dev.openair0_cfg,sizeof(openair0_config_t));
/* update certain parameters */
/* certain parameters have to be updated (calibration related)*/
if ( mod_enb->devs->type == EXMIMO_IF ) {
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ){
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
mod_enb->devs->openair0_cfg.tx_delay = 5;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ){
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
mod_enb->devs->openair0_cfg.tx_delay = 6;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ){
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 256;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
mod_enb->devs->openair0_cfg.tx_delay = 8;
......@@ -150,50 +178,49 @@ void create_eNB_trx_threads( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
mod_enb->devs->openair0_cfg.tx_delay = 5;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
mod_enb->devs->openair0_cfg.tx_delay = 6;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 256;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
else if (mod_enb->devs->type == BLADERF_IF) {
else if(mod_enb->devs->type == BLADERF_IF) {
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ){
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
mod_enb->devs->openair0_cfg.tx_delay = 5;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ){
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
mod_enb->devs->openair0_cfg.tx_delay = 6;
}
else if( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ){
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 256;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
/* check sanity of received configuration parameters and print */
/* check sanity of configuration parameters and print */
check_dev_config(mod_enb);
#ifndef ETHERNET
/* initialize and apply configuration to associated RF device */
/* initialize and configure the RF device */
if (openair0_device_init(mod_enb->devs, &mod_enb->devs->openair0_cfg)<0){
LOG_E(RRH,"Exiting, cannot initialize RF device.\n");
exit(-1);
......@@ -202,9 +229,26 @@ void create_eNB_trx_threads( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT
LOG_I(RRH,"RF device has been successfully initialized.\n");
}
#endif
/* start RF device */
if (mod_enb->devs->type == EXMIMO_IF ) {
} else {
if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0)
LOG_E(RRH,"Unable to initiate RF device.\n");
}
LOG_I(RRH,"RF device has been initiated.\n");
}
/* create main eNB module thread
main_rrh_eNB_thread allocates memory
for TX/RX buffers and creates TX/RX
threads for every eNB module */
pthread_attr_init(&attr);
sched_param_rrh.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr,&sched_param_rrh);
pthread_attr_setschedpolicy(&attr,SCHED_FIFO);
error_code_eNB = pthread_create(&main_rrh_eNB_thread, &attr, rrh_eNB_thread, (void *)mod_enb);
if (error_code_eNB) {
LOG_E(RRH,"Error while creating eNB thread\n");
exit(-1);
......@@ -212,16 +256,9 @@ void create_eNB_trx_threads( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT
}
/*! \fn void *rrh_eNB_thread(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *rrh_eNB_thread(void *arg)
{
void *rrh_eNB_thread(void *arg) {
rrh_module_t *dev=(rrh_module_t *)arg;
pthread_t eNB_rx_thread, eNB_tx_thread;
int error_code_eNB_rx, error_code_eNB_tx;
......@@ -229,42 +266,35 @@ void *rrh_eNB_thread(void *arg)
void *tmp;
unsigned int samples_per_frame=0;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
while (rrh_exit==0) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX, 1 );
if (dev->devs->type != NONE_IF) {
set_rt_period(dev->eth_dev.openair0_cfg);
}
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
/* calculate packet period */
calc_rt_period_ns(dev->eth_dev.openair0_cfg);
/* allocate memory for TX/RX buffers
each antenna port has a TX and a RX buffer
each TX and RX buffer is of (samples_per_frame + HEADER_SIZE) samples (size of samples is 4 bytes) */
rx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*));
tx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*));
LOG_I(RRH,"rx ch %d %p and tx ch %d %p\n",
dev->eth_dev.openair0_cfg.rx_num_channels,
rx_buffer_eNB,
dev->eth_dev.openair0_cfg.tx_num_channels,
tx_buffer_eNB);
LOG_D(RRH,"rx_buffer_eNB address =%p tx_buffer_eNB address =%p \n",rx_buffer_eNB,tx_buffer_eNB);
/* rx_buffer_eNB points to the beginning of data */
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame + HEADER_SIZE));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame + HEADER_SIZE));
rx_buffer_eNB[i]=( tmp + (HEADER_SIZE*sizeof(int32_t)) );
LOG_I(RRH," rx ch %d %p |%p\n",i,rx_buffer_eNB[i],tmp);
tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32));
rx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) );
LOG_D(RRH,"i=%d rx_buffer_eNB[i]=%p tmp= %p\n",i,rx_buffer_eNB[i],tmp);
}
/* tx_buffer_eNB points to the beginning of data */
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) {
tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame + HEADER_SIZE));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame + HEADER_SIZE));
tx_buffer_eNB[i]=( tmp + (HEADER_SIZE*sizeof(int32_t)) );
LOG_I(RRH," tx ch %d %p| %p \n", i,tx_buffer_eNB[i],tmp);
tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32));
tx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) );
LOG_D(RRH,"i= %d tx_buffer_eNB[i]=%p tmp= %p \n",i,tx_buffer_eNB[i],tmp);
}
/* dummy initialization for TX/RX buffers */
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
......@@ -278,12 +308,19 @@ void *rrh_eNB_thread(void *arg)
tx_buffer_eNB[i][j]=12+i;
}
}
/* allocate TX/RX buffers pointers used in write/read operations */
rx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*));
tx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*));
/* init mutexes */
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) {
pthread_mutex_init(&sync_eNB_mutex[i],NULL);
pthread_cond_init(&sync_eNB_cond[i],NULL);
}
/* init mutexes */
pthread_mutex_init(&sync_trx_mutex,NULL);
/* create eNB module's TX/RX threads */
#ifdef LOWLATENCY
error_code_eNB_rx = pthread_create(&eNB_rx_thread, NULL, rrh_eNB_rx_thread, (void *)dev);
error_code_eNB_tx = pthread_create(&eNB_tx_thread, NULL, rrh_eNB_tx_thread, (void *)dev);
......@@ -291,6 +328,7 @@ void *rrh_eNB_thread(void *arg)
#else
pthread_attr_t attr_eNB_rx, attr_eNB_tx;
struct sched_param sched_param_eNB_rx, sched_param_eNB_tx;
pthread_attr_init(&attr_eNB_rx);
pthread_attr_init(&attr_eNB_tx);
sched_param_eNB_rx.sched_priority = sched_get_priority_max(SCHED_FIFO);
......@@ -314,11 +352,53 @@ void *rrh_eNB_thread(void *arg)
exit(-1);
}
/* create timer thread; when no RF device is present a software clock is generated */
if (dev->devs->type == NONE_IF) {
int error_code_timer;
pthread_t main_timer_proc_thread;
LOG_I(RRH,"Creating timer thread with rt period %d ns.\n",rt_period);
/* setup the timer to generate an interrupt:
-for the first time in (sample_per_packet/sample_rate) ns
-and then every (sample_per_packet/sample_rate) ns */
timerspec.it_value.tv_sec = rt_period/1000000000;
timerspec.it_value.tv_nsec = rt_period%1000000000;
timerspec.it_interval.tv_sec = rt_period/1000000000;
timerspec.it_interval.tv_nsec = rt_period%1000000000;
#ifdef LOWLATENCY
error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[eNB][SCHED] deadline scheduling applied to timer thread \n");
#else
pthread_attr_t attr_timer;
struct sched_param sched_param_timer;
pthread_attr_init(&attr_timer);
sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO-1);
pthread_attr_setschedparam(&attr_timer,&sched_param_timer);
pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO-1);
pthread_mutex_init(&timer_mutex,NULL);
error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[eNB][SCHED] FIFO scheduling applied to timer thread \n");
#endif
if (error_code_timer) {
LOG_E(RRH,"Error while creating timer proc thread\n");
exit(-1);
}
}
while (rrh_exit==0)
sleep(1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX,0 );
} //while (eNB_exit==0)
}
rrh_eNB_thread_status = 0;
pthread_exit(&rrh_eNB_thread_status);
......@@ -326,16 +406,7 @@ void *rrh_eNB_thread(void *arg)
}
/*! \fn void *rrh_eNB_rx_thread(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *rrh_eNB_rx_thread(void *arg){
void *rrh_eNB_rx_thread(void *arg) {
/* measuremnt related vars */
struct timespec time0,time1,time2;
......@@ -345,19 +416,23 @@ void *rrh_eNB_rx_thread(void *arg){
struct timespec time_req_1us, time_rem_1us;
rrh_module_t *dev = (rrh_module_t *)arg;
ssize_t bytes_sent;
int i, spp ,pck_rx=0;
openair0_vtimestamp last_hw_counter=0; //volatile int64_t
unsigned int samples_per_frame=0;
int i=0 ,pck_rx=0, s_cnt=0;
openair0_timestamp last_hw_counter=0; //volatile int64_t
unsigned int samples_per_frame=0,samples_per_subframe=0, spp_rf=0, spp_eth=0;
uint8_t loopback=0,measurements=0;
unsigned int subframe=0;
unsigned int frame=0;
//RTIME sleep_ns=1000;
time_req_1us.tv_sec = 0;
time_req_1us.tv_nsec =1000; //time_req_1us.tv_nsec = (int)rt_period/2;--->granularity issue
spp = dev->eth_dev.openair0_cfg.samples_per_packet;
spp_eth = dev->eth_dev.openair0_cfg.samples_per_packet;
spp_rf = dev->devs->openair0_cfg.samples_per_packet;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
samples_per_subframe = (unsigned int)samples_per_frame/10;
loopback = dev->loopback;
measurements = dev->measurements;
next_rx_pos = spp;
next_rx_pos = spp_eth;
#ifdef LOWLATENCY
struct sched_attr attr;
......@@ -369,9 +444,9 @@ void *rrh_eNB_rx_thread(void *arg){
attr.sched_priority = 0;
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = (0.1 * 100) * 10000; //
attr.sched_deadline = rt_period;// 0.1 * 1000000; //
attr.sched_period = rt_period; //0.1 * 1000000; // each TX/RX thread has
attr.sched_runtime = (0.8 * 100) * 10000;//4 * 10000;
attr.sched_deadline = (0.9 * 100) * 10000;//rt_period-2000;
attr.sched_period = 1 * 1000000;//rt_period;
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] eNB RX thread: sched_setattr failed (run with sudo)\n");
......@@ -380,84 +455,88 @@ void *rrh_eNB_rx_thread(void *arg){
#endif
while (rrh_exit == 0) {
while (rx_pos <(1 + subframe)*samples_per_subframe) {
LOG_D(RRH,"starting a new send:%d %d\n",sync_trx,frame);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT, last_hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX, frame);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX, subframe );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK, pck_rx );
LOG_D(RRH,"pack=%d rx_pos=%d subframe=%d frame=%d\n ",pck_rx, rx_pos, subframe,frame);
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++){
if (dev->devs->type == NONE_IF) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT, last_hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, s_cnt );
if (!eNB_rx_started) {
eNB_rx_started=1; // set this flag to 1 to indicate that eNB started
if (RT_flag_eNB==1) {
last_hw_counter=hw_counter;
last_hw_counter=hw_counter;//get current counter
}
} else {
if (RT_flag_eNB==1) {
if (hw_counter > last_hw_counter+1) {
printf("LR");
} else {
while (hw_counter < last_hw_counter+1){
while ((hw_counter < last_hw_counter+1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP, 1 );
nanosleep(&time_req_1us,&time_rem_1us);
//rt_sleep_ns(sleep_ns);
nanosleep(&time_req_1us,&time_rem_1us); //rt_sleep_ns(sleep_ns);
s_cnt++;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP, 0 );
}
}
}
}
}
if (measurements == 1 )
clock_gettime(CLOCK_MONOTONIC,&time1);
/* LOG_I(RRH,"send for%d at %d with %d |%d|%d| \n",i,rx_pos,timestamp_eNB_rx[i],((timestamp_eNB_rx[i]+spp)%samples_per_frame),next_rx_pos );
if ((timestamp_UE_tx[i]%samples_per_frame < next_rx_pos) && (UE_tx_started==1)) {
printf("eNB underflow\n");
if (NRT_flag_eNB==1) {
while ((timestamp_UE_tx[i]%samples_per_frame) < spp)
nanosleep(&time_req_1us,&time_rem_1us);
}
}
if (((rx_pos)< timestamp_UE_tx[i]%samples_per_frame) && (next_rx_pos > (timestamp_UE_tx[i]%samples_per_frame)) && (UE_tx_started==1)) {
printf("eNB underflow\n");
if (NRT_flag_eNB==1) {
while (next_rx_pos > (timestamp_UE_tx[i]%samples_per_frame))
nanosleep(&time_req_1us,&time_rem_1us);
}
}*/
if (measurements == 1 ) clock_gettime(CLOCK_MONOTONIC,&time1);
if (loopback == 1 ) {
if (sync_eNB_rx[i]==0) {
rx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos];
LOG_I(RRH,"tx_buffer_eNB[i][tx_pos]=%d ,tx_pos=%d\n",tx_buffer_eNB[i][tx_pos],tx_pos);
}
else{
} else {
rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos];
LOG_I(RRH,"rx_buffer_eNB[i][rx_pos]=%d ,rx_pos=%d\n",rx_buffer_eNB[i][rx_pos],rx_pos);
}
}
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos];
LOG_D(RRH," rx_eNB[i]=%p rx_buffer_eNB[i][rx_pos]=%p ,rx_pos=%d, i=%d ts=%d\n",rx_eNB[i],&rx_buffer_eNB[i][rx_pos],rx_pos,i,timestamp_rx);
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, rx_pos );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_TS, timestamp_eNB_rx[i]&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
if (dev->devs->type != NONE_IF) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 1 );
/* Read operation to RF device (RX)*/
if ( dev->devs->trx_read_func (dev->devs,
&timestamp_rx,
rx_eNB,
spp_rf,
dev->devs->openair0_cfg.rx_num_channels
)<0) {
perror("RRH eNB : USRP read");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 0 );
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_TS, timestamp_rx&0xffffffff );
//LOG_D(RRH," rx_eNB[i]=%p rx_buffer_eNB[i][rx_pos]=%p ,rx_pos=%d, i=%d ts=%d\n",rx_eNB[i],&rx_buffer_eNB[i][rx_pos],rx_pos,i,timestamp_eNB_rx[i]);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
if ((bytes_sent = dev->eth_dev.trx_write_func (&dev->eth_dev,
timestamp_eNB_rx[i],
timestamp_rx,
rx_eNB,
spp,
i,
0))<0){
perror("RRH eNB : sendto for RX");
spp_eth,
dev->eth_dev.openair0_cfg.rx_num_channels,
0))<0) {
perror("RRH eNB : ETHERNET write");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
timestamp_eNB_rx[i]+=spp;
/* when there is no RF timestamp is updated by number of samples */
if (dev->devs->type == NONE_IF) {
timestamp_rx+=spp_eth;
last_hw_counter=hw_counter;
}
if (measurements == 1 ) {
......@@ -474,7 +553,7 @@ void *rrh_eNB_rx_thread(void *arg){
min_rx_time = total_rx_time;
if (total_rx_time > max_rx_time){
max_rx_time = total_rx_time;
LOG_I(RRH,"Max value %d update at rx_position %d \n",total_rx_time,timestamp_eNB_rx[i]);
LOG_I(RRH,"Max value %d update at rx_position %d \n",total_rx_time,timestamp_rx);
}
average_rx_time = (long long unsigned int)((average_rx_time*trial)+total_rx_time)/(trial+1);
}
......@@ -487,48 +566,64 @@ void *rrh_eNB_rx_thread(void *arg){
memcpy(&time0,&time2,sizeof(struct timespec));
}
if (loopback == 1 ){
if (loopback == 1 ) {
pthread_mutex_lock(&sync_eNB_mutex[i]);
sync_eNB_rx[i]--;
pthread_mutex_unlock(&sync_eNB_mutex[i]);
}
}//for each antenna
rx_pos += spp;
rx_pos += spp_eth;
pck_rx++;
next_rx_pos=(rx_pos+spp);
next_rx_pos=(rx_pos+spp_eth);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 );
/**/
if (frame>50) {
pthread_mutex_lock(&sync_trx_mutex);
while (sync_trx) {
pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex);
}
sync_trx=1;
LOG_D(RRH,"out of while send:%d %d\n",sync_trx,frame);
pthread_cond_signal(&sync_trx_cond);
pthread_mutex_unlock(&sync_trx_mutex);
}
} // while
subframe++;
s_cnt=0;
/* wrap around rx buffer index */
if (next_rx_pos >= samples_per_frame)
next_rx_pos -= samples_per_frame;
if (rx_pos >= samples_per_frame)
rx_pos -= samples_per_frame;
/* wrap around subframe number */
if (subframe == 10 ) {
subframe = 0;
frame++;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 );
} //while (eNB_exit==0)
return(0);
return 0;
}
/*! \fn void *rrh_eNB_tx_thread(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *rrh_eNB_tx_thread(void *arg){
void *rrh_eNB_tx_thread(void *arg) {
struct timespec time0a,time0,time1,time2;
rrh_module_t *dev = (rrh_module_t *)arg;
struct timespec time_req_1us, time_rem_1us;
ssize_t bytes_received;
int spp,i;
int i;
openair0_timestamp last_hw_counter=0;
unsigned int samples_per_frame=0;
unsigned int samples_per_frame=0,samples_per_subframe=0;
unsigned int spp_rf=0, spp_eth=0;
uint8_t loopback=0,measurements=0;
unsigned int subframe=0,frame=0;
unsigned int pck_tx=0;
#ifdef LOWLATENCY
struct sched_attr attr;
......@@ -540,9 +635,9 @@ void *rrh_eNB_tx_thread(void *arg){
attr.sched_priority = 0;
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = (0.1 * 100) * 10000; //
attr.sched_deadline = rt_period;//0.1 * 1000000; //
attr.sched_period = rt_period;//0.1 * 1000000; // each TX/RX thread has
attr.sched_runtime = (0.8 * 100) * 10000;
attr.sched_deadline = (0.9 * 100) * 10000;
attr.sched_period = 1 * 1000000;
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] eNB TX thread: sched_setattr failed\n");
......@@ -550,24 +645,40 @@ void *rrh_eNB_tx_thread(void *arg){
}
#endif
tx_pos=0;
time_req_1us.tv_sec = 0;
time_req_1us.tv_nsec = 1000;
spp = dev->eth_dev.openair0_cfg.samples_per_packet;
time_req_1us.tv_sec = 1;
time_req_1us.tv_nsec = 0;
spp_eth = dev->eth_dev.openair0_cfg.samples_per_packet;
spp_rf = dev->devs->openair0_cfg.samples_per_packet;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
samples_per_subframe = (unsigned int)samples_per_frame/10;
tx_pos=0;
//tx_pos_rf=spp_rf*dev->devs->openair0_cfg.tx_delay;
loopback = dev->loopback;
measurements = dev->measurements;
while (rrh_exit == 0) {
while (tx_pos < (1 + subframe)*samples_per_subframe) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 1 );
LOG_D(RRH,"bef lock read:%d %d\n",sync_trx,frame);
pthread_mutex_lock(&sync_trx_mutex);
while (!sync_trx) {
LOG_D(RRH,"in sync read:%d %d\n",sync_trx,frame);
pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex);
}
LOG_D(RRH,"out of while read:%d %d\n",sync_trx,frame);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, subframe );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, pck_tx );
/*
if (dev->devs->type == NONE_IF) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT, hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT, last_hw_counter );
if (measurements == 1 )
clock_gettime(CLOCK_MONOTONIC,&time0a);
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++){
if (!eNB_tx_started) {
eNB_tx_started=1; // set this flag to 1 to indicate that eNB started
if (RT_flag_eNB==1) {
......@@ -578,7 +689,7 @@ void *rrh_eNB_tx_thread(void *arg){
if (hw_counter > last_hw_counter+1) {
printf("LT");
} else {
while (hw_counter < last_hw_counter+1){
while ((hw_counter < last_hw_counter+1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP, 1 );
nanosleep(&time_req_1us,&time_rem_1us);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP, 0 );
......@@ -586,30 +697,44 @@ void *rrh_eNB_tx_thread(void *arg){
}
}
}
} */
if (measurements == 1 )
clock_gettime(CLOCK_MONOTONIC,&time1);
if (measurements == 1 ) clock_gettime(CLOCK_MONOTONIC,&time1);
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos]; //RF!!!!!
tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos];
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TXCNT, tx_pos );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
bytes_received = dev->eth_dev.trx_read_func(&dev->eth_dev,
&timestamp_eNB_tx[i],
/* Read operation to ETHERNET device */
if (( bytes_received = dev->eth_dev.trx_read_func(&dev->eth_dev,
&timestamp_tx,
tx_eNB,
spp,
i);
spp_eth,
dev->eth_dev.openair0_cfg.tx_num_channels))<0) {
perror("RRH eNB : ETHERNET read");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_eNB_tx[i]&0xffffffff );
if (NRT_flag_eNB==1) {
nrt_eNB_counter[i]++;
if (dev->devs->type != NONE_IF) {
LOG_D(RRH," tx_buffer_eNB[i][tx_pos]=%x t_buffer_eNB[i][tx_pos+1]=%x t_buffer_eNB[i][tx_pos+2]=%x \n",tx_buffer_eNB[0][tx_pos],tx_buffer_eNB[0][tx_pos+1],tx_buffer_eNB[0][tx_pos+2]);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 1 );
/* Write operation to RF device (TX)*/
if ( dev->devs->trx_write_func (dev->devs,
timestamp_tx,
tx_eNB,
spp_rf,
dev->devs->openair0_cfg.tx_num_channels,
0)<0){
perror("RRH eNB : USRP write");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 0 );
}
prev_tx_pos=tx_pos;
tx_pos += spp;
if (tx_pos >= samples_per_frame)
tx_pos -= samples_per_frame;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_tx&0xffffffff );
if (dev->devs->type == NONE_IF) last_hw_counter=hw_counter;
last_hw_counter=hw_counter;
if (loopback ==1 ) {
while (sync_eNB_rx[i]==0)
......@@ -620,28 +745,45 @@ void *rrh_eNB_tx_thread(void *arg){
pthread_mutex_unlock(&sync_eNB_mutex[i]);
}
}
if (measurements == 1 ) {
clock_gettime(CLOCK_MONOTONIC,&time2);
memcpy(&time0,&time2,sizeof(struct timespec));
}
prev_tx_pos=tx_pos;
tx_pos += spp_eth;
pck_tx++;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 );
sync_trx=0;
pthread_cond_signal(&sync_trx_cond);
pthread_mutex_unlock(&sync_trx_mutex);
}
return(0);
/* wrap around tx buffer index */
if (tx_pos >= samples_per_frame)
tx_pos -= samples_per_frame;
/* wrap around subframe number */
subframe++;
if (subframe == 10 ) {
subframe = 0; // the radio frame is complete, start over
frame++;
}
} //while (eNB_exit==0)
return 0;
}
//needs to be fixed
void set_rt_period( openair0_config_t openair0_cfg){
static void calc_rt_period_ns( openair0_config_t openair0_cfg) {
rt_period= (double)(openair0_cfg.samples_per_packet/(openair0_cfg.samples_per_frame/10.0)*1000000);
AssertFatal(rt_period > 0, "Invalid rt period !%u\n", rt_period);
//only in case of NRT with emulated UE
//create_timer_thread();
LOG_I(RRH,"[eNB] Real time period is set to %u ns\n", rt_period);
}
void check_dev_config( rrh_module_t *mod_enb) {
static void check_dev_config( rrh_module_t *mod_enb) {
AssertFatal( (mod_enb->devs->openair0_cfg.num_rb_dl==100 || mod_enb->devs->openair0_cfg.num_rb_dl==50 || mod_enb->devs->openair0_cfg.num_rb_dl==25 || mod_enb->devs->openair0_cfg.num_rb_dl==6) , "Invalid number of resource blocks! %d\n", mod_enb->devs->openair0_cfg.num_rb_dl);
......@@ -656,7 +798,7 @@ void check_dev_config( rrh_module_t *mod_enb) {
AssertFatal( mod_enb->devs->openair0_cfg.tx_gain[0] > 0.0 ,"Invalid TX gain! %f\n", mod_enb->devs->openair0_cfg.tx_gain[0]);
AssertFatal( mod_enb->devs->openair0_cfg.rx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg.rx_bw);
AssertFatal( mod_enb->devs->openair0_cfg.tx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg.tx_bw);
// AssertFatal( mod_enb->devs->openair0_cfg.autocal[0] > 0 , "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg.autocal[0]);
AssertFatal( mod_enb->devs->openair0_cfg.autocal[0] > 0 , "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg.autocal[0]);
printf("\n---------------------RF device configuration parameters---------------------\n");
......
......@@ -2992,22 +2992,6 @@ openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
openair0.func_type = BBU_FUNC;
openair0_cfg[0].log_level = glog_level;
#ifdef ETHERNET
openair0.type=ETH_IF; // not used for the moment
openair0.func_type = BBU_FUNC;
openair0_dev_init_eth(&openair0, &openair0_cfg[0]);
#else
#ifdef EXMIMO
openair0.type=EXMIMO_IF;
printf("Setting the HW to EXMIMO and initializing openair0 ...\n");
#elif OAI_USRP
openair0.type=USRP_IF;
printf("Setting the HW to USRP and initializing openair0 ...\n");
#elif OAI_BLADERF
openair0.type=BLADERF_IF;
printf("Setting the HW to BLADERF and initializing openair0 ...\n");
#endif
if ((mode!=loop_through_memory) &&
(openair0_device_init(&openair0, &openair0_cfg[0]) <0)) {
printf("Exiting, cannot initialize device\n");
......@@ -3015,7 +2999,6 @@ openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
}
else if (mode==loop_through_memory) {
}
#endif
printf("Done\n");
......
......@@ -58,8 +58,8 @@
#define RRH_UE_PORT 51000
#define RRH_UE_DEST_IP "127.0.0.1"
#define FRAME_MAX_SIZE 307200
#define DEFAULT_PERIOD_NS 133333
#define FRAME_MAX_SIZE 307200//76800
#define DEFAULT_PERIOD_NS 133333//200000
#define START_CMD 1
#define PRINTF_PERIOD 3750
......
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Thu Jul 9 09:53:25 2015
[*] Thu Sep 17 14:23:43 2015
[*]
[dumpfile] "/tmp/openair_dump_rrh.vcd"
[dumpfile_mtime] "Thu Jul 9 09:52:29 2015"
[dumpfile_size] 170586112
[savefile] "/home/sud/openair4G/targets/RT/USER/eNB2.gtkw"
[timestart] 16177999000
[size] 1535 876
[dumpfile_mtime] "Thu Sep 17 14:21:43 2015"
[dumpfile_size] 636509125
[savefile] "/home/guepe/openair4G/targets/RT/USER/rrh.gtkw"
[timestart] 17746655400
[size] 1855 1056
[pos] -1 -1
*-17.749426 16178576148 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-15.826077 17746846200 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 224
[signals_width] 230
[sst_expanded] 1
[sst_vpaned_height] 230
[sst_vpaned_height] 287
@24
[color] 1
variables.hw_frame_rx[63:0]
[color] 1
variables.hw_subframe_rx[63:0]
@28
[color] 1
functions.eNB_rx
functions.eNB_rx_sleep
[color] 7
functions.trx_write
functions.trx_write_rf
@c00024
variables.rxcnt[63:0]
@28
......@@ -89,23 +93,27 @@ variables.rxcnt[63:0]
(63)variables.rxcnt[63:0]
@1401200
-group_end
@24
variables.pck_rx[63:0]
variables.hw_frame[63:0]
variables.hw_subframe[63:0]
@28
[color] 1
functions.eNB_tx
functions.eNB_tx_sleep
functions.trx_read_rf
[color] 7
functions.trx_write
[color] 7
functions.trx_read
@24
variables.txcnt[63:0]
variables.rx_ts[63:0]
variables.tx_ts[63:0]
variables.pck_rx[63:0]
variables.hw_cnt_rx[63:0]
variables.lhw_cnt_rx[63:0]
variables.hw_frame[63:0]
@28
functions.eNB_tm
@29
functions.eNB_trx
@25
[color] 3
variables.cnt[63:0]
[pattern_trace] 1
[pattern_trace] 0
......@@ -60,17 +60,17 @@
#include "log_extern.h"
#include "vcd_signal_dumper.h"
//#undef LOWLATENCY
/*****************************************************************************************
* ---------- *
* ------- RRH_BBU_IF ------- RRH_RF_IF -------USRP - COTS_UE- *
* - BBU - --------------- - RRH - ------------- -------BLADERF ---------- *
* ------- ------- -------EXMIMO *
* --------- *
* -------ETH_IF - EMU_UE- *
* --------- *
*****************************************************************************************/
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
static void debug_init(void);
static void get_options(int argc, char *argv[]);
static void print_help(void);
static void get_RFinterfaces(void);
static rrh_module_t new_module(unsigned int id);
int get_ip_address(char* if_name);
char rrh_ip[20] = "192.168.12.242"; // there is code to detect the my ip address
int rrh_port = 50000; // has to be an option
......@@ -98,22 +98,48 @@ uint8_t measurements_flag=0;
/* Default operation as RRH:
- there are neither eNB nor UE modules
- no RF device is asscociated with RRH */
- no RF hardware is specified (NONE_IF)
- default ethernet interface is local */
uint8_t num_eNB_mod=0;
uint8_t num_UE_mod=0;
uint8_t num_EXMIMO_mod=0;
uint8_t num_USRP_mod=0;
uint8_t hardware_target=NONE_IF;
char* if_name="lo";
rrh_module_t *enb_array;
rrh_module_t *ue_array;
pthread_mutex_t timer_mutex;
openair0_vtimestamp hw_counter=0;
unsigned int rt_period=0;
struct itimerspec timerspec;
char* if_name="lo";
static void debug_init(void);
static void get_options(int argc, char *argv[]);
static void print_help(void);
/*!\fn static rrh_module_t new_module(unsigned int id);
* \brief creation of a eNB/UE module
* \param[in] module id
* \return module
* \note
* @ingroup _oai
*/
static rrh_module_t new_module(unsigned int id);
/*!\fn static int get_ip_address(char* if_name)
* \brief retrieves IP address from the specified network interface
* \param[in] name of network interface
* \return 0
* \note
* @ingroup _oai
*/
static int get_ip_address(char* if_name);
int main(int argc, char **argv) {
......@@ -125,58 +151,16 @@ int main(int argc, char **argv) {
debug_init();
/* */
set_latency_target();
/*make a graceful exit when ctrl-c is pressed */
/* make a graceful exit when ctrl-c is pressed */
signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);
/*probe RF front end devices interfaced to RRH */
// get_RFinterfaces();
#ifdef ETHERNET
int error_code_timer;
pthread_t main_timer_proc_thread;
LOG_I(RRH,"Creating timer thread with rt period %d ns.\n",rt_period);
/* setup the timer to generate an interrupt:
-for the first time in (sample_per_packet/sample_rate) ns
-and then every (sample_per_packet/sample_rate) ns */
timerspec.it_value.tv_sec = rt_period/1000000000;
timerspec.it_value.tv_nsec = rt_period%1000000000;
timerspec.it_interval.tv_sec = rt_period/1000000000;
timerspec.it_interval.tv_nsec = rt_period%1000000000;
//#ifndef LOWLATENCY
pthread_attr_t attr_timer;
struct sched_param sched_param_timer;
pthread_attr_init(&attr_timer);
sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr_timer,&sched_param_timer);
pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO);
pthread_mutex_init(&timer_mutex,NULL);
error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] FIFO scheduling applied to timer thread \n");
/*#else
error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] deadline scheduling applied to timer thread \n");
#endif*/
if (error_code_timer) {
LOG_E(RRH,"Error while creating timer proc thread\n");
exit(-1);
}
#endif
/* create modules based on input arguments */
if (eNB_flag==1){
enb_array=(rrh_module_t*)malloc(num_eNB_mod*sizeof(rrh_module_t));
for(i=0;i<num_eNB_mod;i++){
enb_array[i]=new_module(i);//enb_array[i]=new_module(i, get_RF_interfaces(&hardware_target));
create_eNB_trx_threads(&enb_array[i],RT_flag,NRT_flag);
config_BBU_mod(&enb_array[i],RT_flag,NRT_flag);
LOG_I(RRH,"[eNB %d] module(s) created (out of %u) \n",i,num_eNB_mod);
}
}
......@@ -184,7 +168,7 @@ int main(int argc, char **argv) {
ue_array=(rrh_module_t*)malloc(num_UE_mod*sizeof(rrh_module_t));
for(i=0;i<num_UE_mod;i++){
ue_array[i]=new_module(i);
create_UE_trx_threads(&ue_array[i],RT_flag,NRT_flag);
config_UE_mod(&ue_array[i],RT_flag,NRT_flag);
LOG_I(RRH,"[UE %d] module(s) created (out of %u)\n",i, num_UE_mod);
}
}
......@@ -194,22 +178,10 @@ int main(int argc, char **argv) {
while (rrh_exit==0)
sleep(1);
//close sockets
return EXIT_SUCCESS;
}
/*!\fn openair0_device new_module (unsigned int id, dev_type_t type)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static rrh_module_t new_module (unsigned int id) {
rrh_module_t rrh_mod;
......@@ -221,7 +193,9 @@ static rrh_module_t new_module (unsigned int id) {
/* each module is associated with an ethernet device */
rrh_mod.eth_dev.type=ETH_IF;
/* ethernet device is functioning within RRH */
rrh_mod.eth_dev.func_type=RRH_FUNC;
/* specify IP address */
get_ip_address(if_name);
openair0_cfg.my_ip=&rrh_ip[0];
openair0_cfg.my_port=rrh_port;
......@@ -232,7 +206,7 @@ static rrh_module_t new_module (unsigned int id) {
exit(-1);
}
/* specify associated RF device */
/* allocate space and specify associated RF device */
openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_device));
memset(oai_dv,0, sizeof(openair0_device));
......@@ -257,119 +231,6 @@ static rrh_module_t new_module (unsigned int id) {
return rrh_mod;
}
/*! \fn void *timer_proc(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *timer_proc(void *arg) {
timer_t timerid;
struct itimerspec *timer= (struct itimerspec *)arg ; // the timer data structure
struct itimerspec *old_value;
/*
#ifdef LOWLATENCY
struct sched_attr attr;
unsigned int flags = 0;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = (0.1 * 100) * 10000; //
attr.sched_deadline = rt_period-30000;//(0.1 * 100) * 10000; //
attr.sched_period = rt_period;//(0.1 * 100) * 10000; // each TX/RX thread has, as a function of RT PERIOD ??
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] timer thread: sched_setattr failed\n");
exit(-1);
}
#endif
*/
if (timer_create (CLOCK_REALTIME, NULL, &timerid) == -1) {
fprintf (stderr, "couldn't create a timer\n");
perror (NULL);
exit (EXIT_FAILURE);
}
signal(SIGALRM, timer_signal_handler);
LOG_I(RRH,"Timer has started!\n");
timer_settime (timerid, 0, timer, old_value);
while (!rrh_exit) {
sleep(1);
}
timer_delete(timerid);
return (0);
}
/*! \fn void timer_signal_handler(int sig)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void timer_signal_handler(int sig) {
if (sig == SIGALRM) {
pthread_mutex_lock(&timer_mutex);
hw_counter ++;
pthread_mutex_unlock(&timer_mutex);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, hw_counter);
}
}
/*! \fn void signal_handler(int sig)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void signal_handler(int sig) {
void *array[10];
size_t size;
if (sig==SIGSEGV) {
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
exit(-1);
} else {
printf("trying to exit gracefully...\n");
rrh_exit = 1;
}
}
/*! \fn void debug_init(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void debug_init(void) {
// log initialization
......@@ -384,17 +245,10 @@ static void debug_init(void) {
if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd");
}
}
}
/*!\fn void get_options(int argc, char *argv[])
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void get_options(int argc, char *argv[]) {
int opt;
......@@ -457,45 +311,35 @@ static void get_options(int argc, char *argv[]) {
}
/*!\fn void print_help(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
int get_ip_address(char* if_name) {
static int get_ip_address(char* if_name) {
int fd;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "eth0" */
/* I want IP address attached to "if_name" */
strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
perror("IOCTL:");
exit(-1);
}
close(fd);
/* display result */
snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
printf("Got IP address %s from interface %s\n", rrh_ip,if_name);
LOG_I(RRH,"Got IP address %s from interface %s\n", rrh_ip,if_name);
return 0;
}
/*!\fn void print_help(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void print_help(void) {
puts("Usage: \n");
......@@ -504,7 +348,7 @@ static void print_help(void) {
puts("\t -n create eNB module\n");
puts("\t -u create UE module\n");
puts("\t -g define global log level\n");
puts("\t -i set the RRH interface (default eth0)\n");
puts("\t -i set the RRH interface (default lo)\n");
puts("\t -r define rrh log level\n");
puts("\t -e define eNB log level\n");
puts("\t -x enable real time bahaviour\n");
......@@ -516,84 +360,90 @@ static void print_help(void) {
}
/*! \fn void exit_fun(const char* s)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void exit_fun(const char* s)
{
if (s != NULL) {
printf("%s %s() Exiting RRH: %s\n",__FILE__, __FUNCTION__, s);
void *timer_proc(void *arg) {
timer_t timerid;
struct itimerspec *timer= (struct itimerspec *)arg ; // the timer data structure
struct itimerspec *old_value;
#ifdef LOWLATENCY
struct sched_attr attr;
unsigned int flags = 0;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = (0.1 * 100) * 10000; //
attr.sched_deadline = rt_period-30000;//(0.1 * 100) * 10000;
attr.sched_period = rt_period;//(0.1 * 100) * 10000; // each TX/RX thread has, as a function of RT PERIOD ??
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] timer thread: sched_setattr failed\n");
exit(-1);
}
rrh_exit = 1;
exit (-1);
}
#endif
if (timer_create (CLOCK_REALTIME, NULL, &timerid) == -1) {
fprintf (stderr, "couldn't create a timer\n");
perror (NULL);
exit (EXIT_FAILURE);
}
/*! \fn static void get_RFinterfaces(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void get_RFinterfaces(void) {
signal(SIGALRM, timer_signal_handler);
LOG_I(RRH,"Timer has started!\n");
timer_settime (timerid, 0, timer, old_value);
EXMIMO_flag=1;
USRP_flag=1;
num_EXMIMO_mod=1;
num_USRP_mod=1;
while (!rrh_exit) {
sleep(1);
}
}
timer_delete(timerid);
return (0);
}
/*!\fn void create_timer_thread(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void create_timer_thread() {
int error_code_timer;
pthread_t main_timer_proc_thread;
void timer_signal_handler(int sig) {
LOG_I(RRH,"Creating timer thread with rt period %d ns.\n",rt_period);
if (sig == SIGALRM) {
pthread_mutex_lock(&timer_mutex);
hw_counter ++;
pthread_mutex_unlock(&timer_mutex);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, hw_counter);//USED ELSEWHERE
}
}
/* setup the timer to generate an interrupt:
-for the first time in (sample_per_packet/sample_rate) ns
-and then every (sample_per_packet/sample_rate) ns */
timerspec.it_value.tv_sec = rt_period/1000000000;
timerspec.it_value.tv_nsec = rt_period%1000000000;
timerspec.it_interval.tv_sec = rt_period/1000000000;
timerspec.it_interval.tv_nsec = rt_period%1000000000;
pthread_mutex_init(&timer_mutex,NULL);
void signal_handler(int sig) {
#ifndef LOWLATENCY
pthread_attr_t attr_timer;
struct sched_param sched_param_timer;
void *array[10];
size_t size;
pthread_attr_init(&attr_timer);
sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO-1);
pthread_attr_setschedparam(&attr_timer,&sched_param_timer);
pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO-1);
error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] FIFO scheduling applied to timer thread \n");
#else
error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] deadline scheduling applied to timer thread \n");
#endif
if (sig==SIGSEGV) {
// get void*'s for all entries on the stack
size = backtrace(array, 10);
if (error_code_timer) {
LOG_E(RRH,"Error while creating timer proc thread\n");
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
exit(-1);
} else {
printf("trying to exit gracefully...\n");
rrh_exit = 1;
}
}
void exit_fun(const char* s) {
if (s != NULL) {
printf("%s %s() Exiting RRH: %s\n",__FILE__, __FUNCTION__, s);
}
rrh_exit = 1;
exit (-1);
}
......@@ -45,41 +45,68 @@
#include "vcd_signal_dumper.h"
#include "assertions.h"
#define DEFAULT_PERIOD_NS 200000
#define DEFAULT_PERIOD_NS 200000 /* default value is calculated for 25 PRB */
#define RRH_UE_PORT 51000
#define RRH_UE_DEST_IP "127.0.0.1"
/*! \brief RRH supports two types of modules: eNB and UE
each module is associated a device of type ETH_IF
and optionally with an RF device (USRP/BLADERF/EXMIMO) */
each module is associated with an ethernet device (device of ETH_IF)
and optionally with a RF device (device type can be USRP_IF/BLADERF_IF/EXMIMO_IF/NONE_IF)
UE modules will always have RF device type NONE_IF */
typedef struct {
//! module id
/*! \brief module id */
uint8_t id;
//! loopback flag
uint8_t loopback;
//! measurement flag
uint8_t measurements;
//! module's ethernet device
openair0_device eth_dev;
//! pointer to RF module's device (pointer->since its optional)
openair0_device *devs;
/*! \brief! loopback flag */
uint8_t loopback;
/*! \brief measurement flag */
uint8_t measurements;
/*! \brief module's ethernet device */
openair0_device eth_dev;
/*! \brief pointer to RF module's device (pointer->since it's optional) */
openair0_device *devs;
}rrh_module_t;
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void signal_handler(int sig);
/*! \fn void timer_signal_handler(int sig)
* \brief this function
* \param[in] signal type
* \return none
* \note
* @ingroup _oai
*/
void timer_signal_handler(int);
/*! \fn void *timer_proc(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *timer_proc(void *);
void create_timer_thread(void);
/*! \fn void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag,uint8_t NRT_flag)
* \brief receive and apply configuration to modules' optional device
* \param[in] *mod_enb pointer to module
* \param[in] RT_flag real time flag
* \return none
* \note
* @ingroup _oai
*/
void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag);
/*! \fn void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag)
* \brief this function
* \param[in] *mod_ue pointer to module
* \param[in]
* \return none
* \note
* @ingroup _oai
*/
void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag, uint8_t NRT_flag);
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void create_UE_trx_threads( rrh_module_t *dev_ue, uint8_t RT_flag, uint8_t NRT_flag);
void create_eNB_trx_threads( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag);
void signal_handler(int sig);
#endif
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