diff --git a/CMakeLists.txt b/CMakeLists.txt index b54130b30a9e3b6601e4caccbb9d718cb2645335..4092ae54a1a05e2c068c4312738b637bbab91544 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2185,39 +2185,6 @@ target_link_libraries(lte-softmodem PRIVATE ${T_LIB}) target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc asn1_lte_rrc) -add_executable(ocp-enb - ${OPENAIR_DIR}/executables/main-ocp.c - ${OPENAIR_DIR}/executables/softmodem-common.c - ${OPENAIR_DIR}/executables/main-fs6.c - ${OPENAIR_DIR}/executables/transport_split.c - ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c - ${OPENAIR_DIR}/executables/create_tasks.c - ${OPENAIR_DIR}/executables/create_tasks_mbms.c - ${OPENAIR_DIR}/radio/COMMON/common_lib.c - ${OPENAIR_DIR}/radio/COMMON/record_player.c - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c - ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c - ${OPENAIR_DIR}/common/utils/lte/ue_power.c - ${OPENAIR_DIR}/common/utils/lte/prach_utils.c - ${PHY_INTERFACE_DIR}/queue_t.c - ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c - ${T_SOURCE} - ${SHLIB_LOADER_SOURCES} - ) -add_dependencies(ocp-enb oai_iqplayer coding params_libconfig rfsimulator) - -target_link_libraries (ocp-enb - -Wl,--start-group - lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU - ${RAL_LIB} ${NAS_UE_LIB} ITTI - -Wl,--end-group z dl) -target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${CMAKE_DL_LIBS} ${LIB_LMS_LIBRARIES} ${T_LIB}) - add_executable(oairu ${OPENAIR_DIR}/executables/lte-ru.c ${OPENAIR_DIR}/executables/ru_control.c diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 813dc39a6a509935ee3d8e7e17ff51a379f1c6fe..05174fec9067bf72ee281e32a02b726bc51bc6c6 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -181,12 +181,10 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') - if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem' - elif (air_interface.lower() in ['nr','lte']): + else: RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem' - else : - RAN.air_interface[RAN.eNB_instance] = 'ocp-enb' cmd_prefix = test.findtext('cmd_prefix') if cmd_prefix is not None: RAN.cmd_prefix = cmd_prefix @@ -213,12 +211,10 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') - if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem' - elif (air_interface.lower() in ['nr','lte']): + else: RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem' - else : - RAN.air_interface[RAN.eNB_instance] = 'ocp-enb' elif action == 'Initialize_UE': ue_id = test.findtext('id') @@ -280,12 +276,11 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') - if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): CiTestObj.air_interface = 'lte-uesoftmodem' elif (air_interface.lower() in ['nr','lte']): CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem' else : - #CiTestObj.air_interface = 'ocp-enb' logging.error('OCP UE -- NOT SUPPORTED') CiTestObj.cmd_prefix = test.findtext('cmd_prefix') or "" @@ -299,13 +294,10 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') - if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): CiTestObj.air_interface = 'lte-uesoftmodem' - elif (air_interface.lower() in ['nr','lte']): + else: CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem' - else : - #CiTestObj.air_interface = 'ocp-enb' - logging.error('OCP UE -- NOT SUPPORTED') elif (action == 'Ping') or (action == 'Ping_CatM_module'): CiTestObj.ping_args = test.findtext('ping_args') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index cb2546bc22ac5643b8e069bd46608c130e457e7a..f52e066f3fcb2a72a5235ea8bf2b9576c1a06b2f 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -131,20 +131,16 @@ class RANManagement(): mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) - # Check if we build an 5G-NR gNB or an LTE eNB or an OCP eNB - result = re.search('--eNBocp', self.Build_eNB_args) + # Check if we build an 5G-NR gNB or an LTE eNB + result = re.search('--RU', self.Build_eNB_args) if result is not None: - self.air_interface[self.eNB_instance] = 'ocp-enb' + self.air_interface[self.eNB_instance] = 'oairu' else: - result = re.search('--RU', self.Build_eNB_args) + result = re.search('--gNB', self.Build_eNB_args) if result is not None: - self.air_interface[self.eNB_instance] = 'oairu' + self.air_interface[self.eNB_instance] = 'nr-softmodem' else: - result = re.search('--gNB', self.Build_eNB_args) - if result is not None: - self.air_interface[self.eNB_instance] = 'nr-softmodem' - else: - self.air_interface[self.eNB_instance] = 'lte-softmodem' + self.air_interface[self.eNB_instance] = 'lte-softmodem' # Worakround for some servers, we need to erase completely the workspace if self.Build_eNB_forced_workspace_cleanup: @@ -286,7 +282,7 @@ class RANManagement(): mySSH.command('ls ran_build/build', '\$', 3) mySSH.command('ls ran_build/build', '\$', 3) - #check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb) + #check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem) logging.info('CHECK Build with IP='+lIpAddr+' SourcePath='+lSourcePath) result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore()) if result is None: @@ -372,7 +368,7 @@ class RANManagement(): #Get pcap on enb and/or gnb if enabled in the xml if self.eNB_Trace=='yes': - if ((self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb')): + if self.air_interface[self.eNB_instance] == 'lte-softmodem': pcapfile_prefix="enb_" else: pcapfile_prefix="gnb_" @@ -457,7 +453,7 @@ class RANManagement(): #hack UHD_RFNOC_DIR variable for gNB / N310 on RHEL8 server: #if the USRP address is in the xml then we are using an eth USRP (N3xx) - if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): + if self.air_interface[self.eNB_instance] == 'lte-softmodem': gNB = False else: gNB = True @@ -473,7 +469,7 @@ class RANManagement(): monitor_file='../ci-scripts/stats_monitor.py' conf_file='../ci-scripts/stats_monitor_conf.yaml' if self.eNB_Stats=='yes': - if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): + if self.air_interface[self.eNB_instance] == 'lte-softmodem': mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' ' + self.testCase_id + ' enb 2>&1 > enb_stats_monitor_execution.log &', '\$', 5) else: mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' ' + self.testCase_id + ' gnb 2>&1 > gnb_stats_monitor_execution.log &', '\$', 5) @@ -496,7 +492,7 @@ class RANManagement(): mySSH.command('killall --signal SIGKILL record', '\$', 5) mySSH.close() doLoop = False - logging.error('\u001B[1;37;41m eNB/gNB/ocp-eNB logging system did not show got sync! \u001B[0m') + logging.error('\u001B[1;37;41m eNB/gNB logging system did not show got sync! \u001B[0m') HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK) # In case of T tracer recording, we need to kill tshark on EPC side localEpcIpAddr = EPC.IPAddress @@ -553,7 +549,7 @@ class RANManagement(): HTML.CreateHtmlTestRow(f'{self.cmd_prefix} {self.air_interface[self.eNB_instance]} -O {config_file} {extra_options}', 'OK', CONST.ALL_PROCESSES_OK) - logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m') + logging.debug('\u001B[1m Initialize eNB/gNB Completed\u001B[0m') def CheckeNBProcess(self, status_queue): try: @@ -614,19 +610,19 @@ class RANManagement(): mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): + if self.air_interface[self.eNB_instance] == 'lte-softmodem': nodeB_prefix = 'e' else: nodeB_prefix = 'g' - mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) - result = re.search('(-softmodem|ocp)', mySSH.getBefore()) + mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem | grep -v grep', '\$', 5) + result = re.search('-softmodem', mySSH.getBefore()) if result is not None: - mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem ocp-enb || true', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5) time.sleep(10) - mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) - result = re.search('(-softmodem|ocp)', mySSH.getBefore()) + mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem | grep -v grep', '\$', 5) + result = re.search('-softmodem', mySSH.getBefore()) if result is not None: - mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem ocp-enb || true', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5) time.sleep(5) mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) #stopping tshark (valid if eNB and enabled in xml, will not harm otherwise) @@ -1088,7 +1084,7 @@ class RANManagement(): #post processing depending on the node type if not nodeB_prefix_found: - if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): + if self.air_interface[self.eNB_instance] == 'lte-softmodem': nodeB_prefix = 'e' else: nodeB_prefix = 'g' diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml deleted file mode 100644 index eebe62b3b581a345e1dae3e839431ed6d079124d..0000000000000000000000000000000000000000 --- a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml +++ /dev/null @@ -1,147 +0,0 @@ -<!-- - - Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The OpenAirInterface Software Alliance licenses this file to You under - the OAI Public License, Version 1.1 (the "License"); you may not use this file - except in compliance with the License. - You may obtain a copy of the License at - - http://www.openairinterface.org/?page_id=698 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - For more information about the OpenAirInterface (OAI) Software Alliance: - contact@openairinterface.org - ---> -<testCaseList> - <htmlTabRef>test-05-tm1</htmlTabRef> - <htmlTabName>Test-05MHz-TM1</htmlTabName> - <htmlTabIcon>tasks</htmlTabIcon> - <repeatCount>1</repeatCount> - <TestCaseRequestedList> - 030201 - 040101 - 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 - </TestCaseRequestedList> - <TestCaseExclusionList></TestCaseExclusionList> - - <testCase id="030101"> - <class>Initialize_eNB</class> - <desc>Initialize OCP-eNB (FDD/Band7/5MHz)</desc> - <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args> - <air_interface>ocp</air_interface> - </testCase> - - <testCase id="030201"> - <class>Terminate_eNB</class> - <desc>Terminate OCP-eNB</desc> - <air_interface>ocp</air_interface> - </testCase> - - <testCase id="040101"> - <class>Initialize_UE</class> - <desc>Initialize UE</desc> - </testCase> - - <testCase id="040201"> - <class>Terminate_UE</class> - <desc>Terminate UE</desc> - </testCase> - - <testCase id="040301"> - <class>Attach_UE</class> - <desc>Attach UE</desc> - </testCase> - - <testCase id="040401"> - <class>Detach_UE</class> - <desc>Detach UE</desc> - </testCase> - - <testCase id="040501"> - <class>Ping</class> - <desc>ping (5MHz - 20 sec)</desc> - <ping_args>-c 20</ping_args> - <ping_packetloss_threshold>5</ping_packetloss_threshold> - </testCase> - - <testCase id="040603"> - <class>Iperf</class> - <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc> - <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>balanced</iperf_profile> - </testCase> - - <testCase id="040604"> - <class>Iperf</class> - <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc> - <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>single-ue</iperf_profile> - </testCase> - - <testCase id="040605"> - <class>Iperf</class> - <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile)</desc> - <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>unbalanced</iperf_profile> - </testCase> - - <testCase id="040606"> - <class>Iperf</class> - <desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc> - <iperf_args>-t 30 -i 1 -fm</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>single-ue</iperf_profile> - </testCase> - - <testCase id="040607"> - <class>Iperf</class> - <desc>iperf (5MHz - DL/TCP)(30 sec)(balanced profile)</desc> - <iperf_args>-t 30 -i 1 -fm</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>balanced</iperf_profile> - </testCase> - - <testCase id="040641"> - <class>Iperf</class> - <desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc> - <iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>balanced</iperf_profile> - </testCase> - - <testCase id="040642"> - <class>Iperf</class> - <desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc> - <iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>single-ue</iperf_profile> - </testCase> - - <testCase id="040643"> - <class>Iperf</class> - <desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue profile)</desc> - <iperf_args>-t 30 -i 1 -fm -R</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>single-ue</iperf_profile> - </testCase> - - <testCase id="040644"> - <class>Iperf</class> - <desc>iperf (5MHz - UL/TCP)(30 sec)(balanced profile)</desc> - <iperf_args>-t 30 -i 1 -fm -R</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>balanced</iperf_profile> - </testCase> - -</testCaseList> diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml deleted file mode 100644 index 33a0fc205e0855de99602abc4f7394e89ad98963..0000000000000000000000000000000000000000 --- a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml +++ /dev/null @@ -1,38 +0,0 @@ -<!-- - - Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The OpenAirInterface Software Alliance licenses this file to You under - the OAI Public License, Version 1.1 (the "License"); you may not use this file - except in compliance with the License. - You may obtain a copy of the License at - - http://www.openairinterface.org/?page_id=698 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - For more information about the OpenAirInterface (OAI) Software Alliance: - contact@openairinterface.org - ---> -<testCaseList> - <htmlTabRef>build-tab</htmlTabRef> - <htmlTabName>Build</htmlTabName> - <htmlTabIcon>wrench</htmlTabIcon> - <TestCaseRequestedList> - 010101 - </TestCaseRequestedList> - <TestCaseExclusionList></TestCaseExclusionList> - - <testCase id="010101"> - <class>Build_eNB</class> - <desc>Build eNB OCP (USRP)</desc> - <Build_eNB_args>-w USRP -c --eNBocp --ninja</Build_eNB_args> - </testCase> - -</testCaseList> diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 578eaed570bdeeff87cb6a11886d83742b17a67a..d05bbcce806a877e2abaf8eb75f68e8c4fc8d0f1 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -92,8 +92,6 @@ Options: enable cmake debugging messages --eNB Makes the LTE softmodem ---eNBocp - Makes the OCP LTE softmodem --gNB Makes the NR softmodem --RU @@ -247,10 +245,6 @@ function main() { eNB=1 echo_info "Will compile eNB" shift;; - --eNBocp) - eNBocp=1 - echo_info "Will compile OCP eNB" - shift;; --gNB) gNB=1 echo_info "Will compile gNB" @@ -450,7 +444,7 @@ function main() { ######################################################## # to be discussed - if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$gNB" = "1" ] ; then + if [ "$eNB" = "1" -o "$gNB" = "1" ] ; then if [ "$HW" = "None" -a "$TP" = "None" ] ; then echo_info "No local radio head and no transport protocol selected" fi @@ -525,9 +519,6 @@ function main() { if [ "$eNB" = "1" ] ; then execlist="$execlist lte-softmodem" fi - if [ "$eNBocp" = "1" ] ; then - execlist="$execlist ocp-enb" - fi if [ "$gNB" = "1" ] ; then execlist="$execlist nr-softmodem nr-cuup" fi @@ -653,7 +644,7 @@ function main() { #################################################### # Build RF device and transport protocol libraries # #################################################### - if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" ] ; then + if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" ] ; then # build RF device libraries if [ "$HW" != "None" ] ; then diff --git a/common/utils/assertions.h b/common/utils/assertions.h index c8959d0adb15b0bbc4478cde7a162851361432eb..b2916139e0c528512fdb3d5829f954816989e623 100644 --- a/common/utils/assertions.h +++ b/common/utils/assertions.h @@ -28,7 +28,6 @@ #include <sys/types.h> #include <unistd.h> #include <platform_types.h> -#include "backtrace.h" #define _Assert_Exit_ \ if (getenv("gdbStacks")) { \ diff --git a/doc/Doxyfile b/doc/Doxyfile index 1fb88bba746a45a0832be755050cbeae4b91c603..400d99305e4a2966985bd02fcf5b2ed44c513e13 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -2547,7 +2547,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../executables/create_tasks.h \ @CMAKE_CURRENT_SOURCE_DIR@/../executables/softmodem-common.c \ @CMAKE_CURRENT_SOURCE_DIR@/../executables/rt_profiling.h \ -@CMAKE_CURRENT_SOURCE_DIR@/../executables/split_headers.h \ @CMAKE_CURRENT_SOURCE_DIR@/../executables/create_tasks.c \ @CMAKE_CURRENT_SOURCE_DIR@/../executables/nr-uesoftmodem.c \ @CMAKE_CURRENT_SOURCE_DIR@/../executables/nr-uesoftmodem.h \ diff --git a/doc/SystemX-tutorial-design.md b/doc/SystemX-tutorial-design.md index 3e4496f7de6c22811d99984777fde9008bc8e282..804658fd4d288266a275d8bffa6df976bbe07371 100644 --- a/doc/SystemX-tutorial-design.md +++ b/doc/SystemX-tutorial-design.md @@ -109,196 +109,6 @@ route add default oaitun_ue1 or specify the outgoing route in the traffic generator (like option “-I†in ping command). -## Split 6 DL 4G - -The contract describes to reuse the uplink existing if4p5 and to develop -is this work the downlink “functional split 6â€. - -The customer required after signature to develop also the uplink -functional split 6. This is accepted, as long as the whole work is -research with no delivery completeness warranty. - -### Simulation - -To be able to verify the new features and to help in all future -developments, Open Cells added and improved the Rf board simulator -during this contract. - -We added the channel modeling simulation, that offer to simulate various -3GPP defined channels. - -### Main loop - -The main log is in RF simulator is in - - `targets/RT/USER/lte-ru.c and targets/RT/USER/lte-enb.c` - -As this piece of SW is very complex and doesn’t meet our goals -(functional split 6), a cleaned version replaces these 2 files in -executables/ocp-main.c (openair1/SCHED/prach\_procedures.c is also -replaced by this new file as it only launching the RACH actual work in a -way not compatible with our FS6). - -The main loop cadences the I/Q samples reception, signal processing and -I/Q samples sending. - -The main loop uses extensively function pointers to call the right -processing function depending on the split case. - -A lot of OAI reduntant global variables contains the same semantic data: time,frame, subframe. -The reworked main loop take care of a uniq variable that comes directly from harware: RF board sampling number. - -To use OAI, we need to set all OAI variables that derivates from this timestamp value. The function setAllfromTS() implements this. - -### Splitted main level - -When FS6 is actived, a main loop for DU (du_fs6()) a main loop for CU case replaces the uniq eNB main loop. - -Each of these main loops calls initialization of OAI LTE data and the FS6 transport layer initialization. - -Then, it runs a infinite loop on: set time, call UL and DL. The time comes from the RF board, so the DU sends the time to the CU. - -This is enough for RF board dialog, but the FS6 is higher in SW layers, -we need to cut higher functions inside downlink and uplink procedures. - -As much as possible, the FS6 code is in the directory OPENAIR_DIR/executables. When a given OAI piece of code is small or need complex changes, it is reworked in the file fs6-main.c. The functions naming keeps the OAI function name, adding suffix _fromsplit() or _tosplit(). - -When this organization would lead to large code copy, it is better to insert modifications in OAI code. This is done in two files: - -- openair1/SCHED/phy_procedures_lte_eNb.c: to send signaling channels computation results - - the function sendFs6Ulharq() centralizes all signaling channels forwarding to CU -- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c: to deal with FS6 user plane split - - sendFs6Ul() is used once to forward user plane to CU - - -### DownLink - -The main procedure is phy\_procedures\_eNB\_TX() - -This is building the common channels (beacon, multi-UE signaling). - -The FS6 split breaks this function into pieces: - -* The multi-UE signals, built by common\_signal\_procedures(), - subframe2harq\_pid(), generate\_dci\_top(), subframe2harq\_pid() - * These functions run in the DU, nevertheless all context has to be sent - (it is also needed partially for UL spitting) - * Run in the DU also to meet the requirement of pushing - in DU the data encoded with large redundancy (>3 redundancy) - -* the per UE data: pdsch\_procedures() needs further splitting: - - * dlsch\_encoding\_all() that makes the encoding: turbo code - and lte\_rate\_matching\_turbo() that will be in the DU (some - unlikely cases can reach redundancy up to x3, when MCS is very - low (negative SINR cases)). - - * dlsch\_encoding() output needs to be transmitted between the - DU and the CU for functional split 6. - * dlsch\_scrambling() that will go in the DU - * dlsch\_modulation() that will go in the DU - - The du user plane data is made of expanded bit in OAI at FS6 split level. 1 pair of functions compact back these bits into 8bits/byte before sending data and expand it again in the DU data reception (functions: fs6Dl(un)pack()). - -### Uplink - -The uplink require configuration that is part of the DL transmission. - -It interprets the signalling to extract the RACH and the per UE data -channels. - -Ocp-main.c:rxtx() calls directly the entry procedure -phy\_procedures\_eNB\_uespec\_RX() calls: - -* rx\_ulsch() that demodulate and extract soft bits per UE. - - * This function runs in the DU - * the output data will be processes in the DU, so it needs to be - transmitted to the DU -* ulsch\_decoding() that do lte\_rate\_matching\_turbo\_rx() - sub\_block\_deinterleaving\_turbo() - then turbo decode that is in the CU -* fill\_ulsch\_cqi\_indication() fill\_crc\_indication() , fill\_rx\_indication() - * DU performs the signal processing of each channel data, prepare and sent to the CU the computed result - -* Random access channel detection runs in the DU - * the DU reports to the CU only the detected temprary identifier for RACH response - - -### signaling data in each direction (UL and DL) - - -* each LTE channel needs to be propagated between CU and DU - * the simplest are the almost static data such as PSS/SSS, that need only static eNB parameters and primary information (frame numbering) - * all the other channels require data transmission CU to DU and DU to CU - * the general design push all the low level processing for these channels in the DU - * the CU interface transports only signal processing results (UL) or configuration to create the RF signal (DL case) -* HARQ is detected in the DU, then only the ACK or NACK is reported to CU - -* the CU have to control the power and MCS (modulation and coding scheme) - * the DU performs the signal processing and report only the decoded data like the CQI - * as the DU performas the modulation, scrambling and puncturing, each data packet is associated with the LTE parameters required for these features - * in DL, the CU associates the control parameters and the user plane data - * in UL, the CU sends upfront the scheduled UL data to the DU. So, the DU have the required knowledge to decode the next subframes in time. - -### UDP transport layer - -A general UDP transport layer is in executables/transport\_split.c - -Linux offers a UDP socket builtin timeout, that we use. - -In and out buffers are memory zones that contains compacted -(concatenated) UDP chunks. - -For output, sendSubFrame() sends each UDP chunk - -For input, receiveSubFrame() collects all UDP chunks for a group (a -subframe in OAI LTE case). It returns in the following cases: - -- all chunks are received -- a timeout expired -- a chunk from the next subframe already arrived - -### Functional split 6 usage - -The ocp cleaned main hale to be used: run ocp-softmodem instead of -lte-softmodem. - -The functionality and parameters is the same, enhanced with FS6 mode. - -The end line option “--split73†enables the fs6 (also called split 7.3) mode and decided to be cu or du. - -Example: - -```bash -./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 cu:127.0.0.1 -``` - -Run the CU init of the split 6 eNB, that will call du on 127.0.0.1 address - -```bash -./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 du:127.0.0.1 -``` - -will run the du, calling the cu on 127.0.0.1 - -If the CU and the DU are not on the same machine, the remote address of each side need to be specified as per this example - -```bash -./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 du:192.168.1.55 -``` - -runs the functional split 6 DU - -```bash -./lte-uesoftmodem -C 2685000000 -r 50 --rfsim --rfsimulator.serveraddr 192.168.1.1 -d -``` - -Runs the UE (to have the UE signal scope, compile it with make uescope) - -CU+DU+UE can run with option `--noS1` to avoid to use a EPC and/or with `--rfsim` to simulate RF board - - ## 5G and F1 Today 5G achievement is limited to physical layer. diff --git a/executables/create_tasks.c b/executables/create_tasks.c index 97e8880e9c15bf55ccdb7f758da1817739e03d39..8382cc4074cc6a5bc35369cde9e83d5aa0c348aa 100644 --- a/executables/create_tasks.c +++ b/executables/create_tasks.c @@ -36,7 +36,6 @@ #include "RRC/LTE/rrc_defs.h" # include "enb_app.h" # include "openair2/LAYER2/MAC/mac_proto.h" -#include <executables/split_headers.h> #include <openair3/ocp-gtpu/gtp_itf.h> extern RAN_CONTEXT_t RC; @@ -52,12 +51,13 @@ int create_tasks(uint32_t enb_nb) { AssertFatal(rc >= 0, "Create task for eNB APP failed\n"); rrc_enb_init(); itti_mark_task_ready(TASK_RRC_ENB); - if (get_softmodem_params()->emulate_l1 || (EPC_MODE_ENABLED && split73 != SPLIT73_DU)) { + + if (get_softmodem_params()->emulate_l1 || EPC_MODE_ENABLED) { rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); AssertFatal(rc >= 0, "Create task for SCTP failed\n"); } - if (EPC_MODE_ENABLED && ! ( split73==SPLIT73_DU ) ) { + if (EPC_MODE_ENABLED) { rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL); AssertFatal(rc >= 0, "Create task for S1AP failed\n"); rc = itti_create_task(TASK_GTPV1_U, gtpv1uTask, NULL); diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index bdfa4c2335d0b225cd781fef3144adb16d447427..7c25548349aeb8a8ef45cea6290942890f2ab24d 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -84,7 +84,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "lte-softmodem.h" #include "NB_IoT_interface.h" -#include <executables/split_headers.h> #if USING_GPROF # include "sys/gmon.h" @@ -146,14 +145,6 @@ int otg_enabled; uint64_t num_missed_slots=0; // counter for the number of missed slots -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) { - AssertFatal(false, "Must not be called in this context\n"); -} - RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond); RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond); diff --git a/executables/main-fs6.c b/executables/main-fs6.c deleted file mode 100644 index 51bf6d166e992eefc8e464bf8a739e51aa2fd611..0000000000000000000000000000000000000000 --- a/executables/main-fs6.c +++ /dev/null @@ -1,1667 +0,0 @@ -/* -* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The OpenAirInterface Software Alliance licenses this file to You under -* the OAI Public License, Version 1.1 (the "License"); you may not use this file -* except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.openairinterface.org/?page_id=698 -* -* Author and copyright: Laurent Thomas, open-cells.com -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*------------------------------------------------------------------------------- -* For more information about the OpenAirInterface (OAI) Software Alliance: -* contact@openairinterface.org -*/ - -#include <stdint.h> -#include <common/utils/LOG/log.h> -#include <common/utils/system.h> -#include <common/config/config_userapi.h> -#include "executables/lte-softmodem.h" -#include <openair1/PHY/defs_eNB.h> -#include <openair1/PHY/phy_extern.h> -#include <nfapi/oai_integration/vendor_ext.h> -#include <openair1/SCHED/fapi_l1.h> -#include <openair1/PHY/INIT/phy_init.h> -#include <openair2/LAYER2/MAC/mac_extern.h> -#include <openair1/PHY/LTE_REFSIG/lte_refsig.h> -#include <nfapi/oai_integration/nfapi_pnf.h> -#include <executables/split_headers.h> -#include <nfapi/oai_integration/vendor_ext.h> -#include <openair1/PHY/INIT/lte_init.c> -#include <openair1/PHY/LTE_ESTIMATION/lte_estimation.h> -#include <executables/split_headers.h> -#include <openair1/PHY/CODING/coding_extern.h> -#include <threadPool/thread-pool.h> -#include "PHY/sse_intrin.h" - -#define FS6_BUF_SIZE 1000*1000 -static UDPsock_t sockFS6; - -int sum(uint8_t *b, int s) { - int sum=0; - - for (int i=0; i < s; i++) - sum+=b[i]; - - return sum; -} - - -extern double cpuf; - -typedef struct m { - uint64_t iterations; - uint64_t sum; - uint64_t maxArray[11]; -} Meas; - -int cmpint(const void *a, const void *b) -{ - uint64_t *aa=(uint64_t *)a; - uint64_t *bb=(uint64_t *)b; - return (int)(*aa-*bb); -} - -static inline void printMeas(char *txt, - Meas *M, - int period) -{ - if (M->iterations%period == 0 ) { - char txt2[512]; - sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" - PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", - txt, - M->sum/M->iterations, - M->iterations, - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], - M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); -#if T_TRACER - LOG_W(PHY,"%s",txt2); -#else - printf("%s",txt2); -#endif - } -} - -void updateTimes(uint64_t start, Meas *M, int period, char *txt) -{ - if (start!=0) { - uint64_t end=rdtsc_oai(); - long long diff=(end-start)/(cpuf*1000); - M->maxArray[0]=diff; - M->sum+=diff; - M->iterations++; - qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); - printMeas(txt,M,period); - } -} - -#define initStaticTime(a) static __thread uint64_t a={0} -#define pickStaticTime(a) do { a=rdtsc_oai(); } while (0) -#define initRefTimes(a) static __thread Meas a= {0} -static inline int cmpintRev(const void *a, const void *b) { - uint64_t *aa=(uint64_t *)a; - uint64_t *bb=(uint64_t *)b; - return (int)(*bb-*aa); -} - -static inline void printMeas2(char *txt, Meas *M, int period, bool MaxMin) { - if (M->iterations%period == 0 ) { - char txt2[512]; - sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " %s=%" - PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", - txt, - M->sum/M->iterations, - M->iterations, - MaxMin?"max":"min", - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], - M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); -#if T_TRACER - LOG_W(PHY,"%s",txt2); -#else - printf("%s",txt2); -#endif - } -} - -static inline void updateTimesReset(uint64_t start, Meas *M, int period, bool MaxMin, char *txt) { - if (start!=0) { - uint64_t end=rdtsc_oai(); - long long diff=(end-start)/(cpuf*1000); - M->maxArray[0]=diff; - M->sum+=diff; - M->iterations++; - - if ( MaxMin) - qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); - else - qsort(M->maxArray, 11, sizeof(uint64_t), cmpintRev); - - printMeas2(txt,M,period, MaxMin); - - if (M->iterations%period == 0 ) { - bzero(M,sizeof(*M)); - - if (!MaxMin) - for (int i=0; i<11; i++) - M->maxArray[i]=INT_MAX; - } - } -} - -static inline void measTransportTime(uint64_t DuSend, uint64_t CuMicroSec, Meas *M, int period, bool MaxMin, char *txt) { - if (DuSend!=0) { - uint64_t end=rdtsc_oai(); - long long diff=(end-DuSend)/(cpuf*1000)-CuMicroSec; - M->maxArray[0]=diff; - M->sum+=diff; - M->iterations++; - - if ( MaxMin) - qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); - else - qsort(M->maxArray, 11, sizeof(uint64_t), cmpintRev); - - printMeas2(txt,M,period, MaxMin); - - if (M->iterations%period == 0 ) { - bzero(M,sizeof(*M)); - - if (!MaxMin) - for (int i=0; i<11; i++) - M->maxArray[i]=INT_MAX; - } - } -} - -#define ceil16_bytes(a) ((((a+15)/16)*16)/8) - -static void fs6Dlunpack(void *out, void *in, int szUnpacked) { - static uint64_t *lut=NULL; - - if (!lut) { - lut=(uint64_t *) malloc(sizeof(*lut)*256); - - for (int i=0; i <256; i++) - for (int j=0; j<8; j++) - ((uint8_t *)(lut+i))[7-j]=(i>>j)&1; - } - - int64_t *out_64 = (int64_t *)out; - int sz=ceil16_bytes(szUnpacked); - - for (int i=0; i<sz; i++) - out_64[i]=lut[((uint8_t *)in)[i]]; - - return; -} - - -static void fs6Dlpack(void *out, void *in, int szUnpacked) { - __m128i zeros=_mm_set1_epi8(0); - __m128i shuffle=_mm_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7); - const int loop=ceil16_bytes(szUnpacked)/sizeof(uint16_t); - __m128i *iter=(__m128i *)in; - - for (int i=0; i < loop; i++) { - __m128i tmp=_mm_shuffle_epi8(_mm_cmpgt_epi8(*iter++,zeros),shuffle); - ((uint16_t *)out)[i]=(uint16_t)_mm_movemask_epi8(tmp); - } -} - -void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc) { - fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone); - - if (is_prach_subframe(&eNB->frame_parms, proc->frame_prach,proc->subframe_prach)<=0) - return; - - RU_t *ru; - int aa=0; - int ru_aa; - - for (int i=0; i<eNB->num_RU; i++) { - ru=eNB->RU_list[i]; - - for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) { - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa]; - int ce_level; - - for (ce_level=0; ce_level<4; ce_level++) - eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; - } - } - - ocp_rx_prach(eNB, - proc, - eNB->RU_list[0], - header->max_preamble, - header->max_preamble_energy, - header->max_preamble_delay, - header->avg_preamble_energy, - proc->frame_prach, - 0, - false - ); - // run PRACH detection for CE-level 0 only for now when br_flag is set - /* fixme: seems not operational and may overwrite regular LTE prach detection - * OAI code can call is sequence - rx_prach(eNB, - eNB->RU_list[0], - header->max_preamble, - header->max_preamble_energy, - header->max_preamble_delay, - header->avg_preamble_energy, - frame, - 0, - true - ); - */ - LOG_D(PHY,"RACH detection index 0: max preamble: %u, energy: %u, delay: %u, avg energy: %u\n", - header->max_preamble[0], - header->max_preamble_energy[0], - header->max_preamble_delay[0], - header->avg_preamble_energy[0] - ); - return; -} - -void prach_eNB_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc) { - fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone); - uint16_t *max_preamble=header->max_preamble; - uint16_t *max_preamble_energy=header->max_preamble_energy; - uint16_t *max_preamble_delay=header->max_preamble_delay; - uint16_t *avg_preamble_energy=header->avg_preamble_energy; - int subframe=proc->subframe_prach; - int frame=proc->frame_prach; - // Fixme: not clear why we call twice with "br" and without - int br_flag=0; - - if (br_flag==1) { - int prach_mask; - prach_mask = is_prach_subframe (&eNB->frame_parms, proc->frame_prach_br, proc->subframe_prach_br); - eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; - int ind = 0; - int ce_level = 0; - /* Save for later, it doesn't work - for (int ind=0,ce_level=0;ce_level<4;ce_level++) { - - if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1)&& - (prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions - (eNB->prach_vars_br.repetition_number[ce_level]== - eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) { - - */ - - if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) { - if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + eNB->prach_DTX_threshold_emtc[0])) { - eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++; - eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind]; // - eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; - // note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4 - eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + subframe + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40)); - eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is - eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1 + ce_level; // CE Level - LOG_I (PHY, "Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - ind, - ce_level, - prach_mask, - eNB->preamble_list_br[ind].preamble_rel8.timing_advance, - eNB->preamble_list_br[ind].preamble_rel8.preamble, eNB->preamble_list_br[ind].preamble_rel8.rnti, eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type); - } - } - - /* - ind++; - } - } */// ce_level - } else if ((eNB->prach_energy_counter == 100) && - (max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) { - LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", - eNB->Mod_id, - eNB->CC_id, - frame, - subframe, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - max_preamble_delay[0]); - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; - eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; - eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; - eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; - eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; - eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; - eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; - eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; - eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here - eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; - eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is - - if (NFAPI_MODE==NFAPI_MODE_PNF) { // If NFAPI PNF then we need to send the message to the VNF - LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), - eNB->preamble_list[0].preamble_rel8.timing_advance, - eNB->preamble_list[0].preamble_rel8.preamble, - eNB->preamble_list[0].preamble_rel8.rnti, - eNB->preamble_list[0].preamble_rel13.rach_resource_type); - oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; - } - - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - } // max_preamble_energy > prach_I0 + 100 - else { - eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((avg_preamble_energy[0]*124)>>10); - - if (eNB->prach_energy_counter < 100) - eNB->prach_energy_counter++; - } -} - -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, - uint16_t rnti, - int32_t stat) { - static int current_fsf=-1; - int fsf=frame*16+subframe; - uint8_t *bufferZone=eNB->FS6bufferZone; - commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; - // move to the end - uint8_t *firstFreeByte=bufferZone; - int curBlock=0; - - if ( current_fsf != fsf ) { - for (int i=0; i < FirstUDPheader->nbBlocks; i++) { - AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); - firstFreeByte+=alignedSize(firstFreeByte); - curBlock++; - } - - commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; - FirstUDPheader->nbBlocks++; - newUDPheader->blockID=curBlock; - newUDPheader->contentBytes=sizeof(fs6_ul_t)+sizeof(fs6_ul_uespec_uci_t); - hULUEuci(newUDPheader)->type=fs6ULcch; - hULUEuci(newUDPheader)->nb_active_ue=0; - } else - for (int i=0; i < FirstUDPheader->nbBlocks-1; i++) { - AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); - firstFreeByte+=alignedSize(firstFreeByte); - curBlock++; - } - - LOG_D(PHY,"FS6 du, block: %d: adding ul harq/sr: %d, rnti: %d, ueid: %d\n", - curBlock, type, rnti, UEid); - commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; - fs6_ul_uespec_uci_element_t *tmp=(fs6_ul_uespec_uci_element_t *)(hULUEuci(newUDPheader)+1); - tmp+=hULUEuci(newUDPheader)->nb_active_ue; - tmp->type=type; - tmp->UEid=UEid; - tmp->frame=frame; - tmp->subframe=subframe; - - if (uci != NULL) - memcpy(&tmp->uci, uci, sizeof(*uci)); - else - tmp->uci.ue_id=0xFFFF; - - if (harq_ack != NULL) - memcpy(tmp->harq_ack, harq_ack, 4); - - tmp->tdd_mapping_mode=tdd_mapping_mode; - tmp->tdd_multiplexing_mask=tdd_multiplexing_mask; - tmp->n0_subband_power_dB=eNB->measurements.n0_subband_power_dB[0][0]; - tmp->rnti=rnti; - tmp->stat=stat; - hULUEuci(newUDPheader)->nb_active_ue++; - newUDPheader->contentBytes+=sizeof(fs6_ul_uespec_uci_element_t); -} - - -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - uint8_t *bufferZone=eNB->FS6bufferZone; - commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; - // move to the end - uint8_t *firstFreeByte=bufferZone; - int curBlock=0; - - for (int i=0; i < FirstUDPheader->nbBlocks; i++) { - AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); - firstFreeByte+=alignedSize(firstFreeByte); - curBlock++; - } - - commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; - FirstUDPheader->nbBlocks++; - newUDPheader->blockID=curBlock; - newUDPheader->contentBytes=sizeof(fs6_ul_t)+sizeof(fs6_ul_uespec_t) + dataLen; - hULUE(newUDPheader)->type=fs6ULsch; - hULUE(newUDPheader)->UE_id=UE_id; - hULUE(newUDPheader)->harq_id=harq_pid; - memcpy(hULUE(newUDPheader)->ulsch_power, - eNB->pusch_vars[UE_id]->ulsch_power, - sizeof(int)*2); - hULUE(newUDPheader)->cqi_crc_status=eNB->ulsch[UE_id]->harq_processes[harq_pid]->cqi_crc_status; - hULUE(newUDPheader)->O_ACK=eNB->ulsch[UE_id]->harq_processes[harq_pid]->O_ACK; - memcpy(hULUE(newUDPheader)->o_ACK, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK, - sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK)); - hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time); - hULUE(newUDPheader)->segment=segmentID; - memcpy(hULUE(newUDPheader)->o, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o, - sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o)); - memcpy(hULUE(newUDPheader)+1, data, dataLen); - hULUE(newUDPheader)->segLen=dataLen; - hULUE(newUDPheader)->r_offset=r_offset; - hULUE(newUDPheader)->G=eNB->ulsch[UE_id]->harq_processes[harq_pid]->G; -} - -void pusch_procedures_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { - uint32_t harq_pid; - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; - - for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[i]; - - if (ulsch->ue_type > NOCE) - harq_pid = 0; - else - harq_pid= subframe2harq_pid(&eNB->frame_parms,frame,subframe); - - LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - - if (ulsch->rnti>0) - LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d active: %d handled:%d]\n", - i, harq_pid, frame,subframe,i,ulsch->rnti, - ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->status, ulsch_harq->handled); - - if ((ulsch) && - (ulsch->rnti>0) && - (ulsch_harq->status == ACTIVE) && - ((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) && - ((ulsch_harq->subframe == subframe) || (ulsch_harq->repetition_number >1) ) && - (ulsch_harq->handled == 0)) { - // UE has ULSCH scheduling - for (int rb=0; - rb<=ulsch_harq->nb_rb; - rb++) { - int rb2 = rb+ulsch_harq->first_rb; - eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); - } - - LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n", - eNB->Mod_id, frame, subframe, i); - uint8_t nPRS= fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]; - ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + - nPRS)%12; - AssertFatal(ulsch_harq->TBS>0,"illegal TBS %d\n",ulsch_harq->TBS); - LOG_D(PHY, - "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, ), O_ACK %d, beta_cqi %d \n", - eNB->Mod_id,harq_pid,frame,subframe, - ulsch_harq->dci_alloc, - ulsch_harq->rar_alloc, - ulsch_harq->round, - ulsch_harq->first_rb, - ulsch_harq->nb_rb, - ulsch_harq->Qm, - ulsch_harq->TBS, - ulsch_harq->rvidx, - ulsch->cyclicShift, - ulsch_harq->n_DMRS2, - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, - ulsch_harq->O_ACK, - ulsch->beta_offset_cqi_times8); - start_meas(&eNB->ulsch_demodulation_stats); - eNB->FS6bufferZone=bufferZone; - rx_ulsch(eNB, proc, i); - stop_meas(&eNB->ulsch_demodulation_stats); - // TBD: add datablock for transmission - start_meas(&eNB->ulsch_decoding_stats); - ulsch_decoding(eNB,proc, - i, - 0, // control_only_flag - ulsch_harq->V_UL_DAI, - ulsch_harq->nb_rb>20 ? 1 : 0); - stop_meas(&eNB->ulsch_decoding_stats); - } - } -} - -void phy_procedures_eNB_uespec_RX_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { - //RX processing for ue-specific resources - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; - /* TODO: use correct rxdata */ - - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; - - LOG_D (PHY, "[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n", eNB->Mod_id, frame, subframe); - eNB->rb_mask_ul[0] = 0; - eNB->rb_mask_ul[1] = 0; - eNB->rb_mask_ul[2] = 0; - eNB->rb_mask_ul[3] = 0; - // Fix me here, these should be locked - eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; - eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0; - // Call SRS first since all others depend on presence of SRS or lack thereof - srs_procedures (eNB, proc); - eNB->first_run_I0_measurements = 0; - uci_procedures (eNB, proc); - - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // If PNF or monolithic - pusch_procedures_tosplit(bufferZone, bufSize, eNB,proc); - } - - lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements); - int min_I0=1000,max_I0=0; - - if ((frame==0) && (subframe==4)) { - for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) { - if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2; - - if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) - min_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; - - if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) - max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; - } - - LOG_I (PHY, "max_I0 %d, min_I0 %d\n", max_I0, min_I0); - } - - return; -} - - -void fill_rx_indication_from_split(uint8_t *bufferZone, PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe, ul_propagation_t *ul_propa) { - nfapi_rx_indication_pdu_t *pdu; - int timing_advance_update; - uint32_t harq_pid; - - if (eNB->ulsch[UE_id]->ue_type > 0) - harq_pid = 0; - else - harq_pid = subframe2harq_pid (&eNB->frame_parms, - frame, subframe); - - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rx_ind.sfn_sf = frame<<4| subframe; - eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; - pdu = &eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; - // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; - pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; - pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; - pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - AssertFatal(pdu->rx_indication_rel8.length <= NFAPI_RX_IND_DATA_MAX, "Invalid PDU len %d\n", - pdu->rx_indication_rel8.length); - memcpy(pdu->rx_ind_data, - eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes, - pdu->rx_indication_rel8.length); - // estimate timing advance for MAC - timing_advance_update = ul_propa[UE_id].ta; - - // if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);} - // if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);} - switch (eNB->frame_parms.N_RB_DL) { - case 6: /* nothing to do */ - break; - - case 15: - timing_advance_update /= 2; - break; - - case 25: - timing_advance_update /= 4; - break; - - case 50: - timing_advance_update /= 8; - break; - - case 75: - timing_advance_update /= 12; - break; - - case 100: - timing_advance_update /= 16; - break; - - default: - abort (); - } - - // put timing advance command in 0..63 range - timing_advance_update += 31; - - if (timing_advance_update < 0) - timing_advance_update = 0; - - if (timing_advance_update > 63) - timing_advance_update = 63; - - pdu->rx_indication_rel8.timing_advance = timing_advance_update; - // estimate UL_CQI for MAC (from antenna port 0 only) - int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; - - if (SNRtimes10 < -640) - pdu->rx_indication_rel8.ul_cqi = 0; - else if (SNRtimes10 > 635) - pdu->rx_indication_rel8.ul_cqi = 255; - else - pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5; - - LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n", - harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, - timing_advance_update); - eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; - eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); -} - -void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, ul_propagation_t *ul_propa) { - //LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; - uint32_t harq_pid; - uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe); - - for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[i]; - - if (ulsch->ue_type > NOCE) harq_pid = 0; - else harq_pid=harq_pid0; - - LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - - if (ulsch->rnti>0) - LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d handled:%d]\n", - i, harq_pid, frame,subframe,i,ulsch->rnti, - ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); - - if ((ulsch) && - (ulsch->rnti>0) && - (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && - (ulsch_harq->handled == 0)) { - // UE has ULSCH scheduling - for (int rb=0; - rb<=ulsch_harq->nb_rb; - rb++) { - int rb2 = rb+ulsch_harq->first_rb; - eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); - } - - start_meas(&eNB->ulsch_decoding_stats); - // This is a new packet, so compute quantities regarding segmentation - ulsch_harq->B = ulsch_harq->TBS+24; - lte_segmentation(NULL, - NULL, - ulsch_harq->B, - &ulsch_harq->C, - &ulsch_harq->Cplus, - &ulsch_harq->Cminus, - &ulsch_harq->Kplus, - &ulsch_harq->Kminus, - &ulsch_harq->F); - ulsch_decoding_data(eNB, proc, i, harq_pid, - ulsch_harq->nb_rb>20 ? 1 : 0); - stop_meas(&eNB->ulsch_decoding_stats); - } // if ((ulsch) && - // (ulsch->rnti>0) && - // (ulsch_harq->status == ACTIVE)) - else if ((ulsch) && - (ulsch->rnti>0) && - (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && - (ulsch_harq->handled == 1)) { - // this harq process is stale, kill it, this 1024 frames later (10s), consider reducing that - ulsch_harq->status = SCH_IDLE; - ulsch_harq->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); - LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask); - } - } // for (i=0; i<NUMBER_OF_UE_MAX; i++) - - while (proc->nbDecode > 0) { - notifiedFIFO_elt_t *req=pullTpool(proc->respDecode, proc->threadPool); - if (req == NULL) - break; // Tpool has been stopped - postDecode(proc, req); - delNotifiedFIFO_elt(req); - } -} - -void recvFs6Ul(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, ul_propagation_t *ul_propa) { - void *bufPtr=bufferZone; - - for (int i=0; i < nbBlocks; i++) { //nbBlocks is the actual received blocks - if ( ((commonUDP_t *)bufPtr)->contentBytes > sizeof(fs6_ul_t) ) { - int type=hULUE(bufPtr)->type; - - if ( type == fs6ULsch) { - LTE_eNB_ULSCH_t *ulsch =eNB->ulsch[hULUE(bufPtr)->UE_id]; - LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[hULUE(bufPtr)->harq_id]; - memcpy(ulsch_harq->eUL+hULUE(bufPtr)->r_offset, - hULUE(bufPtr)+1, - hULUE(bufPtr)->segLen); - memcpy(eNB->pusch_vars[hULUE(bufPtr)->UE_id]->ulsch_power, - hULUE(bufPtr)->ulsch_power, - sizeof(int)*2); - ulsch_harq->G=hULUE(bufPtr)->G; - ulsch_harq->cqi_crc_status=hULUE(bufPtr)->cqi_crc_status; - //ulsch_harq->O_ACK= hULUE(bufPtr)->O_ACK; - memcpy(ulsch_harq->o_ACK, hULUE(bufPtr)->o_ACK, - sizeof(ulsch_harq->o_ACK)); - memcpy(ulsch_harq->o,hULUE(bufPtr)->o, sizeof(ulsch_harq->o)); - ul_propa[hULUE(bufPtr)->UE_id].ta=hULUE(bufPtr)->ta; - LOG_D(PHY,"Received ulsch data for: rnti:%x, cqi_crc_status %d O_ACK: %d, segment: %d, seglen: %d \n", - ulsch->rnti, ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK,hULUE(bufPtr)->segment, hULUE(bufPtr)->segLen); - } else if ( type == fs6ULcch ) { - int nb_uci=hULUEuci(bufPtr)->nb_active_ue; - fs6_ul_uespec_uci_element_t *tmp=(fs6_ul_uespec_uci_element_t *)(hULUEuci(bufPtr)+1); - - for (int j=0; j < nb_uci ; j++) { - LOG_D(PHY,"FS6 cu, block: %d/%d: received ul harq/sr: %d, rnti: %d, ueid: %d\n", - i, j, type, tmp->rnti, tmp->UEid); - eNB->measurements.n0_subband_power_dB[0][0]=tmp->n0_subband_power_dB; - - if (tmp->uci.ue_id != 0xFFFF) - memcpy(&eNB->uci_vars[tmp->UEid],&tmp->uci, sizeof(tmp->uci)); - - if ( tmp->type == fs6ULindicationHarq ) - fill_uci_harq_indication (tmp->UEid, eNB, &eNB->uci_vars[tmp->UEid], - tmp->frame, tmp->subframe, tmp->harq_ack, - tmp->tdd_mapping_mode, tmp->tdd_multiplexing_mask); - else if ( tmp->type == fs6ULindicationSr ) - fill_sr_indication(tmp->UEid, eNB,tmp->rnti,tmp->frame,tmp->subframe,tmp->stat); - else - LOG_E(PHY, "Split FS6: impossible UL harq type\n"); - - tmp++; - } - } else - LOG_E(PHY, "FS6 ul packet type impossible\n" ); - } - - bufPtr+=alignedSize(bufPtr); - } -} - -void phy_procedures_eNB_uespec_RX_fromsplit(uint8_t *bufferZone, int nbBlocks,PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc) { - // The configuration arrived in Dl, so we can extract the UL data - ul_propagation_t ul_propa[NUMBER_OF_UE_MAX]; - recvFs6Ul(bufferZone, nbBlocks, eNB, ul_propa); - - // dirty memory allocation in OAI... - for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) - if ( eNB->uci_vars[i].frame == proc->frame_rx && - eNB->uci_vars[i].subframe == proc->subframe_rx ) - eNB->uci_vars[i].active=0; - - pusch_procedures_fromsplit(bufferZone, nbBlocks, eNB, proc, ul_propa); -} - -void rcvFs6DL(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, int frame, int subframe) { - void *bufPtr=bufferZone; - - for (int i=0; i < nbBlocks; i++) { //nbBlocks is the actual received blocks - if ( ((commonUDP_t *)bufPtr)->contentBytes > sizeof(fs6_dl_t) ) { - int type=hDLUE(bufPtr)->type; - - if ( type == fs6DlConfig) { - int curUE=hDLUE(bufPtr)->UE_id; - LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[curUE][0]; - LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch0->harq_processes[hDLUE(bufPtr)->harq_pid]; -#ifdef PHY_TX_THREAD - dlsch0->active[subframe] = 1; -#else - dlsch0->active = 1; -#endif - dlsch0->harq_ids[frame%2][subframe]=hDLUE(bufPtr)->harq_pid; - dlsch0->rnti=hDLUE(bufPtr)->rnti; - dlsch0->sqrt_rho_a=hDLUE(bufPtr)->sqrt_rho_a; - dlsch0->sqrt_rho_b=hDLUE(bufPtr)->sqrt_rho_b; - dlsch_harq->nb_rb=hDLUE(bufPtr)->nb_rb; - memcpy(dlsch_harq->rb_alloc, hDLUE(bufPtr)->rb_alloc, sizeof(hDLUE(bufPtr)->rb_alloc)); - dlsch_harq->Qm=hDLUE(bufPtr)->Qm; - dlsch_harq->Nl=hDLUE(bufPtr)->Nl; - dlsch_harq->pdsch_start=hDLUE(bufPtr)->pdsch_start; -#ifdef PHY_TX_THREAD - dlsch_harq->CEmode = hDLUE(bufPtr)->CEmode; - dlsch_harq->i0=hDLUE(bufPtr)->i0; - dlsch_harq->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag; -#else - dlsch0->i0=hDLUE(bufPtr)->i0; - dlsch0->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag; -#endif - fs6Dlunpack(dlsch_harq->eDL, - hDLUE(bufPtr)+1, hDLUE(bufPtr)->dataLen); - LOG_D(PHY,"received %d bits, in harq id: %di fsf: %d.%d, sum %d\n", - hDLUE(bufPtr)->dataLen, hDLUE(bufPtr)->harq_pid, frame, subframe, sum(dlsch_harq->eDL, hDLUE(bufPtr)->dataLen)); - } else if (type == fs6UlConfig) { - int nbUE=(((commonUDP_t *)bufPtr)->contentBytes - sizeof(fs6_dl_t)) / sizeof( fs6_dl_ulsched_t ) ; -#define cpyVal(a) memcpy(&ulsch_harq->a,&hTxULUE(bufPtr)->a, sizeof(ulsch_harq->a)) - - for ( int i=0; i < nbUE; i++ ) { - int curUE=hTxULUE(bufPtr)->UE_id; - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[curUE]; - LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[hTxULUE(bufPtr)->harq_pid]; - ulsch->ue_type=hTxULUE(bufPtr)->ue_type; - ulsch->harq_mask=hTxULUE(bufPtr)->harq_mask; - ulsch->Mlimit=hTxULUE(bufPtr)->Mlimit; - ulsch->max_turbo_iterations=hTxULUE(bufPtr)->max_turbo_iterations; - ulsch->bundling=hTxULUE(bufPtr)->bundling; - ulsch->beta_offset_cqi_times8=hTxULUE(bufPtr)->beta_offset_cqi_times8; - ulsch->beta_offset_ri_times8=hTxULUE(bufPtr)->beta_offset_ri_times8; - ulsch->beta_offset_harqack_times8=hTxULUE(bufPtr)->beta_offset_harqack_times8; - ulsch->Msg3_active=hTxULUE(bufPtr)->Msg3_active; - ulsch->cyclicShift=hTxULUE(bufPtr)->cyclicShift; - ulsch->cooperation_flag=hTxULUE(bufPtr)->cooperation_flag; - ulsch->num_active_cba_groups=hTxULUE(bufPtr)->num_active_cba_groups; - memcpy(ulsch->cba_rnti,hTxULUE(bufPtr)->cba_rnti,sizeof(ulsch->cba_rnti));//NUM_MAX_CBA_GROUP]; - ulsch->rnti=hTxULUE(bufPtr)->rnti; - ulsch_harq->nb_rb=hTxULUE(bufPtr)->nb_rb; - ulsch_harq->handled=0; - ulsch_harq->status = ACTIVE; - ulsch_harq->frame = frame; - ulsch_harq->subframe = subframe; - ulsch_harq->first_rb=hTxULUE(bufPtr)->first_rb; - ulsch_harq->O_RI=hTxULUE(bufPtr)->O_RI; - ulsch_harq->Or1=hTxULUE(bufPtr)->Or1; - ulsch_harq->Msc_initial=hTxULUE(bufPtr)->Msc_initial; - ulsch_harq->Nsymb_initial=hTxULUE(bufPtr)->Nsymb_initial; - ulsch_harq->V_UL_DAI=hTxULUE(bufPtr)->V_UL_DAI; - ulsch_harq->Qm=hTxULUE(bufPtr)->Qm; - ulsch_harq->srs_active=hTxULUE(bufPtr)->srs_active; - ulsch_harq->TBS=hTxULUE(bufPtr)->TBS; - ulsch_harq->Nsymb_pusch=hTxULUE(bufPtr)->Nsymb_pusch; - cpyVal(dci_alloc); - cpyVal(rar_alloc); - cpyVal(status); - cpyVal(Msg3_flag); - cpyVal(phich_active); - cpyVal(phich_ACK); - cpyVal(previous_first_rb); - cpyVal(B); - cpyVal(G); - //cpyVal(o); - cpyVal(uci_format); - cpyVal(Or2); - cpyVal(o_RI); - cpyVal(o_ACK); - cpyVal(O_ACK); - //cpyVal(q); - cpyVal(o_RCC); - cpyVal(q_ACK); - cpyVal(q_RI); - cpyVal(RTC); - cpyVal(ndi); - cpyVal(round); - cpyVal(rvidx); - cpyVal(Nl); - cpyVal(n_DMRS); - cpyVal(previous_n_DMRS); - cpyVal(n_DMRS2); - cpyVal(delta_TF); - cpyVal(repetition_number ); - cpyVal(total_number_of_repetitions); - LOG_D(PHY,"Received request to perform ulsch for: rnti:%d, fsf: %d/%d, O_ACK: %d\n", - ulsch->rnti, frame, subframe, ulsch_harq->O_ACK); - } - } else if ( type == fs6ULConfigCCH ) { - fs6_dl_uespec_ulcch_element_t *tmp=(fs6_dl_uespec_ulcch_element_t *)(hTxULcch(bufPtr)+1); - - for (int i=0; i< hTxULcch(bufPtr)->nb_active_ue; i++ ) - memcpy(&eNB->uci_vars[tmp->UE_id], &tmp->cch_vars, sizeof(tmp->cch_vars)); - } else - LOG_E(PHY, "Impossible block in fs6 DL\n"); - } - - bufPtr+=alignedSize(bufPtr); - } -} - -void phy_procedures_eNB_TX_fromsplit(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas ) { - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - int subframe=proc->subframe_tx; - int frame=proc->frame_tx; - //LTE_UL_eNB_HARQ_t *ulsch_harq; - eNB->pdcch_vars[subframe&1].num_pdcch_symbols=hDL(bufferZone)->num_pdcch_symbols; - eNB->pdcch_vars[subframe&1].num_dci=hDL(bufferZone)->num_dci; - uint8_t num_mdci = eNB->mpdcch_vars[subframe&1].num_dci = hDL(bufferZone)->num_mdci; - eNB->pbch_configured=true; - memcpy(eNB->pbch_pdu,hDL(bufferZone)->pbch_pdu, 4); - - // Remove all scheduled DL, we will populate from the CU sending - for (int UE_id=0; UE_id<NUMBER_OF_DLSCH_MAX; UE_id++) { - LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0]; - - if ( dlsch0 && dlsch0->rnti>0 ) { -#ifdef PHY_TX_THREAD - dlsch0->active[subframe] = 0; -#else - dlsch0->active = 0; -#endif - } - } - - rcvFs6DL(bufferZone, nbBlocks, eNB, frame, subframe); - - if (do_meas==1) { - start_meas(&eNB->phy_proc_tx); - start_meas(&eNB->dlsch_common_and_dci); - } - - // clear the transmit data array for the current subframe - for (int aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) { - memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], - 0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t)); - } - - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - if (is_pmch_subframe(frame,subframe,fp)) { - pmch_procedures(eNB,proc,0); - } else { - // this is not a pmch subframe, so generate PSS/SSS/PBCH - common_signal_procedures(eNB,frame, subframe); - } - } - - // clear previous allocation information for all UEs - for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { - //if (eNB->dlsch[i][0]) - //eNB->dlsch[i][0]->subframe_tx[subframe] = 0; - } - - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - for (int i=0; i< hDL(bufferZone)->num_dci; i++) - eNB->pdcch_vars[subframe&1].dci_alloc[i]=hDL(bufferZone)->dci_alloc[i]; - - LOG_D (PHY, "Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %" PRIu8 ")\n", frame, subframe, hDL(bufferZone)->num_dci); - generate_dci_top(hDL(bufferZone)->num_pdcch_symbols, - hDL(bufferZone)->num_dci, - &eNB->pdcch_vars[subframe&1].dci_alloc[0], - 0, - hDL(bufferZone)->amp, - fp, - eNB->common_vars.txdataF, - subframe); - - if (num_mdci > 0) { - LOG_D (PHY, "[eNB %" PRIu8 "] Frame %d, subframe %d: Calling generate_mdci_top (mpdcch) (num_dci %" PRIu8 ")\n", eNB->Mod_id, frame, subframe, num_mdci); - generate_mdci_top (eNB, frame, subframe, AMP, eNB->common_vars.txdataF); - } - } - - for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { - LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0]; - LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[UE_id][1]; - - if ((dlsch0)&&(dlsch0->rnti>0)&& -#ifdef PHY_TX_THREAD - (dlsch0->active[subframe] == 1) -#else - (dlsch0->active == 1) -#endif - ) { - uint64_t sum=0; - - for ( int i= subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti); - i< (subframe+1) * fp->ofdm_symbol_size * (fp->symbols_per_tti); - i++) - sum+=((int32_t *)(eNB->common_vars.txdataF[0]))[i]; - - LOG_D(PHY,"frame: %d, subframe: %d, sum of dlsch mod v1: %lx\n", frame, subframe, sum); - int harq_pid=dlsch0->harq_ids[frame%2][subframe]; - pdsch_procedures(eNB, - proc, - harq_pid, - dlsch0, - dlsch1); - } - } - - eNB->phich_vars[subframe&1]=hDL(bufferZone)->phich_vars; - generate_phich_top(eNB, - proc, - AMP); -} - -#define cpyToDu(a) hTxULUE(newUDPheader)->a=ulsch->a -#define cpyToDuHarq(a) hTxULUE(newUDPheader)->a=ulsch_harq->a -#define memcpyToDuHarq(a) memcpy(&hTxULUE(newUDPheader)->a,&ulsch_harq->a, sizeof(ulsch_harq->a)); - -void appendFs6TxULUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int curUE, LTE_eNB_ULSCH_t *ulsch, int frame, int subframe) { - commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; - // move to the end - uint8_t *firstFreeByte=bufferZone; - int curBlock=0; - - for (int i=0; i < FirstUDPheader->nbBlocks; i++) { - AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); - firstFreeByte+=alignedSize(firstFreeByte); - curBlock++; - } - - commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; - FirstUDPheader->nbBlocks++; - newUDPheader->blockID=curBlock; - newUDPheader->contentBytes=sizeof(fs6_dl_t)+sizeof(fs6_dl_ulsched_t); - // We skip the fs6 DL header, that is populated by caller - // This header will be duplicated during sending - hTxULUE(newUDPheader)->type=fs6UlConfig; - hTxULUE(newUDPheader)->UE_id=curUE; - int harq_pid; - - if (ulsch->ue_type > NOCE) - // LTE-M case - harq_pid = 0; - else - harq_pid = subframe2harq_pid(fp, frame, subframe); - - LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[harq_pid]; - hTxULUE(newUDPheader)->harq_pid=harq_pid; - cpyToDu(ue_type); - cpyToDu(harq_mask); - cpyToDu(Mlimit); - cpyToDu(max_turbo_iterations); - cpyToDu(bundling); - cpyToDu(beta_offset_cqi_times8); - cpyToDu(beta_offset_ri_times8); - cpyToDu(beta_offset_harqack_times8); - cpyToDu(Msg3_active); - cpyToDu(cyclicShift); - cpyToDu(cooperation_flag); - cpyToDu(num_active_cba_groups); - memcpy(hTxULUE(newUDPheader)->cba_rnti,ulsch->cba_rnti,sizeof(ulsch->cba_rnti));//NUM_MAX_CBA_GROUP]; - cpyToDu(rnti); - cpyToDuHarq(nb_rb); - cpyToDuHarq(Msc_initial); - cpyToDuHarq(Nsymb_initial); - cpyToDuHarq(O_RI); - cpyToDuHarq(Or1); - cpyToDuHarq(first_rb); - cpyToDuHarq(V_UL_DAI); - cpyToDuHarq(Qm); - cpyToDuHarq(srs_active); - cpyToDuHarq(TBS); - cpyToDuHarq(Nsymb_pusch); - memcpyToDuHarq(dci_alloc); - memcpyToDuHarq(rar_alloc); - memcpyToDuHarq(status); - memcpyToDuHarq(Msg3_flag); - memcpyToDuHarq(phich_active); - memcpyToDuHarq(phich_ACK); - memcpyToDuHarq(previous_first_rb); - memcpyToDuHarq(B); - memcpyToDuHarq(G); - //memcpyToDuHarq(o); - memcpyToDuHarq(uci_format); - memcpyToDuHarq(Or2); - memcpyToDuHarq(o_RI); - memcpyToDuHarq(o_ACK); - memcpyToDuHarq(O_ACK); - //memcpyToDuHarq(q); - memcpyToDuHarq(o_RCC); - memcpyToDuHarq(q_ACK); - memcpyToDuHarq(q_RI); - memcpyToDuHarq(RTC); - memcpyToDuHarq(ndi); - memcpyToDuHarq(round); - memcpyToDuHarq(rvidx); - memcpyToDuHarq(Nl); - memcpyToDuHarq(n_DMRS); - memcpyToDuHarq(previous_n_DMRS); - memcpyToDuHarq(n_DMRS2); - memcpyToDuHarq(delta_TF); - memcpyToDuHarq(repetition_number ); - memcpyToDuHarq(total_number_of_repetitions); - LOG_D(PHY,"Added request to perform ulsch for: rnti:%x, fsf: %d/%d\n", ulsch->rnti, frame, subframe); -} - -void appendFs6DLUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int UE_id, int8_t harq_pid, LTE_eNB_DLSCH_t *dlsch0, LTE_DL_eNB_HARQ_t *harqData, int frame, int subframe) { - commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; - // move to the end - uint8_t *firstFreeByte=bufferZone; - int curBlock=0; - - for (int i=0; i < FirstUDPheader->nbBlocks; i++) { - AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); - firstFreeByte+=alignedSize(firstFreeByte); - curBlock++; - } - - int UEdataLen= get_G(fp, - harqData->nb_rb, - harqData->rb_alloc, - harqData->Qm, - harqData->Nl, - harqData->pdsch_start, - frame,subframe, - 0); - AssertFatal(firstFreeByte+ceil16_bytes(UEdataLen)+sizeof(fs6_dl_t) <= bufferZone+FS6_BUF_SIZE, ""); - commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; - FirstUDPheader->nbBlocks++; - newUDPheader->blockID=curBlock; - newUDPheader->contentBytes=sizeof(fs6_dl_t)+sizeof(fs6_dl_uespec_t) + ceil16_bytes(UEdataLen); - // We skip the fs6 DL header, that is populated by caller - // This header will be duplicated during sending - hDLUE(newUDPheader)->type=fs6DlConfig; - hDLUE(newUDPheader)->UE_id=UE_id; - hDLUE(newUDPheader)->harq_pid=harq_pid; - hDLUE(newUDPheader)->rnti=dlsch0->rnti; - hDLUE(newUDPheader)->sqrt_rho_a=dlsch0->sqrt_rho_a; - hDLUE(newUDPheader)->sqrt_rho_b=dlsch0->sqrt_rho_b; - hDLUE(newUDPheader)->nb_rb=harqData->nb_rb; - memcpy(hDLUE(newUDPheader)->rb_alloc, harqData->rb_alloc, sizeof(harqData->rb_alloc)); - hDLUE(newUDPheader)->Qm=harqData->Qm; - hDLUE(newUDPheader)->Nl=harqData->Nl; - hDLUE(newUDPheader)->pdsch_start=harqData->pdsch_start; -#ifdef PHY_TX_THREAD - hDLUE(newUDPheader)->CEmode=harqData->CEmode; - hDLUE(newUDPheader)->i0=harqData->i0; - hDLUE(newUDPheader)->sib1_br_flag=harqData->sib1_br_flag; -#else - hDLUE(newUDPheader)->i0=dlsch0->i0; - hDLUE(newUDPheader)->sib1_br_flag=dlsch0->sib1_br_flag; -#endif - hDLUE(newUDPheader)->dataLen=UEdataLen; - fs6Dlpack(hDLUE(newUDPheader)+1, harqData->eDL, UEdataLen); - LOG_D(PHY,"sending %d bits, in harq id: %di fsf: %d.%d, sum %d\n", - UEdataLen, harq_pid, frame, subframe, sum(harqData->eDL, UEdataLen)); - //for (int i=0; i < UEdataLen; i++) - //LOG_D(PHY,"buffer ei[%d]:%hhx\n", i, ( (uint8_t *)(hDLUE(newUDPheader)+1) )[i]); -} - -void appendFs6DLUEcch(uint8_t *bufferZone, PHY_VARS_eNB *eNB, int frame, int subframe) { - commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; - // move to the end - uint8_t *firstFreeByte=bufferZone; - int curBlock=0; - - for (int i=0; i < FirstUDPheader->nbBlocks; i++) { - AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); - firstFreeByte+=alignedSize(firstFreeByte); - curBlock++; - } - - commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; - bool first_UE=true; - - for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) { - LTE_eNB_UCI *uci = &(eNB->uci_vars[i]); - - if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) { - LOG_D(PHY,"Frame %d, subframe %d: adding uci procedures (type %d) for %d \n", - frame, - subframe, - uci->type, - i); - - if ( first_UE ) { - FirstUDPheader->nbBlocks++; - newUDPheader->blockID=curBlock; - newUDPheader->contentBytes=sizeof(fs6_dl_t)+sizeof(fs6_dl_uespec_ulcch_t); - hTxULcch(newUDPheader)->type=fs6ULConfigCCH; - hTxULcch(newUDPheader)->nb_active_ue=0; - first_UE=false; - } - - fs6_dl_uespec_ulcch_element_t *tmp=(fs6_dl_uespec_ulcch_element_t *)(hTxULcch(newUDPheader)+1); - tmp+=hTxULcch(newUDPheader)->nb_active_ue; - tmp->UE_id=i; - memcpy(&tmp->cch_vars,uci, sizeof(tmp->cch_vars)); - hTxULcch(newUDPheader)->nb_active_ue++; - newUDPheader->contentBytes+=sizeof(fs6_dl_uespec_ulcch_element_t); - } - } -} - -void phy_procedures_eNB_TX_tosplit(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas, uint8_t *buf, int bufSize) { - int frame=proc->frame_tx; - int subframe=proc->subframe_tx; - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - - if ((fp->frame_type == TDD) && (subframe_select (fp, subframe) == SF_UL)) { - LOG_W(HW,"no sending in eNB_TX\n"); - return; - } - - // clear previous allocation information for all UEs - for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { - //if (eNB->dlsch[i][0]) - //eNB->dlsch[i][0]->subframe_tx[subframe] = 0; - } - - // Send to DU the UL scheduled for future UL subframe - for (int i=0; i<NUMBER_OF_UE_MAX; i++) { - int harq_pid; - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[i]; - if (ulsch == NULL) - continue; - - if (ulsch->ue_type > NOCE) - harq_pid = 0; - else - harq_pid= subframe2harq_pid(&eNB->frame_parms,frame,subframe); - - LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - - if (ulsch->rnti>0) { - LOG_D(PHY,"check in UL scheduled harq %d: rnti %d, tx frame %d/%d, ulsch: %d, %d/%d (handled: %d)\n", - harq_pid, ulsch->rnti, frame, subframe, ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); - } - - for (int k=0; k<8; k++) { - ulsch_harq = ulsch->harq_processes[k]; - if (ulsch_harq == NULL) - continue; - - if ((ulsch->rnti>0) && - (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && - (ulsch_harq->handled == 0) - ) - appendFs6TxULUE(bufferZone, - fp, - i, - ulsch, - frame, - subframe - ); - } - } - - appendFs6DLUEcch(bufferZone, - eNB, - frame, - subframe - ); - uint8_t num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols; - uint8_t num_dci = eNB->pdcch_vars[subframe&1].num_dci; - uint8_t num_mdci = eNB->mpdcch_vars[subframe&1].num_dci; - memcpy(hDL(bufferZone)->pbch_pdu,eNB->pbch_pdu,4); - - if ( num_dci <= 8 ) - LOG_D(PHY,"num_pdcch_symbols %"PRIu8",number dci %"PRIu8"\n",num_pdcch_symbols, num_dci); - else { - LOG_E(PHY, "Num dci too large for current FS6 implementation, reducing to 8 dci (was %d)\n", num_dci); - num_dci=8; - } - - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - hDL(bufferZone)->num_pdcch_symbols=num_pdcch_symbols; - hDL(bufferZone)->num_dci=num_dci; - hDL(bufferZone)->num_mdci=num_mdci; - hDL(bufferZone)->amp=AMP; - - for (int i=0; i< hDL(bufferZone)->num_dci; i++) - hDL(bufferZone)->dci_alloc[i]=eNB->pdcch_vars[subframe&1].dci_alloc[i]; - - LOG_D(PHY, "pbch configured: %d\n", eNB->pbch_configured); - } - - if (do_meas==1) stop_meas(&eNB->dlsch_common_and_dci); - - if (do_meas==1) start_meas(&eNB->dlsch_ue_specific); - - for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { - LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0]; - - if ((dlsch0)&&(dlsch0->rnti>0)&& -#ifdef PHY_TX_THREAD - (dlsch0->active[subframe] == 1) -#else - (dlsch0->active == 1) -#endif - ) { - // get harq_pid - int harq_pid = dlsch0->harq_ids[frame%2][subframe]; - AssertFatal(harq_pid>=0,"harq_pid is negative\n"); - - if (harq_pid>=8) { - if (dlsch0->ue_type == NOCE) - LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x [ %1d.%1d.%1d.%1d.%1d.%1d.%1d.%1d\n", harq_pid,UE_id,frame,subframe,dlsch0->rnti, - dlsch0->harq_ids[frame%2][0], - dlsch0->harq_ids[frame%2][1], - dlsch0->harq_ids[frame%2][2], - dlsch0->harq_ids[frame%2][3], - dlsch0->harq_ids[frame%2][4], - dlsch0->harq_ids[frame%2][5], - dlsch0->harq_ids[frame%2][6], - dlsch0->harq_ids[frame%2][7]); - } else { - if (dlsch_procedures(eNB, - proc, - harq_pid, - dlsch0, - &eNB->UE_stats[(uint32_t)UE_id])) { - // data in: dlsch0 harq_processes[harq_pid]->e - /* length - get_G(fp, - dlsch_harq->nb_rb, - dlsch_harq->rb_alloc, - dlsch_harq->Qm, - dlsch_harq->Nl, - dlsch_harq->pdsch_start, - frame,subframe, - 0) - need harq_pid - */ - LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch0->harq_processes[harq_pid]; - appendFs6DLUE(bufferZone, - fp, - UE_id, - harq_pid, - dlsch0, - dlsch_harq, - frame, - subframe - ); - } - } - } else if ((dlsch0)&&(dlsch0->rnti>0)&& -#ifdef PHY_TX_THREAD - (dlsch0->active[subframe] == 0) -#else - (dlsch0->active == 0) -#endif - ) { - // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later) - //dlsch0->subframe_tx[subframe]=0; - } - } - - hDL(bufferZone)->phich_vars=eNB->phich_vars[subframe&1]; - - if (do_meas==1) stop_meas(&eNB->dlsch_ue_specific); - - if (do_meas==1) stop_meas(&eNB->phy_proc_tx); - - // MBMS is not working in OAI - if (hDL(bufferZone)->num_mdci) abort(); - - return; -} - -void *DL_du_fs6(void *arg) { - RU_t *ru=(RU_t *)arg; - static uint64_t lastTS; - L1_rxtx_proc_t L1proc= {0}; - // We pick the global thread pool from the legacy code global vars - L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool; - L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode; - L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode; - initStaticTime(begingWait); - initStaticTime(begingProcessing); - initRefTimes(fullLoop); - initRefTimes(DuHigh); - initRefTimes(DuLow); - initRefTimes(transportTime); - - while (1) { - for (int i=0; i<ru->num_eNB; i++) { - initBufferZone(bufferZone); - pickStaticTime(begingWait); - int nb_blocks=receiveSubFrame(&sockFS6, bufferZone, sizeof(bufferZone), CTsentCUv0 ); - updateTimesReset(begingWait, &fullLoop, 1000, false, "DU wait CU"); - - if (nb_blocks > 0) { - if ( lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti < hUDP(bufferZone)->timestamp) { - LOG_E(HW,"Missed a subframe: expecting: %lu, received %lu\n", - lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti, - hUDP(bufferZone)->timestamp); - } else if ( lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti > hUDP(bufferZone)->timestamp) { - LOG_E(HW,"Received a subframe in past time from CU (dropping it): expecting: %lu, received %lu\n", - lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti, - hUDP(bufferZone)->timestamp); - } - - pickStaticTime(begingProcessing); - lastTS=hUDP(bufferZone)->timestamp; - setAllfromTS(hUDP(bufferZone)->timestamp - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti, &L1proc); - measTransportTime(hDL(bufferZone)->DuClock, hDL(bufferZone)->CuSpentMicroSec, - &transportTime, 1000, false, "Transport time, to CU + from CU for one subframe"); - phy_procedures_eNB_TX_fromsplit( bufferZone, nb_blocks, ru->eNB_list[i], &L1proc, 1); - updateTimesReset(begingProcessing, &DuHigh, 1000, false, "DU high layer1 processing for DL"); - } else - LOG_E(PHY,"DL not received for subframe\n"); - } - - pickStaticTime(begingProcessing); - feptx_prec(ru, L1proc.frame_tx,L1proc.subframe_tx ); - feptx_ofdm(ru, L1proc.frame_tx,L1proc.subframe_tx ); - ocp_tx_rf(ru, &L1proc); - updateTimesReset(begingProcessing, &DuLow, 1000, false, "DU low layer1 processing for DL"); - - if ( IS_SOFTMODEM_RFSIM ) - return NULL; - } - - return NULL; -} - -void UL_du_fs6(RU_t *ru, L1_rxtx_proc_t *proc) { - initStaticTime(begingWait); - initRefTimes(fullLoop); - pickStaticTime(begingWait); - rx_rf(ru, proc); - updateTimesReset(begingWait, &fullLoop, 1000, false, "DU wait USRP"); - // front end processing: convert from time domain to frequency domain - // fills rxdataF buffer - fep_full(ru, proc->subframe_rx); - // Fixme: datamodel issue - PHY_VARS_eNB *eNB = RC.eNB[0][0]; - - if (NFAPI_MODE==NFAPI_MODE_PNF) { - // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - //add_subframe(&frame, &subframe, 4); - //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); - oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - } - - initBufferZone(bufferZone); - hUDP(bufferZone)->timestamp=proc->timestamp_rx; - prach_eNB_tosplit(bufferZone, FS6_BUF_SIZE, eNB, proc ); - - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - phy_procedures_eNB_uespec_RX_tosplit(bufferZone, FS6_BUF_SIZE, eNB, proc ); - } - - if (hUDP(bufferZone)->nbBlocks==0) { - hUDP(bufferZone)->nbBlocks=1; // We have to send the signaling, even is there is no user plan data (no UE) - hUDP(bufferZone)->blockID=0; - hUDP(bufferZone)->contentBytes=sizeof(fs6_ul_t); - } - - for (int i=0; i<ru->num_eNB; i++) { - sendSubFrame(&sockFS6, bufferZone, sizeof(fs6_ul_t), CTsentDUv0); - } -} - -void DL_cu_fs6(RU_t *ru, L1_rxtx_proc_t *proc, uint64_t DuClock, uint64_t startCycle) { - initRefTimes(CUprocessing); - // Fixme: datamodel issue - PHY_VARS_eNB *eNB = RC.eNB[0][0]; - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.frame = proc->frame_rx; - eNB->UL_INFO.subframe = proc->subframe_rx; - eNB->UL_INFO.module_id = eNB->Mod_id; - eNB->UL_INFO.CC_id = eNB->CC_id; - eNB->if_inst->UL_indication(&eNB->UL_INFO, proc); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - initBufferZone(bufferZone); - phy_procedures_eNB_TX_tosplit(bufferZone, eNB, proc, 1, bufferZone, FS6_BUF_SIZE); - hUDP(bufferZone)->timestamp=proc->timestamp_tx; - - if (hUDP(bufferZone)->nbBlocks==0) { - hUDP(bufferZone)->nbBlocks=1; // We have to send the signaling, even is there is no user plan data (no UE) - hUDP(bufferZone)->blockID=0; - hUDP(bufferZone)->contentBytes=sizeof(fs6_dl_t); - } - - hDL(bufferZone)->DuClock=DuClock; - hDL(bufferZone)->CuSpentMicroSec=(rdtsc_oai()-startCycle)/(cpuf*1000); - updateTimesReset(startCycle, &CUprocessing, 1000, true,"CU entire processing from recv to send"); - sendSubFrame(&sockFS6, bufferZone, sizeof(fs6_dl_t), CTsentCUv0 ); - return; -} - -void UL_cu_fs6(RU_t *ru, L1_rxtx_proc_t *proc, uint64_t *TS, uint64_t *DuClock, uint64_t *startProcessing) { - initBufferZone(bufferZone); - initStaticTime(begingWait); - initRefTimes(fullLoop); - pickStaticTime(begingWait); - int nb_blocks=receiveSubFrame(&sockFS6, bufferZone, sizeof(bufferZone), CTsentDUv0 ); - * DuClock=hUDP(bufferZone)->senderClock; - * startProcessing=rdtsc_oai(); - updateTimesReset(begingWait, &fullLoop, 1000, false, "CU wait DU"); - - if (nb_blocks ==0) { - LOG_W(PHY, "CU lost a subframe\n"); - return; - } - - if (nb_blocks != hUDP(bufferZone)->nbBlocks ) - LOG_W(PHY, "received %d blocks for %d expected\n", nb_blocks, hUDP(bufferZone)->nbBlocks); - - if ( *TS != hUDP(bufferZone)->timestamp ) { - LOG_W(HW, "CU received time: %lu instead of %lu expected\n", hUDP(bufferZone)->timestamp, *TS); - *TS=hUDP(bufferZone)->timestamp; - } - - setAllfromTS(hUDP(bufferZone)->timestamp, proc); - PHY_VARS_eNB *eNB = RC.eNB[0][0]; - - if (is_prach_subframe(&eNB->frame_parms, proc->frame_prach,proc->subframe_prach)>0) - prach_eNB_fromsplit(bufferZone, sizeof(bufferZone), eNB, proc); - - release_UE_in_freeList(eNB->Mod_id); - - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - phy_procedures_eNB_uespec_RX_fromsplit(bufferZone, nb_blocks, eNB, proc); - } -} - -void *cu_fs6(void *arg) { - setbuf(stdout, NULL); - setbuf(stderr, NULL); - RU_t *ru = (RU_t *)arg; - //RU_proc_t *proc = &ru->proc; - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(ru->frame_parms,1); - phy_init_RU(ru); - wait_sync("ru_thread"); - char remoteIP[1024]; - strncpy(remoteIP,get_softmodem_params()->split73+3, 1023); //three first char should be cu: or du: - char port_def[256]=DU_PORT; - - for (int i=0; i <1000; i++) - if (remoteIP[i]==':') { - strncpy(port_def,remoteIP+i+1,255); - remoteIP[i]=0; - break; - } - - AssertFatal(createUDPsock(NULL, CU_PORT, remoteIP, port_def, &sockFS6), ""); - L1_rxtx_proc_t L1proc= {0}; - // We pick the global thread pool from the legacy code global vars - L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool; - L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode; - L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode; - uint64_t timeStamp=0; - initStaticTime(begingWait); - initStaticTime(begingWait2); - initRefTimes(waitDUAndProcessingUL); - initRefTimes(makeSendDL); - initRefTimes(fullLoop); - uint64_t DuClock=0, startProcessing=0; - - while(1) { - timeStamp+=ru->frame_parms->samples_per_tti; - updateTimesReset(begingWait, &fullLoop, 1000, true, "CU for full SubFrame (must be less 1ms)"); - pickStaticTime(begingWait); - UL_cu_fs6(ru, &L1proc, &timeStamp, &DuClock, &startProcessing); - updateTimesReset(begingWait, &waitDUAndProcessingUL, 1000, true,"CU Time in wait Rx + Ul processing"); - pickStaticTime(begingWait2); - DL_cu_fs6(ru, &L1proc, DuClock, startProcessing); - updateTimesReset(begingWait2, &makeSendDL, 1000, true,"CU Time in DL build+send"); - } - - return NULL; -} - -void *du_fs6(void *arg) { - setbuf(stdout, NULL); - setbuf(stderr, NULL); - RU_t *ru = (RU_t *)arg; - //RU_proc_t *proc = &ru->proc; - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(ru->frame_parms,1); - phy_init_RU(ru); - init_rf(ru); - wait_sync("ru_thread"); - char remoteIP[1024]; - strncpy(remoteIP,get_softmodem_params()->split73+3,1023); //three first char should be cu: or du: - char port_def[256]=CU_PORT; - - for (int i=0; i <1000; i++) - if (remoteIP[i]==':') { - strncpy(port_def,remoteIP+i+1,255); - remoteIP[i]=0; - break; - } - - AssertFatal(createUDPsock(NULL, DU_PORT, remoteIP, port_def, &sockFS6), ""); - - if (ru->rfdevice.trx_start_func(&ru->rfdevice) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else - LOG_I(PHY,"RU %d rf device ready\n",ru->idx); - - initStaticTime(begingWait); - initRefTimes(waitRxAndProcessingUL); - initRefTimes(fullLoop); - pthread_t t; - - if ( !IS_SOFTMODEM_RFSIM ) - threadCreate(&t, DL_du_fs6, (void *)ru, "MainDuTx", -1, OAI_PRIORITY_RT_MAX); - - L1_rxtx_proc_t L1proc= {0}; - // We pick the global thread pool from the legacy code global vars - L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool; - L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode; - L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode; - - while(!oai_exit) { - updateTimesReset(begingWait, &fullLoop, 1000, true,"DU for full SubFrame (must be less 1ms)"); - pickStaticTime(begingWait); - UL_du_fs6(ru, &L1proc); - - if ( IS_SOFTMODEM_RFSIM ) - DL_du_fs6((void *)ru); - - updateTimesReset(begingWait, &waitRxAndProcessingUL, 1000, true,"DU Time in wait Rx + Ul processing"); - } - - ru->rfdevice.trx_end_func(&ru->rfdevice); - LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); - return NULL; -} diff --git a/executables/main-ocp.c b/executables/main-ocp.c deleted file mode 100644 index b9abbf979055ac520903568777ca63df8e6946f1..0000000000000000000000000000000000000000 --- a/executables/main-ocp.c +++ /dev/null @@ -1,1287 +0,0 @@ -/* -* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The OpenAirInterface Software Alliance licenses this file to You under -* the OAI Public License, Version 1.1 (the "License"); you may not use this file -* except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.openairinterface.org/?page_id=698 -* -* Author and copyright: Laurent Thomas, open-cells.com -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*------------------------------------------------------------------------------- -* For more information about the OpenAirInterface (OAI) Software Alliance: -* contact@openairinterface.org -*/ - - -/* - * This file replaces - * executables/lte-softmodem.c - * executables/rt_wrapper.c - * executables/lte-ru.c - * executables/lte-enb.c - * executables/ru_control.c - * openair1/SCHED/prach_procedures.c - * The merger of OpenAir central code to this branch - * should check if these 3 files are modified and analyze if code code has to be copied in here - */ -#define _GNU_SOURCE -#include <pthread.h> - -#include <common/utils/LOG/log.h> -#include <common/utils/system.h> -#include <common/utils/assertions.h> -static int DEFBANDS[] = {7}; -static int DEFENBS[] = {0}; -#include <common/config/config_userapi.h> -#include "executables/lte-softmodem.h" -#include <openair1/PHY/defs_eNB.h> -#include <openair1/PHY/phy_extern.h> -#include <nfapi/oai_integration/vendor_ext.h> -#include <openair1/SCHED/fapi_l1.h> -#include <openair1/PHY/INIT/phy_init.h> -#include <openair2/LAYER2/MAC/mac_extern.h> -#include <openair1/PHY/LTE_REFSIG/lte_refsig.h> -#include <nfapi/oai_integration/nfapi_pnf.h> -#include <executables/split_headers.h> -#include <common/utils/threadPool/thread-pool.h> -#include <openair2/ENB_APP/NB_IoT_interface.h> -#include <common/utils/load_module_shlib.h> -#include <targets/COMMON/create_tasks.h> -#include <openair1/PHY/TOOLS/phy_scope_interface.h> -#include <openair2/UTIL/OPT/opt.h> -#include <openair1/SIMULATION/TOOLS/sim.h> -#include <openair1/PHY/phy_vars.h> -#include <openair2/LAYER2/MAC/mac_vars.h> -#include <openair2/RRC/LTE/rrc_vars.h> - -pthread_cond_t nfapi_sync_cond; -pthread_mutex_t nfapi_sync_mutex; -int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -pthread_cond_t sync_cond; -pthread_mutex_t sync_mutex; -int sync_var=-1; //!< protected by mutex \ref sync_mutex. -int config_sync_var=-1; -int oai_exit = 0; -double cpuf; -THREAD_STRUCT thread_struct; - -extern uint16_t sf_ahead; // Bell Labs -//uint16_t sf_ahead=4; -//uint16_t slot_ahead=6; -int otg_enabled; -uint64_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -int split73; -char *split73_config; -int split73; -AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0}; -AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]= {0}; - -static void *ru_thread( void *param ); -void kill_RU_proc(RU_t *ru) { -} -void kill_eNB_proc(int inst) { -} -void free_transport(PHY_VARS_eNB *eNB) { -} -void reset_opp_meas(void) { -} -extern void phy_free_RU(RU_t *); - -void exit_function(const char *file, const char *function, const int line, const char *s) { - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } - - close_log_mem(); - oai_exit = 1; - sleep(1); //allow lte-softmodem threads to exit first - exit(1); -} - -// Fixme: there are many mistakes in the datamodel and in redondant variables -// TDD is also mode complex -void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc) { - for (int i=0; i < RC.nb_inst; i++) { - for (int j=0; j<RC.nb_CC[i]; j++) { - LTE_DL_FRAME_PARMS *fp=&RC.eNB[i][j]->frame_parms; - uint64_t TStx=TS+(sf_ahead)*fp->samples_per_tti; - uint64_t TSrach=TS;//-fp->samples_per_tti; - proc->timestamp_rx= TS; - proc->timestamp_tx= TStx; - proc->subframe_rx= (TS / fp->samples_per_tti)%10; - proc->subframe_prach=(TSrach / fp->samples_per_tti)%10; - proc->subframe_prach_br=(TSrach / fp->samples_per_tti)%10; - proc->frame_rx= (TS / (fp->samples_per_tti*10))&1023; - proc->frame_prach= (TSrach / (fp->samples_per_tti*10))&1023; - proc->frame_prach_br=(TSrach / (fp->samples_per_tti*10))&1023; - proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; - proc->subframe_tx= (TStx / fp->samples_per_tti)%10; - } - } - - return; -} - -void init_RU_proc(RU_t *ru) { - pthread_t t; - - switch(split73) { - case SPLIT73_CU: - threadCreate(&t, cu_fs6, (void *)ru, "MainCu", -1, OAI_PRIORITY_RT_MAX); - break; - - case SPLIT73_DU: - threadCreate(&t, du_fs6, (void *)ru, "MainDuRx", -1, OAI_PRIORITY_RT_MAX); - break; - - default: - threadCreate(&t, ru_thread, (void *)ru, "MainRu", -1, OAI_PRIORITY_RT_MAX); - } -} - -// Create per UE structures -void init_transport(PHY_VARS_eNB *eNB) { - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - LOG_I(PHY, "Initialise transport\n"); - - for (int i=0; i<NUMBER_OF_DLSCH_MAX; i++) { - LOG_D(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i); - - for (int j=0; j<2; j++) { - AssertFatal( (eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp)) != NULL, - "Can't get eNB dlsch structures for UE %d \n", i); - eNB->dlsch[i][j]->rnti=0; - LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); - } - } - - for (int i=0; i<NUMBER_OF_ULSCH_MAX; i++) { - LOG_D(PHY,"Allocating Transport Channel Buffers for ULSCH, UE %d\n",i); - AssertFatal((eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0)) != NULL, - "Can't get eNB ulsch structures\n"); - // this is the transmission mode for the signalling channels - // this will be overwritten with the real transmission mode by the RRC once the UE is connected - eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2; - } - - // ULSCH for RA - AssertFatal( (eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0)) !=NULL, - "Can't get eNB ulsch structures\n"); - eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI); - eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra); - eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH); - eNB->rx_total_gain_dB=130; - - for(int i=0; i<NUMBER_OF_UE_MAX; i++) - eNB->mu_mimo_mode[i].dl_pow_off = 2; - - eNB->check_for_total_transmissions = 0; - eNB->check_for_MUMIMO_transmissions = 0; - eNB->FULL_MUMIMO_transmissions = 0; - eNB->check_for_SUMIMO_transmissions = 0; - fp->pucch_config_common.deltaPUCCH_Shift = 1; - - if (eNB->use_DTX == 0) - fill_subframe_mask(eNB); -} - -void init_eNB_afterRU(void) { - for (int inst=0; inst<RC.nb_inst; inst++) { - for (int CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) { - PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id]; - eNB->frame_parms.nb_antennas_rx = 0; - eNB->frame_parms.nb_antennas_tx = 0; - eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *)); - - for (int ce_level=0; ce_level<4; ce_level++) { - eNB->prach_vars_br.rxsigF[ce_level] = (int16_t **)malloc16(64*sizeof(int16_t *)); - } - - for (int ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) { - eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; - eNB->frame_parms.nb_antennas_tx += eNB->RU_list[ru_id]->nb_tx; - AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL, - "RU %d : common.rxdataF is NULL\n", - eNB->RU_list[ru_id]->idx); - AssertFatal(eNB->RU_list[ru_id]->prach_rxsigF!=NULL, - "RU %d : prach_rxsigF is NULL\n", - eNB->RU_list[ru_id]->idx); - - for (int i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) { - LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i]; - - for (int ce_level=0; ce_level<4; ce_level++) - eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; - } - } - - AssertFatal( eNB->frame_parms.nb_antennas_rx > 0 && eNB->frame_parms.nb_antennas_rx < 5, ""); - AssertFatal( eNB->frame_parms.nb_antennas_tx > 0 && eNB->frame_parms.nb_antennas_rx < 5, ""); - phy_init_lte_eNB(eNB,0,0); - - // need to copy rxdataF after L1 variables are allocated - for (int inst=0; inst<RC.nb_inst; inst++) { - for (int CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) { - PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id]; - - for (int ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) { - for (int i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) - eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; - } - } - } - - LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); - init_transport(eNB); - //init_precoding_weights(RC.eNB[inst][CC_id]); - } - } -} - -void init_eNB(int single_thread_flag,int wait_for_sync) { - AssertFatal(RC.eNB != NULL,"RC.eNB must have been allocated\n"); - - for (int inst=0; inst<RC.nb_L1_inst; inst++) { - AssertFatal(RC.eNB[inst] != NULL,"RC.eNB[%d] must have been allocated\n", inst); - - for (int CC_id=0; CC_id<RC.nb_L1_CC[inst]; CC_id++) { - AssertFatal(RC.eNB[inst][CC_id] != NULL,"RC.eNB[%d][%d] must have been allocated\n", inst, CC_id); - PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id]; - eNB->abstraction_flag = 0; - eNB->single_thread_flag = single_thread_flag; - AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); - eNB->if_inst->schedule_response = schedule_response; - eNB->if_inst->PHY_config_req = phy_config_request; - memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); - memset((void *)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); - pthread_mutex_init( &eNB->UL_INFO_mutex, NULL); - LOG_I(PHY,"Setting indication lists\n"); - eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; - eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; - eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; - eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list = eNB->cqi_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; - eNB->prach_energy_counter = 0; - } - } - - SET_LOG_DEBUG(PRACH); -} - -void stop_eNB(int nb_inst) { - for (int inst=0; inst<nb_inst; inst++) { - LOG_I(PHY,"Killing eNB %d processing threads\n",inst); - kill_eNB_proc(inst); - } -} - -// this is for RU with local RF unit -void fill_rf_config(RU_t *ru, char *rf_config_file) { - int i; - LTE_DL_FRAME_PARMS *fp = ru->frame_parms; - openair0_config_t *cfg = &ru->openair0_cfg; - //printf("////////////////numerology in config = %d\n",numerology); - int numerology = 0; //get_softmodem_params()->numerology; - - if(fp->N_RB_DL == 100) { - if(numerology == 0) { - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - } else if(numerology == 1) { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } else if(numerology == 2) { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } else { - LOG_E(PHY,"Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology); - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - } else if(fp->N_RB_DL == 50) { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } else if (fp->N_RB_DL == 25) { - cfg->sample_rate=7.68e6; - cfg->samples_per_frame = 76800; - cfg->tx_bw = 2.5e6; - cfg->rx_bw = 2.5e6; - } else if (fp->N_RB_DL == 6) { - cfg->sample_rate=1.92e6; - cfg->samples_per_frame = 19200; - cfg->tx_bw = 1.5e6; - cfg->rx_bw = 1.5e6; - } else - AssertFatal(1==0,"Unknown N_RB_DL %d\n",fp->N_RB_DL); - - if (fp->frame_type==TDD) - cfg->duplex_mode = duplex_mode_TDD; - else //FDD - cfg->duplex_mode = duplex_mode_FDD; - - cfg->Mod_id = 0; - cfg->num_rb_dl=fp->N_RB_DL; - cfg->tx_num_channels=ru->nb_tx; - cfg->rx_num_channels=ru->nb_rx; - cfg->clock_source=get_softmodem_params()->clock_source; - - for (i=0; i<ru->nb_tx; i++) { - cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; - cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - cfg->tx_gain[i] = (double)ru->att_tx; - cfg->rx_gain[i] = ru->max_rxgain-(double)ru->att_rx; - cfg->configFilename = rf_config_file; - LOG_I(PHY,"channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", - i, cfg->tx_gain[i], - cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i]); - } -} - -/* this function maps the RU tx and rx buffers to the available rf chains. - Each rf chain is is addressed by the card number and the chain on the card. The - rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple - antennas are mapped to successive RF chains on the same card. */ -int setup_RU_buffers(RU_t *ru) { - //uint16_t N_TA_offset = 0; - LTE_DL_FRAME_PARMS *frame_parms; - AssertFatal(ru, "ru is NULL"); - frame_parms = ru->frame_parms; - LOG_I(PHY,"setup_RU_buffers: frame_parms = %p\n",frame_parms); - - if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) { - ru->N_TA_offset = 624; - } else if (frame_parms->N_RB_DL == 50) { - ru->N_TA_offset = 624/2; - ru->sf_extension /= 2; - ru->end_of_burst_delay /= 2; - } else if (frame_parms->N_RB_DL == 25) { - ru->N_TA_offset = 624/4; - ru->sf_extension /= 4; - ru->end_of_burst_delay /= 4; - } else { - LOG_E(PHY,"not handled, todo\n"); - exit(1); - } - } else { - ru->N_TA_offset = 0; - ru->sf_extension = 0; - ru->end_of_burst_delay = 0; - } - - return(0); -} - -#if 0 -void init_precoding_weights(PHY_VARS_eNB *eNB) { - int layer,ru_id,aa,re,ue,tb; - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - RU_t *ru; - LTE_eNB_DLSCH_t *dlsch; - - // init precoding weigths - for (ue=0; ue<NUMBER_OF_UE_MAX; ue++) { - for (tb=0; tb<2; tb++) { - dlsch = eNB->dlsch[ue][tb]; - - for (layer=0; layer<4; layer++) { - int nb_tx=0; - - for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { - ru = RC.ru[ru_id]; - nb_tx+=ru->nb_tx; - } - - dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(nb_tx*sizeof(int32_t *)); - - for (aa=0; aa<nb_tx; aa++) { - dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(fp->ofdm_symbol_size*sizeof(int32_t)); - - for (re=0; re<fp->ofdm_symbol_size; re++) { - dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; - } - } - } - } - } -} -#endif - -void ocp_rx_prach(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - RU_t *ru, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, - uint16_t Nf, - uint8_t tdd_mapindex, - uint8_t br_flag) { - int i; - int prach_mask=0; - - if (br_flag == 0) { - rx_prach0(eNB,ru,proc->frame_prach, proc->subframe_prach, - max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0); - } else { // This is procedure for eMTC, basically handling the repetitions - prach_mask = is_prach_subframe(&eNB->frame_parms,proc->frame_prach_br,proc->subframe_prach_br); - - for (i=0; i<4; i++) { - if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]==1) && - ((prach_mask&(1<<(i+1))) > 0)) { // check that prach CE level is active now - - // if first reception in group of repetitions store frame for later (in RA-RNTI for Msg2) - if (eNB->prach_vars_br.repetition_number[i]==0) - eNB->prach_vars_br.first_frame[i]=proc->frame_prach_br; - - // increment repetition number - eNB->prach_vars_br.repetition_number[i]++; - // do basic PRACH reception - rx_prach0(eNB,ru,proc->frame_prach, proc->subframe_prach_br, - max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i); - - // if last repetition, clear counter - if (eNB->prach_vars_br.repetition_number[i] == eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[i]) { - eNB->prach_vars_br.repetition_number[i]=0; - } - } - } /* for i ... */ - } /* else br_flag == 0 */ -} - -void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int br_flag) { - uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4],avg_preamble_energy[4]; - RU_t *ru; - int aa=0; - int ru_aa; - - for (int i=0; i<eNB->num_RU; i++) { - ru=eNB->RU_list[i]; - - for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) { - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa]; - int ce_level; - - if (br_flag==1) - for (ce_level=0; ce_level<4; ce_level++) - eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; - } - } - - // run PRACH detection for CE-level 0 only for now when br_flag is set - ocp_rx_prach(eNB, - proc, - eNB->RU_list[0], - &max_preamble[0], - &max_preamble_energy[0], - &max_preamble_delay[0], - &avg_preamble_energy[0], - proc->frame_prach, - 0 - ,br_flag - ); - LOG_D(PHY,"RACH detection index 0: max preamble: %u, energy: %u, delay: %u, avg energy: %u\n", - max_preamble[0], - max_preamble_energy[0], - max_preamble_delay[0], - avg_preamble_energy[0] - ); - - if (br_flag==1) { - int prach_mask; - prach_mask = is_prach_subframe (&eNB->frame_parms, proc->frame_prach_br, proc->subframe_prach_br); - eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; - int ind = 0; - int ce_level = 0; - /* Save for later, it doesn't work - for (int ind=0,ce_level=0;ce_level<4;ce_level++) { - - if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1)&& - (prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions - (eNB->prach_vars_br.repetition_number[ce_level]== - eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) { - - */ - - if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) { - if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + eNB->prach_DTX_threshold_emtc[0])) { - eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++; - eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind]; // - eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; - // note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4 - eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + proc->subframe_prach + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40)); - eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is - eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1 + ce_level; // CE Level - LOG_I (PHY, "Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - ind, - ce_level, - prach_mask, - eNB->preamble_list_br[ind].preamble_rel8.timing_advance, - eNB->preamble_list_br[ind].preamble_rel8.preamble, eNB->preamble_list_br[ind].preamble_rel8.rnti, eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type); - } - } - - /* - ind++; - } - } */// ce_level - } else if ((eNB->prach_energy_counter == 100) && - (max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) { - LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", - eNB->Mod_id, - eNB->CC_id, - proc->frame_prach, - proc->subframe_prach, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - max_preamble_delay[0]); - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; - eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; - eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; - eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; - eNB->UL_INFO.rach_ind.sfn_sf = proc->frame_prach<<4 | proc->subframe_prach; - eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; - eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; - eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; - eNB->preamble_list[0].preamble_rel8.rnti = 1+proc->subframe_prach; // note: fid is implicitly 0 here - eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; - eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is - - if (NFAPI_MODE==NFAPI_MODE_PNF) { // If NFAPI PNF then we need to send the message to the VNF - LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), - eNB->preamble_list[0].preamble_rel8.timing_advance, - eNB->preamble_list[0].preamble_rel8.preamble, - eNB->preamble_list[0].preamble_rel8.rnti, - eNB->preamble_list[0].preamble_rel13.rach_resource_type); - oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; - } - - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - } // max_preamble_energy > prach_I0 + 100 - else { - eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((avg_preamble_energy[0]*124)>>10); - - if (eNB->prach_energy_counter < 100) - eNB->prach_energy_counter++; - } -} // else br_flag - -void prach_eNB(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int frame,int subframe) { - // check if we have to detect PRACH first - if (is_prach_subframe(&eNB->frame_parms, frame,subframe)>0) { - prach_procedures_ocp(eNB, proc, 0); - prach_procedures_ocp(eNB, proc, 1); - } -} - -static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name) { - AssertFatal( eNB !=NULL, ""); - - if (NFAPI_MODE==NFAPI_MODE_PNF) { - // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - //add_subframe(&frame, &subframe, 4); - //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); - oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - } - - AssertFatal( !(NFAPI_MODE==NFAPI_MODE_PNF && - eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0), ""); - prach_eNB(eNB,proc,proc->frame_rx,proc->subframe_rx); - release_UE_in_freeList(eNB->Mod_id); - - // UE-specific RX processing for subframe n - if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - phy_procedures_eNB_uespec_RX(eNB, proc); - } - - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.frame = proc->frame_rx; - eNB->UL_INFO.subframe = proc->subframe_rx; - eNB->UL_INFO.module_id = eNB->Mod_id; - eNB->UL_INFO.CC_id = eNB->CC_id; - eNB->if_inst->UL_indication(&eNB->UL_INFO, proc); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - phy_procedures_eNB_TX(eNB, proc, 1); - return(0); -} - -void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc) { - LTE_DL_FRAME_PARMS *fp = ru->frame_parms; - void *rxp[ru->nb_rx]; - unsigned int rxs; - int i; - openair0_timestamp ts=0, timestamp_rx; - static openair0_timestamp old_ts=0; - - for (i=0; i<ru->nb_rx; i++) - //receive in the next slot - rxp[i] = (void *)&ru->common.rxdata[i][((proc->subframe_rx+1)%10)*fp->samples_per_tti]; - - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &ts, - rxp, - fp->samples_per_tti, - ru->nb_rx); - timestamp_rx = ts-ru->ts_offset; - - // AssertFatal(rxs == fp->samples_per_tti, - // "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); - if(rxs != fp->samples_per_tti) { - LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); -#if defined(USRP_REC_PLAY) - exit_fun("Exiting IQ record/playback"); -#else - //exit_fun( "problem receiving samples" ); - LOG_E(PHY, "problem receiving samples"); -#endif - } - - if (old_ts != 0 && timestamp_rx - old_ts != fp->samples_per_tti) { - LOG_E(HW,"impossible shift in rx stream, rx: %ld, previous rx distance: %ld, should be %d\n", timestamp_rx, proc->timestamp_rx - old_ts, fp->samples_per_tti); - //ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); - //proc->timestamp_rx = ts-ru->ts_offset; - } - - old_ts=timestamp_rx; - setAllfromTS(timestamp_rx, proc); -} - -void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc) { - LTE_DL_FRAME_PARMS *fp = ru->frame_parms; - void *txp[ru->nb_tx]; - int i; - lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10); - lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10); - int sf_extension = 0; - - if ((SF_type == SF_DL) || - (SF_type == SF_S)) { - int siglen=fp->samples_per_tti; - radio_tx_burst_flag_t flags = TX_BURST_MIDDLE; - - if (SF_type == SF_S) { - /* end_of_burst_delay is used to stop TX only "after a while". - * If we stop right after effective signal, with USRP B210 and - * B200mini, we observe a high EVM on the S subframe (on the - * PSS). - * A value of 400 (for 30.72MHz) solves this issue. This is - * the default. - */ - siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) - + (fp->dl_symbols_in_S_subframe - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples) - + ru->end_of_burst_delay; - flags = TX_BURST_END; - } - - if (fp->frame_type == TDD && - SF_type == SF_DL && - prevSF_type == SF_UL) { - flags = TX_BURST_START; - sf_extension = ru->sf_extension; - } - -#if defined(__x86_64) || defined(__i386__) - sf_extension = (sf_extension)&0xfffffff8; -#elif defined(__arm__) || defined(__aarch64__) - sf_extension = (sf_extension)&0xfffffffc; -#endif - - for (i=0; i<ru->nb_tx; i++) - txp[i] = (void *)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension]; - - /* add fail safe for late command end */ - // prepare tx buffer pointers - ru->rfdevice.trx_write_func(&ru->rfdevice, - proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, subframe %d\n",ru->idx, - (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->subframe_tx); - } - - return; -} - -static void *ru_thread( void *param ) { - setbuf(stdout, NULL); - setbuf(stderr, NULL); - RU_t *ru = (RU_t *)param; - L1_rxtx_proc_t L1proc= {0}; - // We pick the global thread pool from the legacy code global vars - L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool; - L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode; - L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode; - - if (ru->if_south == LOCAL_RF) { // configure RF parameters only - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(ru->frame_parms,1); - phy_init_RU(ru); - init_rf(ru); - } - - AssertFatal(setup_RU_buffers(ru)==0, "Exiting, cannot initialize RU Buffers\n"); - LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx); - wait_sync("ru_thread"); - - // Start RF device if any - if (ru->rfdevice.trx_start_func(&ru->rfdevice) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else - LOG_I(PHY,"RU %d rf device ready\n",ru->idx); - - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices - while (!oai_exit) { - // synchronization on input FH interface, acquire signals/data and block - rx_rf(ru, &L1proc); - // do RX front-end processing (frequency-shift, dft) if needed - fep_full(ru, L1proc.subframe_rx); - - // At this point, all information for subframe has been received on FH interface - // If this proc is to provide synchronization, do so - // Fixme: not used - // wakeup_slaves(proc); - for (int i=0; i<ru->num_eNB; i++) { - char string[20]; - sprintf(string,"Incoming RU %d",ru->idx); - - if (rxtx(ru->eNB_list[i],&L1proc,string) < 0) - LOG_E(PHY,"eNB %d CC_id %d failed during execution\n", - ru->eNB_list[i]->Mod_id,ru->eNB_list[i]->CC_id); - } - - // do TX front-end processing if needed (precoding and/or IDFTs) - feptx_prec(ru, L1proc.frame_tx, L1proc.subframe_tx); - // do OFDM if needed - feptx_ofdm(ru, L1proc.frame_tx, L1proc.subframe_tx); - // do outgoing fronthaul (south) if needed - ocp_tx_rf(ru, &L1proc); - } - - LOG_W(PHY,"Exiting ru_thread \n"); - ru->rfdevice.trx_end_func(&ru->rfdevice); - LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); - return NULL; -} - -int init_rf(RU_t *ru) { - char name[256]; - pthread_getname_np(pthread_self(),name, 255); - pthread_setname_np(pthread_self(),"UHD for OAI"); - int ret=openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - pthread_setname_np(pthread_self(),name); - return ret; -} - -void ocp_init_RU(RU_t *ru, char *rf_config_file, int send_dmrssync) { - PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; - int i; - int CC_id; - // read in configuration file) - LOG_I(PHY,"configuring RU from file\n"); - LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n", - RC.nb_L1_inst,RC.nb_RU,get_nprocs()); - - if (RC.nb_CC != 0) - for (i=0; i<RC.nb_L1_inst; i++) - for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++) - RC.eNB[i][CC_id]->num_RU=0; - - LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - ru->rf_config_file = rf_config_file; - ru->idx = 0; - ru->ts_offset = 0; - - if (ru->is_slave == 1) { - ru->in_synch = 0; - ru->generate_dmrs_sync = 0; - } else { - ru->in_synch = 1; - ru->generate_dmrs_sync=send_dmrssync; - } - - ru->cmd = EMPTY; - ru->south_out_cnt= 0; - - // ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0; - if (ru->generate_dmrs_sync == 1) { - generate_ul_ref_sigs(); - ru->dmrssync = (int16_t *)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t)); - } - - ru->wakeup_L1_sleeptime = 2000; - ru->wakeup_L1_sleep_cnt_max = 3; - - if (ru->num_eNB > 0) { - AssertFatal(ru->eNB_list[0], "ru->eNB_list is not initialized\n"); - } else { - LOG_E(PHY,"Wrong data model, assigning eNB 0, carrier 0 to RU 0\n"); - ru->eNB_list[0] = RC.eNB[0][0]; - ru->num_eNB=1; - } - - eNB0 = ru->eNB_list[0]; - // datamodel error in regular OAI: a RU uses one single eNB carrier parameters! - ru->frame_parms = &eNB0->frame_parms; - - for (i=0; i<ru->num_eNB; i++) { - eNB0 = ru->eNB_list[i]; - int ruIndex=eNB0->num_RU++; - eNB0->RU_list[ruIndex] = ru; - } -} - -void stop_RU(int nb_ru) { - for (int inst = 0; inst < nb_ru; inst++) { - LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - //kill_RU_proc(RC.ru[inst]); - } -} - -/* --------------------------------------------------------*/ -/* from here function to use configuration module */ -static int DEFBFW[] = {0x00007fff}; -void ocpRCconfig_RU(RU_t *ru) { - paramdef_t RUParams[] = RUPARAMS_DESC; - paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; - config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); - - if ( RUParamList.numelt == 0 ) { - LOG_W(PHY, "Calling RCconfig_RU while no ru\n"); - RC.nb_RU = 0; - return; - } // setting != NULL - - ru->idx = 0; - ru->if_timing = synch_to_ext_device; - paramdef_t *vals=RUParamList.paramarray[0]; - - if (RC.nb_L1_inst >0) - ru->num_eNB = vals[RU_ENB_LIST_IDX].numelt; - else - ru->num_eNB = 0; - - for (int i=0; i<ru->num_eNB; i++) - ru->eNB_list[i] = RC.eNB[vals[RU_ENB_LIST_IDX].iptr[i]][0]; - - if (config_isparamset(vals, RU_SDR_ADDRS)) { - ru->openair0_cfg.sdr_addrs = strdup(*(vals[RU_SDR_ADDRS].strptr)); - } - - if (config_isparamset(vals, RU_SDR_CLK_SRC)) { - char *paramVal=*(vals[RU_SDR_CLK_SRC].strptr); - LOG_D(PHY, "RU clock source set as %s\n", paramVal); - - if (strcmp(paramVal, "internal") == 0) { - ru->openair0_cfg.clock_source = internal; - } else if (strcmp(paramVal, "external") == 0) { - ru->openair0_cfg.clock_source = external; - } else if (strcmp(paramVal, "gpsdo") == 0) { - ru->openair0_cfg.clock_source = gpsdo; - } else { - LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", paramVal); - } - } - - if (strcmp(*(vals[RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(vals,RU_LOCAL_IF_NAME_IDX)) ) { - ru->if_south = LOCAL_RF; - ru->function = eNodeB_3GPP; - } else { - ru->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); - ru->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); - ru->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); - ru->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); - ru->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); - ru->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); - ru->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); - } - - ru->max_pdschReferenceSignalPower = *(vals[RU_MAX_RS_EPRE_IDX].uptr);; - ru->max_rxgain = *(vals[RU_MAX_RXGAIN_IDX].uptr); - ru->num_bands = vals[RU_BAND_LIST_IDX].numelt; - /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ - ru->sf_extension = *(vals[RU_SF_EXTENSION_IDX].uptr); - ru->end_of_burst_delay = *(vals[RU_END_OF_BURST_DELAY_IDX].uptr); - - for (int i=0; i<ru->num_bands; i++) - ru->band[i] = vals[RU_BAND_LIST_IDX].iptr[i]; - } else { - ru->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); - ru->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); - ru->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); - ru->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); - ru->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); - ru->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); - ru->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); - } /* strcmp(local_rf, "yes") != 0 */ - - ru->nb_tx = *(vals[RU_NB_TX_IDX].uptr); - ru->nb_rx = *(vals[RU_NB_RX_IDX].uptr); - ru->att_tx = *(vals[RU_ATT_TX_IDX].uptr); - ru->att_rx = *(vals[RU_ATT_RX_IDX].uptr); - return; -} - - -static void get_options(void) { - CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - get_common_options(SOFTMODEM_ENB_BIT); - CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); - - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - memset((void *)&RC,0,sizeof(RC)); - /* Read RC configuration file */ - RCConfig(); - NB_eNB_INST = RC.nb_inst; - printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU); - - if (!IS_SOFTMODEM_NONBIOT) { - load_NB_IoT(); - printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", - RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst); - } else { - printf("All Nb-IoT instances disabled\n"); - RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0; - } - } -} - -void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { - int CC_id; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id] = (LTE_DL_FRAME_PARMS *) malloc(sizeof(LTE_DL_FRAME_PARMS)); - /* Set some default values that may be overwritten while reading options */ - frame_parms[CC_id]->frame_type = FDD; - frame_parms[CC_id]->tdd_config = 3; - frame_parms[CC_id]->tdd_config_S = 0; - frame_parms[CC_id]->N_RB_DL = 100; - frame_parms[CC_id]->N_RB_UL = 100; - frame_parms[CC_id]->Ncp = NORMAL; - frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms[CC_id]->Nid_cell = 0; - frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms[CC_id]->nb_antenna_ports_eNB = 1; - frame_parms[CC_id]->nb_antennas_tx = 1; - frame_parms[CC_id]->nb_antennas_rx = 1; - frame_parms[CC_id]->nushift = 0; - frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; - frame_parms[CC_id]->phich_config_common.phich_duration = normal; - // UL RS Config - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; - // downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31. - // downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; - // downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; - // downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; - //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]); - frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0]; - } -} - -void init_pdcp(void) { - pdcp_layer_init(); - uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? - (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; - - if (IS_SOFTMODEM_NOS1) - pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; - - pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT; - - if ( split73!=SPLIT73_DU) - pdcp_module_init(pdcp_initmask, 0); - - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); - } -} - -static void wait_nfapi_init(char *thread_name) { - LOG_I(ENB_APP, "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); - pthread_mutex_lock( &nfapi_sync_mutex ); - - while (nfapi_sync_var<0) - pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); - - pthread_mutex_unlock(&nfapi_sync_mutex); - LOG_I(ENB_APP, "NFAPI: got sync (%s)\n", thread_name); -} - -void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { - LOG_I(ENB_APP, "sending TERMINATE_MESSAGE from task %s (%d) to task %s (%d)\n", - itti_get_task_name(from), from, itti_get_task_name(to), to); - MessageDef *msg; - msg = itti_alloc_new_message (from, 0, TERMINATE_MESSAGE); - itti_send_msg_to_task (to, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); -} - -int main ( int argc, char **argv ) { - //mtrace(); - int i; - int CC_id = 0; - sf_ahead=4; // Bell Labs - AssertFatal(load_configmodule(argc,argv,0), "[SOFTMODEM] Error, configuration module init failed\n"); - logInit(); - printf("Reading in command-line options\n"); - get_options (); - AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n"); - EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; -#if T_TRACER - T_Config_Init(); -#endif - set_latency_target(); - set_softmodem_sighandler(); - cpuf=get_cpu_freq_GHz(); - set_taus_seed (0); - - if (opp_enabled ==1) - reset_opp_meas(); - - itti_init(TASK_MAX, tasks_info); - init_opt(); -#ifndef PACKAGE_VERSION -# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" -#endif - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - - /* Read configuration */ - if (RC.nb_inst > 0) { - // Allocate memory from RC variable - read_config_and_init(); - } else { - printf("RC.nb_inst = 0, Initializing L1\n"); - RCconfig_L1(); - } - - // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. - // but RU thread deals with pre_scd and this is necessary in VNF and simulator. - // some initialization is necessary and init_ru_vnf do this. - RU_t ru; - - if ( NFAPI_MODE != NFAPI_MODE_VNF) { - ocpRCconfig_RU(&ru); - LOG_I(PHY, - "number of L1 instances %d, number of RU %d, number of CPU cores %d\n", - RC.nb_L1_inst, RC.nb_RU, get_nprocs()); - } - - if ( strlen(get_softmodem_params()->split73) > 0 ) { - char tmp[1024]= {0}; - strncpy(tmp,get_softmodem_params()->split73, 1023); - tmp[2]=0; - - if ( strncasecmp(tmp,"cu", 2)==0 ) - split73=SPLIT73_CU; - else if ( strncasecmp(tmp,"du", 2)==0 ) - split73=SPLIT73_DU; - else - AssertFatal(false,"split73 syntax: <cu|du>:<remote ip addr>[:<ip port>] (string found: %s) \n",get_softmodem_params()->split73); - } - - if (RC.nb_inst > 0) { - /* Start the agent. If it is turned off in the configuration, it won't start */ - - /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks */ - init_pdcp(); - AssertFatal(create_tasks(1)==0,"cannot create ITTI tasks\n"); - - for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) { - MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); - RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; - itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - } - } - - if (RC.nb_inst > 0) { - protocol_ctxt_t ctxt; - ctxt.module_id = 0 ; - ctxt.instance = 0; - ctxt.rnti = 0; - ctxt.enb_flag = 1; - ctxt.frame = 0; - ctxt.subframe = 0; - pdcp_run(&ctxt); - } - - /* start threads if only L1 or not a CU */ - if (RC.nb_inst == 0 || NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) { - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs); - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - - if (NFAPI_MODE!=NFAPI_MONOLITHIC) { - LOG_I(ENB_APP,"NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - } - - if (NFAPI_MODE==NFAPI_MODE_VNF) {// VNF -#if defined(PRE_SCD_THREAD) - init_ru_vnf(); // ru pointer is necessary for pre_scd. -#endif - wait_nfapi_init("main?"); - } - - LOG_I(ENB_APP,"START MAIN THREADS\n"); - // start the main threads - number_of_cards = 1; - printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); - - if (RC.nb_L1_inst > 0) { - printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", - get_softmodem_params()->single_thread_flag, - get_softmodem_params()->wait_for_sync); - init_eNB(get_softmodem_params()->single_thread_flag, - get_softmodem_params()->wait_for_sync); - } - - for (int x=0; x < RC.nb_L1_inst; x++) - for (int CC_id=0; CC_id<RC.nb_L1_CC[x]; CC_id++) { - L1_rxtx_proc_t *L1proc= &RC.eNB[x][CC_id]->proc.L1_proc; - L1proc->threadPool=(tpool_t *)malloc(sizeof(tpool_t)); - L1proc->respEncode=(notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t)); - L1proc->respDecode=(notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t)); - - initTpool(get_softmodem_params()->threadPoolConfig, L1proc->threadPool,cpumeas(CPUMEAS_GETSTATE)); - initNotifiedFIFO(L1proc->respEncode); - initNotifiedFIFO(L1proc->respDecode); - } - } - - printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - - if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) { - printf("Initializing RU threads\n"); - ocp_init_RU(&ru, - get_softmodem_params()->rf_config_file, - get_softmodem_params()->send_dmrs_sync); - ru.rf_map.card=0; - ru.rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); - init_RU_proc(&ru); - config_sync_var=0; - - if (NFAPI_MODE==NFAPI_MODE_PNF) { // PNF - wait_nfapi_init("main?"); - } - - LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU); - // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) - printf("ALL RUs ready - init eNBs\n"); - sleep(1); - - if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) { - LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n"); - init_eNB_afterRU(); - } else { - LOG_I(ENB_APP,"NFAPI mode - DO NOT call init_eNB_afterRU()\n"); - } - - LOG_UI(ENB_APP,"ALL RUs ready - ALL eNBs ready\n"); - // connect the TX/RX buffers - sleep(1); /* wait for thread activation */ - LOG_I(ENB_APP,"Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); - config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); - } - - create_tasks_mbms(1); - // wait for end of program - LOG_UI(ENB_APP,"TYPE <CTRL-C> TO TERMINATE\n"); - // CI -- Flushing the std outputs for the previous marker to show on the eNB / DU / CU log file - fflush(stdout); - fflush(stderr); - - // end of CI modifications - //getchar(); - if(IS_SOFTMODEM_DOSCOPE) - load_softscope("enb", NULL); - - itti_wait_tasks_end(); - oai_exit=1; - LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit); - // stop threads - - if (RC.nb_inst == 0) { - if(IS_SOFTMODEM_DOSCOPE) - end_forms(); - - LOG_I(ENB_APP,"stopping MODEM threads\n"); - stop_eNB(NB_eNB_INST); - stop_RU(RC.nb_RU); - - /* release memory used by the RU/eNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - for (int inst = 0; inst < NB_eNB_INST; inst++) { - for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { - free_transport(RC.eNB[inst][cc_id]); - phy_free_lte_eNB(RC.eNB[inst][cc_id]); - } - } - - free_lte_top(); - end_configmodule(); - pthread_cond_destroy(&sync_cond); - pthread_mutex_destroy(&sync_mutex); - pthread_cond_destroy(&nfapi_sync_cond); - pthread_mutex_destroy(&nfapi_sync_mutex); - pthread_mutex_destroy(&ue_pf_po_mutex); - } - - terminate_opt(); - logClean(); - printf("Bye.\n"); - return 0; -} diff --git a/executables/main_ru.c b/executables/main_ru.c index 9f9df6e84c9b39fc22f31de58b5d85d6d1532baa..ee2e6dc39c604f5a009c41ba5c4133189df34d83 100644 --- a/executables/main_ru.c +++ b/executables/main_ru.c @@ -56,7 +56,6 @@ #include "openair2/ENB_APP/enb_paramdef.h" #include "system.h" -#include <executables/split_headers.h> #include <executables/softmodem-common.h> #include <executables/thread-common.h> diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 025cc344810cfa0571eab32122dbe56f5fa2e99e..86834927a6e5c39db6c1b300848235e61d17c23f 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -153,19 +153,8 @@ int otg_enabled; uint32_t timing_advance = 0; uint64_t num_missed_slots=0; // counter for the number of missed slots -#include <executables/split_headers.h> #include <SIMULATION/ETH_TRANSPORT/proto.h> -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, - uint16_t rnti, int32_t stat) { - AssertFatal(false, "Must not be called in this context\n"); -} - - extern void reset_opp_meas(void); extern void print_opp_meas(void); diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 1263d9713b55e31c6a08d9b0afe7fc5d9a48c4c2..b44a81d791d04796e17c6e6d07e464903a298f06 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -107,7 +107,6 @@ extern "C" /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define RF_CONFIG_FILE softmodem_params.rf_config_file -#define SPLIT73 softmodem_params.split73 #define TP_CONFIG softmodem_params.threadPoolConfig #define PHY_TEST softmodem_params.phy_test #define DO_RA softmodem_params.do_ra @@ -137,7 +136,6 @@ extern "C" extern int usrp_tx_thread; #define CMDLINE_PARAMS_DESC { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, 0},\ - {"split73", CONFIG_HLP_SPLIT73, 0, strptr:&SPLIT73, defstrval:NULL, TYPE_STRING, 0}, \ {"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:&TP_CONFIG, defstrval:"-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \ {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \ @@ -207,7 +205,6 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ - { .s5 = { NULL } }, \ { .s3a = { config_checkstr_assign_integer, \ {"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ @@ -287,7 +284,6 @@ typedef struct { uint64_t optmask; //THREAD_STRUCT thread_struct; char *rf_config_file; - char *split73; char *threadPoolConfig; int phy_test; int do_ra; diff --git a/executables/split_headers.h b/executables/split_headers.h deleted file mode 100644 index dc451773c5bf887030ded0c2a691f4473b0d7032..0000000000000000000000000000000000000000 --- a/executables/split_headers.h +++ /dev/null @@ -1,331 +0,0 @@ -/* -* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The OpenAirInterface Software Alliance licenses this file to You under -* the OAI Public License, Version 1.1 (the "License"); you may not use this file -* except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.openairinterface.org/?page_id=698 -* -* Author and copyright: Laurent Thomas, open-cells.com -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*------------------------------------------------------------------------------- -* For more information about the OpenAirInterface (OAI) Software Alliance: -* contact@openairinterface.org -*/ - - -#ifndef __SPLIT_HEADERS_H -#define __SPLIT_HEADERS_H - -#include <stdint.h> -#include <stdbool.h> -#include <openair1/PHY/defs_eNB.h> -#include <common/utils/telnetsrv/telnetsrv_proccmd.h> - -#define CU_PORT "7878" -#define DU_PORT "8787" -#define SPLIT73_CU 1 -#define SPLIT73_DU 2 -extern int split73; - -#define MTU 65536 -#define UDP_TIMEOUT 900000L // in micro second (struct timeval, NOT struct timespec) -// linux may timeout for a much longer time (up to 10ms) -#define blockAlign 32 //bytes to align memory for SIMD copy (256 bits vectors) - -// FS6 transport configuration and handler -typedef struct { - char *sourceIP; - char *sourcePort; - char *destIP; - char *destPort; - struct addrinfo *destAddr; - int sockHandler; -} UDPsock_t; - -#define CTsentCUv0 0xA500 -#define CTsentDUv0 0x5A00 - -// Main FS6 transport layer header -// All packets starts with this header -typedef struct commonUDP_s { - uint64_t timestamp; // id of the group (subframe for LTE) - uint16_t nbBlocks; // total number of blocks for this timestamp - uint16_t blockID; // id: 0..nbBocks-1 - uint16_t contentType; // defines the content format - uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes - uint64_t senderClock; -} commonUDP_t; - -// FS6 UL common header (DU to CU) -// gives the RACH detection data and is always sent to inform the CU that a subframe arrived -typedef struct { - uint16_t max_preamble[4]; - uint16_t max_preamble_energy[4]; - uint16_t max_preamble_delay[4]; - uint16_t avg_preamble_energy[4]; -} fs6_ul_t; - -// FS6 DL common header (CU to DU) -// gives the DCI configuration from each subframe -typedef struct { - uint8_t pbch_pdu[4]; - int num_pdcch_symbols; - int num_dci; - DCI_ALLOC_t dci_alloc[8]; - int num_mdci; - int amp; - LTE_eNB_PHICH phich_vars; - uint64_t DuClock; - uint64_t CuSpentMicroSec; -} fs6_dl_t; - -// a value to type all sub packets, -// to detect errors, and to be able to extend to other versions -// the first byte of each sub structure should match one of these values -enum pckType { - fs6UlConfig=25, - fs6DlConfig=26, - fs6ULConfigCCH=27, - fs6ULsch=28, - fs6ULcch=29, - fs6ULindicationHarq=40, - fs6ULindicationSr=41, -}; - -// CU to DU definition of a future UL subframe decode -// defines a UE future data plane -typedef struct { - enum pckType type:8; - uint16_t UE_id; - int8_t harq_pid; - UE_type_t ue_type; - - uint8_t dci_alloc; - uint8_t rar_alloc; - SCH_status_t status; - uint8_t Msg3_flag; - uint8_t subframe; - uint32_t frame; - uint8_t handled; - uint8_t phich_active; - uint8_t phich_ACK; - uint16_t previous_first_rb; - uint32_t B; - uint32_t G; - UCI_format_t uci_format; - uint8_t Or2; - uint8_t o_RI[2]; - uint8_t o_ACK[4]; - uint8_t O_ACK; - uint8_t o_RCC; - int16_t q_ACK[MAX_ACK_PAYLOAD]; - int16_t q_RI[MAX_RI_PAYLOAD]; - uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS]; - uint8_t ndi; - uint8_t round; - uint8_t rvidx; - uint8_t Nl; - uint8_t n_DMRS; - uint8_t previous_n_DMRS; - uint8_t n_DMRS2; - int32_t delta_TF; - uint32_t repetition_number ; - uint32_t total_number_of_repetitions; - - uint16_t harq_mask; - uint16_t nb_rb; - uint8_t Qm; - uint16_t first_rb; - uint8_t O_RI; - uint8_t Or1; - uint16_t Msc_initial; - uint8_t Nsymb_initial; - uint8_t V_UL_DAI; - uint8_t srs_active; - uint32_t TBS; - uint8_t Nsymb_pusch; - uint8_t Mlimit; - uint8_t max_turbo_iterations; - uint8_t bundling; - uint16_t beta_offset_cqi_times8; - uint16_t beta_offset_ri_times8; - uint16_t beta_offset_harqack_times8; - uint8_t Msg3_active; - uint16_t rnti; - uint8_t cyclicShift; - uint8_t cooperation_flag; - uint8_t num_active_cba_groups; - uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; -} fs6_dl_ulsched_t; - -// CU to DU defintion of a DL packet for a given UE -// The data itself is padded at the end of this structure -typedef struct { - enum pckType type:8; - int UE_id; - int8_t harq_pid; - uint16_t rnti; - int16_t sqrt_rho_a; - int16_t sqrt_rho_b; - CEmode_t CEmode:8; - uint16_t nb_rb; - uint8_t Qm; - int8_t Nl; - uint8_t pdsch_start; - uint8_t sib1_br_flag; - uint16_t i0; - uint32_t rb_alloc[4]; - int dataLen; -} fs6_dl_uespec_t; - -// CU to DU definition of CCH channel -typedef struct { - int16_t UE_id; - LTE_eNB_UCI cch_vars; -} fs6_dl_uespec_ulcch_element_t; - -// header to group all UE CCH channels definitions in one UDP packet -typedef struct { - enum pckType type:8; - int16_t nb_active_ue; -} fs6_dl_uespec_ulcch_t; - -// code internal, not transmitted as this -typedef struct { - int ta; -} ul_propagation_t; - -// One UE UL data, data plane, UE data appended after the header -typedef struct { - enum pckType type:8; - short UE_id; - uint8_t harq_id; - uint8_t segment; - int segLen; - int r_offset; - int G; - int ulsch_power[2]; - uint8_t o_ACK[4]; - uint8_t O_ACK; - int ta; - uint8_t o[MAX_CQI_BYTES]; - uint8_t cqi_crc_status; -} fs6_ul_uespec_t; - -// UL UCI (control plane), per UE -typedef struct { - enum pckType type:8; - int UEid; - int frame; - int subframe; - LTE_eNB_UCI uci; - uint8_t harq_ack[4]; - uint8_t tdd_mapping_mode; - uint16_t tdd_multiplexing_mask; - unsigned short n0_subband_power_dB; - uint16_t rnti; - int32_t stat; -} fs6_ul_uespec_uci_element_t; - -// all segments UCI grouped in one UDP packet -typedef struct { - enum pckType type:8; - int16_t nb_active_ue; -} fs6_ul_uespec_uci_t; - - -bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result); -int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType); -int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType); - -#define initBufferZone(xBuf) \ - uint8_t xBuf[FS6_BUF_SIZE]; \ - ((commonUDP_t *)xBuf)->nbBlocks=0; - -#define hUDP(xBuf) ((commonUDP_t *)xBuf) -#define hDL(xBuf) ((fs6_dl_t*)(((commonUDP_t *)xBuf)+1)) -#define hUL(xBuf) ((fs6_ul_t*)(((commonUDP_t *)xBuf)+1)) -#define hDLUE(xBuf) ((fs6_dl_uespec_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) -#define hTxULUE(xBuf) ((fs6_dl_ulsched_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) -#define hTxULcch(xBuf) ((fs6_dl_uespec_ulcch_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) -#define hULUE(xBuf) ((fs6_ul_uespec_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1)) -#define hULUEuci(xBuf) ((fs6_ul_uespec_uci_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1)) - -static inline size_t alignedSize(uint8_t *ptr) { - commonUDP_t *header=(commonUDP_t *) ptr; - return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign; -} - -static inline void *commonUDPdata(uint8_t *ptr) { - return (void *) (((commonUDP_t *)ptr)+1); -} - -void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc); -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, - uint16_t rnti, int32_t stat); -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset); -void *cu_fs6(void *arg); -void *du_fs6(void *arg); -void fill_rf_config(RU_t *ru, char *rf_config_file); -int init_rf(RU_t *ru); -void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc); -void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc); -void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe); -void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int fembms_flag); -bool dlsch_procedures(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - int harq_pid, - LTE_eNB_DLSCH_t *dlsch, - LTE_eNB_UE_stats *ue_stats) ; -void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req); -void pdsch_procedures(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - int harq_pid, - LTE_eNB_DLSCH_t *dlsch, - LTE_eNB_DLSCH_t *dlsch1); -void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); -void uci_procedures(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc); -void ocp_rx_prach(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - RU_t *ru, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, - uint16_t Nf, - uint8_t tdd_mapindex, - uint8_t br_flag); -void rx_prach0(PHY_VARS_eNB *eNB, - RU_t *ru, - int frame_prach, - int subframe, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, - uint16_t Nf, - uint8_t tdd_mapindex, - uint8_t br_flag, - uint8_t ce_level - ); -void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc); - -// mistakes in main OAI -void phy_init_RU(RU_t *); -void fep_full(RU_t *ru, int subframe); -void feptx_prec(RU_t *ru,int frame,int subframe); -void feptx_ofdm(RU_t *ru, int frame, int subframe); -void oai_subframe_ind(uint16_t sfn, uint16_t sf); -void softmodem_printresources(int sig, telnet_printfunc_t pf); -extern uint16_t sf_ahead; -#endif diff --git a/executables/transport_split.c b/executables/transport_split.c deleted file mode 100644 index 6a21e90a6fffa6990b6eee514a57734f78b3f65b..0000000000000000000000000000000000000000 --- a/executables/transport_split.c +++ /dev/null @@ -1,195 +0,0 @@ -/* -* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The OpenAirInterface Software Alliance licenses this file to You under -* the OAI Public License, Version 1.1 (the "License"); you may not use this file -* except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.openairinterface.org/?page_id=698 -* -* Author and copyright: Laurent Thomas, open-cells.com -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*------------------------------------------------------------------------------- -* For more information about the OpenAirInterface (OAI) Software Alliance: -* contact@openairinterface.org -*/ - - - -#include <executables/split_headers.h> -#include <sys/types.h> /* See NOTES */ -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/udp.h> -#include <netdb.h> -#include "executables/lte-softmodem.h" - -bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result) { - struct addrinfo hints= {0}, *servinfo, *p; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_PASSIVE; - int status; - - if ((status = getaddrinfo(sourceIP, sourcePort, &hints, &servinfo)) != 0) { - LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); - return false; - } - - // loop through all the results and bind to the first we can - for(p = servinfo; p != NULL; p = p->ai_next) { - if ((result->sockHandler = socket(p->ai_family, p->ai_socktype, - p->ai_protocol)) == -1) { - LOG_W(GTPU,"socket: %s\n", strerror(errno)); - continue; - } - - if (bind(result->sockHandler, p->ai_addr, p->ai_addrlen) == -1) { - close(result->sockHandler); - LOG_W(GTPU,"bind: %s\n", strerror(errno)); - continue; - } - - break; // if we get here, we must have connected successfully - } - - if (p == NULL) { - // looped off the end of the list with no successful bind - LOG_E(GTPU,"failed to bind socket: %s %s \n",sourceIP,sourcePort); - return false; - } - - freeaddrinfo(servinfo); // all done with this structure - - if ((status = getaddrinfo(destIP, destPort, &hints, &servinfo)) != 0) { - LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); - return false; - } - - if (servinfo) { - result->destAddr=servinfo; - } else { - LOG_E(PHY,"No valid UDP addr: %s:%s\n",destIP, destPort); - return false; - } - - int enable=1; - AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,""); - struct timeval tv= {0,UDP_TIMEOUT}; - - if (IS_SOFTMODEM_RFSIM) - tv.tv_sec=2; //debug: wait 2 seconds for human understanding - - AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,""); - // Make a send/recv buffer larger than a a couple of subframe - // so the kernel will store for us in and out paquets - int buff=1000*1000*10; - AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, ""); - AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, ""); - return true; -} - -// sock: udp socket -// bufferZone: a reception area of bufferSize -int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType) { - int rcved=0; - commonUDP_t *bufOrigin=(commonUDP_t *)bufferZone; - static uint8_t crossData[65536]; - static int crossDataSize=0; - - if (crossDataSize) { - LOG_D(HW,"copy a block received in previous subframe\n"); - memcpy(bufferZone, crossData, crossDataSize); - rcved=1; - bufferZone+=crossDataSize; - crossDataSize=0; - } - - do { - //read all subframe data from the control unit - int ret=recv(sock->sockHandler, bufferZone, bufferSize, 0); - - if ( ret==-1) { - if ( errno == EWOULDBLOCK || errno== EINTR ) { - LOG_I(HW,"Received: Timeout, subframe incomplete\n"); - return rcved; - } else { - LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno)); - return -1; - } - } else { - if (hUDP(bufferZone)->contentType != contentType) - abort(); - - if (rcved && bufOrigin->timestamp != hUDP(bufferZone)->timestamp ) { - if ( hUDP(bufferZone)->timestamp > bufOrigin->timestamp ) { - LOG_W(HW,"Received data for TS: %lu before end of TS : %lu completion\n", - hUDP(bufferZone)->timestamp, - bufOrigin->timestamp); - memcpy(crossData, bufferZone, ret ); - crossDataSize=ret; - return rcved; - } else { - LOG_W(HW,"Dropping late packet\n"); - continue; - } - } - - rcved++; - bufferZone+=ret; - } - - LOG_D(HW,"Received: blocks: %d/%d, size %d, TS: %lu\n", - rcved, bufOrigin->nbBlocks, ret, bufOrigin->timestamp); - } while ( rcved == 0 || rcved < bufOrigin->nbBlocks ); - - return rcved; -} - -int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType) { - commonUDP_t *UDPheader=(commonUDP_t *)bufferZone ; - UDPheader->contentType=contentType; - UDPheader->senderClock=rdtsc_oai(); - int nbBlocks=UDPheader->nbBlocks; - int blockId=0; - - if (nbBlocks <= 0 ) { - LOG_E(PHY,"FS6: can't send blocks: %d\n", nbBlocks); - return 0; - } - - do { - if (blockId > 0 ) { - commonUDP_t *currentHeader=(commonUDP_t *)bufferZone; - currentHeader->timestamp=UDPheader->timestamp; - currentHeader->nbBlocks=UDPheader->nbBlocks; - currentHeader->blockID=blockId; - currentHeader->contentType=UDPheader->contentType; - memcpy(commonUDPdata((void *)currentHeader), commonUDPdata(bufferZone), secondHeaderSize); - } - - blockId++; - int sz=alignedSize(bufferZone); - // Let's use the first address returned by getaddrinfo() - int ret=sendto(sock->sockHandler, bufferZone, sz, 0, - sock->destAddr->ai_addr, sock->destAddr->ai_addrlen); - - if ( ret != sz ) - LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d, %s)\n", - sz, ret, errno, strerror(errno)); - - LOG_D(HW,"Sent: TS: %lu, blocks %d/%d, block size : %d \n", - UDPheader->timestamp, UDPheader->nbBlocks-nbBlocks, UDPheader->nbBlocks, sz); - bufferZone+=sz; - nbBlocks--; - } while (nbBlocks); - - return 0; -} diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 6a989edc4d23a01e34fce301e11a9d55139e8ea6..ed4ca980497dc493841a9ded76319212f91381a0 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -39,7 +39,6 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "prach_extern.h" #include <openair1/PHY/LTE_TRANSPORT/transport_proto.h> -#include <executables/split_headers.h> #include "common/utils/lte/prach_utils.h" void rx_prach0(PHY_VARS_eNB *eNB, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index ebfdceefc3cf1e3d794ef7239cc206805e9ceacf..e358ee3a58140e5a182a129e37797bb19c6b2cc5 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -41,7 +41,6 @@ #include "RRC/LTE/rrc_extern.h" #include "PHY_INTERFACE/phy_interface.h" #include "transport_proto.h" -#include <executables/split_headers.h> extern int oai_exit; @@ -321,12 +320,6 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, else E = ulsch_harq->Qm * ((GpmodC==0?0:1) + (Gp/ulsch_harq->C)); - if ( split73 == SPLIT73_DU ) { - sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->eUL+r_offset, E*sizeof(int16_t), r_offset); - r_offset += E; - continue; - } - union turboReqUnion id= {.s={ulsch->rnti,proc->frame_rx,proc->subframe_rx,0,0}}; notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboDecode_t), id.p, diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index a168652d1a93a05a541326f5c3ccf897d74fb1fc..668716e1f9a34ee2d678dc284337aa60bbb0ffd2 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -759,7 +759,6 @@ typedef struct PHY_VARS_eNB_s { int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; - uint8_t *FS6bufferZone; int32_t pusch_signal_threshold; } PHY_VARS_eNB; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a44edd830ba02f45d68376e41f687f4cd4be6385..ebc3b76ec7b52854570ffc01e98e78f6d50763e6 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -47,7 +47,6 @@ #include <time.h> #include "intertask_interface.h" -#include <executables/split_headers.h> #define MBMS_NFAPI_SCHEDULER @@ -724,12 +723,8 @@ void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { } } -void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) { - if ( split73 == SPLIT73_DU ) { - sendFs6Ulharq(fs6ULindicationSr, UEid, eNB, NULL, frame, subframe, NULL,0,0, rnti, stat); - return; - } - +void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) +{ pthread_mutex_lock(&eNB->UL_INFO_mutex); nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind; nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; @@ -1862,12 +1857,8 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har #define packetError(ConD, fmt, args...) if (!(ConD)) { LOG_E(PHY, fmt, args); goodPacket=false; } -void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) { - if ( split73 == SPLIT73_DU ) { - sendFs6Ulharq(fs6ULindicationHarq, UEid, eNB, uci, frame, subframe, harq_ack, tdd_mapping_mode, tdd_multiplexing_mask, 0, 0); - return; - } - +void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) +{ int DLSCH_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST); //AssertFatal(DLSCH_id>=0,"DLSCH_id doesn't exist rnti:%x\n", uci->rnti); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index e6bcfe4cc8c928e685cf5bc97c2dc7d52af8d44d..307b127e1a220101846636978b7277c01494119f 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -56,7 +56,6 @@ #include "unitary_defs.h" #include "dummy_functions.c" #include "executables/thread-common.h" -#include "executables/split_headers.h" #include "common/ran_context.h" void feptx_ofdm(RU_t *ru, int frame, int subframe); void feptx_prec(RU_t *ru, int frame, int subframe); @@ -92,14 +91,6 @@ static int cmpdouble(const void *p1, const void *p2) { RAN_CONTEXT_t RC; int emulate_rf = 0; -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) { - AssertFatal(false, "Must not be called in this context\n"); -} - void handler(int sig) { void *array[10]; size_t size; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index b9228ca0d27cc6d64d568a8d01958d599aa9fff4..05e42735771140358a379139ecdb40a38f51a9f2 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -52,7 +52,6 @@ #include "common/config/config_load_configmodule.h" #include "executables/thread-common.h" #include "executables/lte-softmodem.h" -#include "executables/split_headers.h" #include "common/ran_context.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" @@ -91,14 +90,6 @@ static int cmpdouble(const void *p1, const void *p2) { } RAN_CONTEXT_t RC; -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) { - AssertFatal(false, "Must not be called in this context\n"); -} - extern void fep_full(RU_t *ru, int subframe); extern void ru_fep_full_2thread(RU_t *ru, int subframe); //extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 680b566eec100b009cf1fc2b2320b4e7084a809e..6404b2641806546d035a6d0bf3238af5b60b611f 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -32,7 +32,6 @@ #include <nr_pdcp/nr_pdcp.h> #include <softmodem-common.h> #include <nr-softmodem.h> -#include <split_headers.h> #include "gnb_app.h" #include "assertions.h"