diff --git a/ci-scripts/Jenkinsfile-git-dashboard b/ci-scripts/Jenkinsfile-git-dashboard new file mode 100644 index 0000000000..6ebd46bc76 --- /dev/null +++ b/ci-scripts/Jenkinsfile-git-dashboard @@ -0,0 +1,45 @@ +#!/bin/groovy +/* + * 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 + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + + +pipeline { + agent { + label pythonExecutor + } + stages { + stage ("gDashboard") { + steps { + script { + //retrieve MR data from gitlab and export to gSheet + sh returnStdout: true, script: 'python3 ci-scripts/ran_dashboard.py' + } + } + } + } +} + + diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 3c0dba1575..d5c526acb3 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -214,14 +214,14 @@ pipeline { } } } - } + } stage ("Variant Builds") { parallel { stage ("Build basic simulator") { steps { gitlabCommitStatus(name: "Build basic-sim") { - timeout (time: 30, unit: 'MINUTES') { + timeout (time: 45, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -230,7 +230,7 @@ pipeline { stage ("Build 5G gNB-USRP") { steps { gitlabCommitStatus(name: "Build gNB-USRP") { - timeout (time: 30, unit: 'MINUTES') { + timeout (time: 45, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -239,7 +239,7 @@ pipeline { stage ("Build 5G NR-UE-USRP") { steps { gitlabCommitStatus(name: "Build nr-UE-USRP") { - timeout (time: 30, unit: 'MINUTES') { + timeout (time: 45, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -248,7 +248,7 @@ pipeline { stage ("Build eNB-ethernet") { steps { gitlabCommitStatus(name: "Build eNB-ethernet") { - timeout (time: 30, unit: 'MINUTES') { + timeout (time: 45, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -259,7 +259,7 @@ pipeline { // This is typically the last one to finish. lock (vmResource) { gitlabCommitStatus(name: "Build UE-ethernet") { - timeout (time: 30, unit: 'MINUTES') { + timeout (time: 45, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } diff --git a/ci-scripts/conf_files/channelmod_rfsimu.conf b/ci-scripts/conf_files/channelmod_rfsimu.conf new file mode 100644 index 0000000000..9a6ded24f1 --- /dev/null +++ b/ci-scripts/conf_files/channelmod_rfsimu.conf @@ -0,0 +1,57 @@ +#/* configuration for channel modelisation */ +#/* To be included in main config file when */ +#/* channel modelisation is used (rfsimulator with chanmod options enabled) */ +channelmod = { + max_chan=10; + modellist="modellist_rfsimu_1"; + modellist_rfsimu_1 = ( + { + model_name = "rfsimu_channel_enB0" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = -10; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + }, + { + model_name = "rfsimu_channel_ue1" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = 0; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + } + ); + modellist_rfsimu_2 = ( + { + model_name = "rfsimu_channel_ue0" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = 0; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + }, + { + model_name = "rfsimu_channel_ue1" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = 0; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + }, + { + model_name = "rfsimu_channel_ue2" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = 0; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + } + ); +}; + diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 4d89ad96da..087ee37f01 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -260,7 +260,6 @@ NETWORK_CONTROLLER : FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; }; - log_config : { global_log_level ="info"; @@ -279,3 +278,4 @@ NETWORK_CONTROLLER : rrc_log_verbosity ="medium"; }; +@include "channelmod_rfsimu.conf" diff --git a/ci-scripts/ran_dashboard.py b/ci-scripts/ran_dashboard.py new file mode 100644 index 0000000000..601cda1722 --- /dev/null +++ b/ci-scripts/ran_dashboard.py @@ -0,0 +1,275 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# Merge Requests Dashboard for RAN on googleSheet +# +# Required Python Version +# Python 3.x +# +#--------------------------------------------------------------------- + +#----------------------------------------------------------- +# Import +#----------------------------------------------------------- + +#import google spreadsheet API +import gspread +from oauth2client.service_account import ServiceAccountCredentials + + +import subprocess +import shlex #lexical analysis +import json #json structures +import datetime #now() and date formating +from datetime import datetime + +#----------------------------------------------------------- +# Class Declaration +#----------------------------------------------------------- + +class gDashboard: + def __init__(self, creds_file, spreadsheet, worksheet): #"creds.json", 'OAI RAN Dashboard', 'MR Status' + self.scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"] + self.creds = ServiceAccountCredentials.from_json_keyfile_name(creds_file, self.scope) + self.client = gspread.authorize(self.creds) + #spreadsheet + self.ss = self.client.open(spreadsheet) + #worksheet + self.sheet = self.ss.worksheet(worksheet) + self.ss.del_worksheet(self.sheet) #start by deleting the old sheet + self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="20") #create a new one + + self.d = {} #data dictionary + + + def fetchData(self,cmd): + #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ + process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) + output = process.stdout.readline() + tmp=output.decode("utf-8") + self.d = json.loads(tmp) + + + def gBuild(self, destinationSheetName): + + #line 1 : update date/time, format dd/mm/YY H:M:S + now = datetime.now() + dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M") + row =[dt_string] + self.sheet.insert_row(row, index=1, value_input_option='RAW') + + #line 2 empty + #line 3 is for the column names + i=3 + row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","OK MERGE","Merge conflicts"] + self.sheet.insert_row(row, index=i, value_input_option='RAW') + + #line 4 onward, MR data lines + for x in range(len(self.d)): + i=i+1 + date_time_str = self.d[x]['created_at'] + date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ') + + milestone1=milestone2=milestone3=milestone4="" + if self.d[x]['milestone']!=None: + if self.d[x]['milestone']['title']=="REVIEW_CAN_START": + milestone1="X" + elif self.d[x]['milestone']['title']=="REVIEW_IN_PROGRESS": + milestone2="X" + elif self.d[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED": + milestone3="X" + elif self.d[x]['milestone']['title']=="OK_TO_BE_MERGED": + milestone4="X" + else: + pass + else: + pass + + #check if empty or not + if self.d[x]['assignee']!=None: + assignee = str(self.d[x]['assignee']['name']) + else: + assignee = "" + + #check if empty or not + if len(self.d[x]['reviewers'])!=0: + reviewer = str(self.d[x]['reviewers'][0]['name']) + else: + reviewer = "" + + if self.d[x]['has_conflicts']==True: + conflicts = "YES" + else: + conflicts = "" + + #build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR + row =["", str(date_time_obj.date()),str(self.d[x]['author']['name']),str(self.d[x]['title']),\ + assignee, reviewer,\ + milestone1,milestone2,milestone3,milestone4,conflicts] + + #insert the row to worksheet + self.sheet.insert_row(row, index=i, value_input_option='RAW') + + + #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) + i=3 + requests=[] + for x in range(len(self.d)): + rowIndex=i + colIndex=0 + hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.d[x]['iid']) +'\"' + text= '\"'+str(self.d[x]['iid'])+'"' + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) + i=i+1 + body = {"requests": requests} + self.ss.batch_update(body) + + + + def addHyperlink(self, hyperlink, text, destinationSheetName, rowIndex, colIndex): + sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId'] + request =\ + { + "updateCells": { + "rows": [ + { + "values": [ + { + "userEnteredValue": { + "formulaValue":"=HYPERLINK({},{})".format(hyperlink, text) + } + } + ] + } + ], + "fields": "userEnteredValue", + "start": { + "sheetId": sheetId, + "rowIndex": rowIndex, + "columnIndex": colIndex + } + } + } + return request + + + + def gFormat(self,sourceSheetName,destinationSheetName): # "Formating" , "MR Status" + #the requests are appended in a list of requests to be sent as one update batch; this to save API calls (quotas) + #copy formating template + sourceSheetId = self.ss.worksheet(sourceSheetName)._properties['sheetId'] + destinationSheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId'] + requests=[] + requests.append( + { + "copyPaste": { + "source": { + "sheetId": sourceSheetId, + "startRowIndex": 0, + "endRowIndex": 40, + "startColumnIndex": 0, + "endColumnIndex": 12 + }, + "destination": { + "sheetId": destinationSheetId, + "startRowIndex": 0, + "endRowIndex": 40, + "startColumnIndex": 0, + "endColumnIndex": 12 + }, + "pasteType": "PASTE_FORMAT" + } + } + ) + + + #resize columns fit to data, except col 0 + sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId'] + requests.append( + { + 'autoResizeDimensions': { + 'dimensions': { + 'sheetId': sheetId, + 'dimension': 'COLUMNS', + 'startIndex': 1, + 'endIndex': 12 + } + } + } + ) + + + #resize col 0 + sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId'] + requests.append( + { + "updateDimensionProperties": { + "range": { + "sheetId": sheetId, + "dimension": "COLUMNS", + "startIndex": 0, + "endIndex": 1 + }, + "properties": { + "pixelSize": 100 + }, + "fields": "pixelSize" + } + } + ) + + + #resize milestones to be cleaner + sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId'] + requests.append( + { + "updateDimensionProperties": { + "range": { + "sheetId": sheetId, + "dimension": "COLUMNS", + "startIndex": 6, + "endIndex": 10 + }, + "properties": { + "pixelSize": 135 + }, + "fields": "pixelSize" + } + } + ) + + body = {"requests": requests} + self.ss.batch_update(body) + + + +def main(): + my_gDashboard=gDashboard("/home/oaicicd/remi/creds.json", 'OAI RAN Dashboard', 'MR Status') + cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ + my_gDashboard.fetchData(cmd) + my_gDashboard.gBuild("MR Status") + my_gDashboard.gFormat("Formating" , "MR Status") + + + +if __name__ == "__main__": + # execute only if run as a script + main() diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e723f34d2e..16e922e7c1 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -45,6 +45,8 @@ include_directories(${CONFIG_INCLUDE_DIRS}) pkg_search_module(CRYPTO libcrypto REQUIRED) include_directories(${CRYPTO_INCLUDE_DIRS}) +#uhd 4.0 and iris installs by default in /usr/local +include_directories("/usr/local/include/") #use native cmake method as this package is not in pkg-config if (${RF_BOARD} STREQUAL "OAI_USRP") find_package(Boost REQUIRED) @@ -52,7 +54,7 @@ if (${RF_BOARD} STREQUAL "OAI_USRP") elseif (${RF_BOARD} STREQUAL "OAI_IRIS") include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") - include_directories("/usr/local/include/") + set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) LINK_DIRECTORIES("/usr/local/lib") @@ -410,6 +412,7 @@ add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") +add_boolean_option(NEW_GTPU False "NEW_GTP") set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI @@ -418,7 +421,6 @@ add_library(ITTI ) add_dependencies(ITTI rrc_flag) set(ITTI_LIB ITTI) - set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c) ################################################## @@ -2233,26 +2235,21 @@ add_library(CN_UTILS ) set(GTPV1U_DIR ${OPENAIR3_DIR}/GTPV1-U) -set (GTPV1U_SRC - ${RRC_DIR}/rrc_eNB_GTPV1U.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c - ${GTPV1U_DIR}/gtpv1u_teid_pool.c -) -add_library(GTPV1U ${GTPV1U_SRC}) -add_dependencies(GTPV1U rrc_flag) -#add_library (GTPV1U_OCP -#${OPENAIR3_DIR}/ocp-gtp/gtp_itf.cpp -#) -#include_directories(${OPENAIR3_DIR}/ocp-gtp) +add_library (GTPV1U_OCP + ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c + ${RRC_DIR}/rrc_eNB_GTPV1U.c +${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp +) +add_dependencies(GTPV1U_OCP rrc_flag) +include_directories(${OPENAIR3_DIR}/ocp-gtp) #NR case set (NR_GTPV1U_SRC ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c ${RRC_DIR}/rrc_eNB_GTPV1U.c + ${GTPV1U_DIR}/gtpv1u_eNB.c + ${GTPV1U_DIR}/gtpv1u_gNB.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c @@ -2262,6 +2259,12 @@ set (NR_GTPV1U_SRC add_library(NR_GTPV1U ${NR_GTPV1U_SRC}) add_dependencies(NR_GTPV1U rrc_flag) +if (${NEW_GTPU}) +set(GTPV1U GTPV1U_OCP) +else() +set(GTPV1U NR_GTPV1U) +endif() + set (MME_APP_SRC ${OPENAIR3_DIR}/MME_APP/mme_app.c ${OPENAIR3_DIR}/MME_APP/mme_config.c @@ -2800,6 +2803,7 @@ add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c ${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c ${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c + ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ) target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES}) @@ -2814,6 +2818,7 @@ include_directories("${OPENAIR_DIR}/common/utils/T") if (${T_TRACER}) set(T_SOURCE + ${OPENAIR_DIR}/common/utils/T/T_IDs.h ${OPENAIR_DIR}/common/utils/T/T.c ${OPENAIR_DIR}/common/utils/T/local_tracer.c) set(T_LIB "rt") @@ -2901,7 +2906,6 @@ add_executable(lte-softmodem ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -2911,7 +2915,8 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2942,7 +2947,6 @@ add_executable(ocp-enb ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -2952,7 +2956,8 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l target_link_libraries (ocp-enb -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -3022,7 +3027,8 @@ endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB - GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON + + ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES} -Wl,--end-group z dl) @@ -3050,21 +3056,20 @@ add_executable(nr-softmodem ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c ) target_link_libraries (nr-softmodem -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} @@ -3094,7 +3099,6 @@ add_executable(ocp-gnb ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${XFORMS_SOURCE_NR} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3104,7 +3108,7 @@ add_executable(ocp-gnb target_link_libraries (ocp-gnb -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON @@ -3183,6 +3187,17 @@ target_link_libraries (dlsim_tm4 pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB} ) +add_executable(rftest + ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c + ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_scope.c + ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_DIR}/executables/softmodem-common.c + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} +) +target_link_libraries(rftest minimal_lib PHY_NR_COMMON pthread dl m forms ${T_LIB} ) + add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c ${OPENAIR_DIR}/common/utils/backtrace.c @@ -3415,7 +3430,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) add_executable(test_epc_play_scenario @@ -3434,7 +3449,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) @@ -3480,7 +3495,7 @@ if (${T_TRACER}) NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR NGAP_GNB - CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB + CN_UTILS ${GTPV1U} SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts) if (TARGET ${i}) add_dependencies(${i} generate_T) @@ -3571,14 +3586,12 @@ add_executable(nr-ittisim ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3587,7 +3600,7 @@ add_executable(nr-ittisim target_link_libraries (nr-ittisim -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20 index 9ef79be9c2..4b1cda42f8 100755 --- a/cmake_targets/install_external_packages.ubuntu20 +++ b/cmake_targets/install_external_packages.ubuntu20 @@ -83,6 +83,8 @@ get_distribution_release() { check_supported_distribution() { case $(get_distribution_release) in "ubuntu20.04") return 0 ;; + "ubuntu20.10") return 0 ;; + "ubuntu21.04") return 0 ;; esac return 1 } @@ -157,8 +159,16 @@ install_protobuf_from_source(){ #cd protobuf-2.6.1/ rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz - tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner - cd protobuf-3.3.0/ || exit + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner + cd protobuf-3.3.0/ + else + export LD_LIBRARY_PATH=/usr/local/lib #protoc needs to know where toclook for shared libs + rm -rf /tmp/protobuf + git clone --depth=1 --branch=v3.3.0 https://github.com/protocolbuffers/protobuf.git /tmp/protobuf + cd /tmp/protobuf + git submodule update --init --recursive + ./autogen.sh + fi ./configure echo "Compiling protobuf" make -j"$(nproc)" @@ -198,15 +208,15 @@ install_usrp_uhd_driver_from_source(){ rm -rf /tmp/uhd git clone https://github.com/EttusResearch/uhd.git cd uhd || exit - git checkout tags/v3.13.0.2 + git checkout UHD-3.15.LTS mkdir -p host/build cd host/build || exit - $CMAKE ../ + $CMAKE ../ -GNinja echo "Compiling UHD" - make -j"$(nproc)" - make test - $SUDO make install + ninja + $SUDO ninja install $SUDO ldconfig + $SUDO /usr/lib/uhd/utils/uhd_images_downloader.py ) >& "$uhd_install_log" } @@ -329,6 +339,7 @@ check_install_ubuntu_packages() { $SUDO apt install -y software-properties-common case "$(get_distribution_release)" in "ubuntu20.04") + "ubuntu21.04") specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev" LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" @@ -345,7 +356,6 @@ check_install_ubuntu_packages() { openvpn \ pkg-config \ python3-dev \ - python-pexpect \ sshfs \ swig \ tshark \ @@ -358,7 +368,6 @@ check_install_ubuntu_packages() { iperf3 \ android-tools-adb \ wvdial \ - python-numpy \ sshpass \ nscd \ bc \ @@ -379,7 +388,6 @@ check_install_ubuntu_packages() { git \ graphviz \ gtkwave \ - guile-2.0-dev \ iperf \ iptables \ libxtables-dev \ @@ -419,7 +427,8 @@ check_install_ubuntu_packages() { libxpm-dev \ libboost-all-dev \ nettle-dev \ - nettle-bin + nettle-bin \ + libreadline-dev fi $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" diff --git a/cmake_targets/tools/run_enb_s1_usrp b/cmake_targets/tools/run_enb_s1_usrp index e119126683..1a4c6b10b8 100755 --- a/cmake_targets/tools/run_enb_s1_usrp +++ b/cmake_targets/tools/run_enb_s1_usrp @@ -101,7 +101,6 @@ function main() local -i run_gdb=0 local -i show_stdout=0 local exe_arguments="" - local itti_dump_file="" until [ -z "$1" ] do @@ -154,18 +153,6 @@ function main() exe_arguments="$exe_arguments --rf-config-file=$rf_config_file" fi ;; - -K | --itti-dump-file) - itti_dump_file=$2 - # can omit file name if last arg on the line - if [ "x$itti_dump_file" = "x" ]; then - itti_dump_file="/tmp/enb_s1_usrp_itti.log" - shift 1; - else - shift 2; - fi - echo "setting ITTI dump file to: $itti_dump_file" - exe_arguments="$exe_arguments -K $itti_dump_file" - ;; -m | --mscgen) g_msc_dir=$2 # can omit file name if last arg on the line diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 6d01d98c65..1df1bc16f7 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -255,7 +255,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */ ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */ ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) || - ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) { + ((strlen(oneargv) > 2) && (strcmp(oneargv + 2, cfgoptions[n].optname) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) { char *valptr=NULL; int ret; config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index 8baaa99bb8..0688f6531f 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -82,10 +82,12 @@ typedef struct configmodule_interface { #ifdef CONFIG_LOADCONFIG_MAIN configmodule_interface_t *cfgptr=NULL; -static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugflags]> \n \ - debugflags can also be defined in the config_libconfig section of the config file\n \ +static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugflags]><:incp[path]>\n \ + debugflags can also be defined in the config section of the config file\n \ debugflags: mask, 1->print parameters, 2->print memory allocations debug messages\n \ - 4->print command line processing debug messages\n "; + 4->print command line processing debug messages\n \ + incp parameter can be used to define the include path used for config files (@include directive)\n \ + defaults is set to the path of the main config file.\n"; #define CONFIG_SECTIONNAME "config" #define CONFIGPARAM_DEBUGFLAGS_IDX 0 diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index eb08a70183..17266246f0 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -33,8 +33,9 @@ #include #include +#include + #include -#include #include "config_libconfig.h" #include "config_libconfig_private.h" @@ -347,17 +348,35 @@ int config_libconfig_init(char *cfgP[], int numP) { config_get_if()->numptrs=0; memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS); memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated)); - + /* search for include path parameter and set config file include path accordingly */ + for (int i=0; isched_get_priority_max(SCHED_FIFO)) { + LOG_E(TMR,"Prio not possible: %d, min is %d, max: %d, forced in the range\n", + priority, + sched_get_priority_min(SCHED_OAI), + sched_get_priority_max(SCHED_OAI)); + if(prioritysched_get_priority_max(SCHED_OAI)) + priority=sched_get_priority_max(SCHED_OAI); + } + AssertFatal(priority<=sched_get_priority_max(SCHED_OAI),""); struct sched_param sparam={0}; sparam.sched_priority = priority; - pthread_attr_setschedparam(&attr, &sparam); - - pthread_create(t, &attr, func, param); + ret=pthread_attr_setschedparam(&attr, &sparam); + AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); + ret=pthread_create(t, &attr, func, param); + AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); pthread_setname_np(*t, name); if (affinity != -1 ) { @@ -216,7 +233,6 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, CPU_SET(affinity, &cpuset); AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity"); } - pthread_attr_destroy(&attr); } diff --git a/common/utils/system.h b/common/utils/system.h index a89a6c5b17..fbfd338a1a 100644 --- a/common/utils/system.h +++ b/common/utils/system.h @@ -46,9 +46,11 @@ void set_latency_target(void); void configure_linux(void); void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority); -#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO) -#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10 -#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO) + +#define SCHED_OAI SCHED_RR +#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_OAI) +#define OAI_PRIORITY_RT ((sched_get_priority_min(SCHED_OAI)+sched_get_priority_max(SCHED_OAI))/2) +#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_OAI)-2 void thread_top_init(char *thread_name, int affinity, diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 03f7af99bc..734126721a 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -461,12 +461,12 @@ int process_command(char *buf) { int i,j,k; char modulename[TELNET_CMD_MAXSIZE]; char cmd[TELNET_CMD_MAXSIZE]; - char cmdb[TELNET_MAX_MSGLENGTH]; + char *cmdb=NULL; char *bufbck; int rt; memset(modulename,0,sizeof(modulename)); memset(cmd,0,sizeof(cmd)); - memset(cmdb,0,sizeof(cmdb)); + if (strncasecmp(buf,"ex",2) == 0) return CMDSTATUS_EXIT; @@ -490,12 +490,10 @@ int process_command(char *buf) { return CMDSTATUS_FOUND; } - memset(modulename,0,sizeof(modulename)); - memset(cmd,0,sizeof(cmd)); - memset(cmdb,0,sizeof(cmdb)); + bufbck=strdup(buf); rt=CMDSTATUS_NOTFOUND; - j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb); + j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb); if (telnetparams.telnetdbg > 0) printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); @@ -562,7 +560,7 @@ int process_command(char *buf) { rt= CMDSTATUS_FOUND; } /* loop */ } /* for i */ - + free(cmdb); free(bufbck); return rt; } @@ -702,7 +700,7 @@ void poll_telnetcmdq(void *qid, void *arg) { */ void exec_moduleinit(char *modname) { void (*fptr)(void); - char initfunc[TELNET_CMD_MAXSIZE+9]; + char initfunc[TELNET_CMD_MAXSIZE+10]; if (strlen(modname) > TELNET_CMD_MAXSIZE) { fprintf(stderr,"[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n", diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 5db1a5e34e..a32b7c3859 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -37,14 +37,21 @@ #else #define THREADINIT PTHREAD_MUTEX_INITIALIZER #endif -#define mutexinit(mutex) AssertFatal(pthread_mutex_init(&mutex,NULL)==0,""); -#define condinit(signal) AssertFatal(pthread_cond_init(&signal,NULL)==0,""); -#define mutexlock(mutex) AssertFatal(pthread_mutex_lock(&mutex)==0,""); +#define mutexinit(mutex) {int ret=pthread_mutex_init(&mutex,NULL); \ + AssertFatal(ret==0,"ret=%d\n",ret);} +#define condinit(signal) {int ret=pthread_cond_init(&signal,NULL); \ + AssertFatal(ret==0,"ret=%d\n",ret);} +#define mutexlock(mutex) {int ret=pthread_mutex_lock(&mutex); \ + AssertFatal(ret==0,"ret=%d\n",ret);} #define mutextrylock(mutex) pthread_mutex_trylock(&mutex) -#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,""); -#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,""); -#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); -#define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); +#define mutexunlock(mutex) {int ret=pthread_mutex_unlock(&mutex); \ + AssertFatal(ret==0,"ret=%d\n",ret);} +#define condwait(condition, mutex) {int ret=pthread_cond_wait(&condition, &mutex); \ + AssertFatal(ret==0,"ret=%d\n",ret);} +#define condbroadcast(signal) {int ret=pthread_cond_broadcast(&signal); \ + AssertFatal(ret==0,"ret=%d\n",ret);} +#define condsignal(signal) {int ret=pthread_cond_broadcast(&signal); \ + AssertFatal(ret==0,"ret=%d\n",ret);} #define tpool_nbthreads(tpool) (tpool.nbThreads) typedef struct notifiedFIFO_elt_s { struct notifiedFIFO_elt_s *next; @@ -78,7 +85,7 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, ret->reponseFifo=reponseFifo; ret->processingFunc=processingFunc; // We set user data piece aligend 32 bytes to be able to process it with SIMD - ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32; + ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32); ret->malloced=true; return ret; } diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index a087b989fa..f2422d9822 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -210,8 +210,8 @@ time the worker finished the job time the client reads the result if you set the environement variable: -thread-pool-measurements to a valid file name +threadPoolMeasurements to a valid file name These measurements will be wrote to this Linux pipe. -A tool to read the linux fifo and display it in ascii is provided: -see the local directory Makefile for this tool and to compile the thread pool unitary tests. +A tool to read the linux fifo and display it in ascii is provided; compute the binay: +in cmake building directory: make/ninja measurement_display diff --git a/doc/SW_archi.md b/doc/SW_archi.md index d92f802148..0d03591891 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -296,6 +296,28 @@ gtp thread calls directly pdcp_data_req(), so it runs inside it's context intern ## inside other threads gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex. +# New GTP +## initialization +Coexistance until full merge with legacy GTP +cmake new option: NEW_GTPU to use the new implementation (it changes for the entire executable) +It is possible to use both old and new GTP in same executable because the itti task and all functions names are different +Current status of new implementation: not tested, X2 not developped, 5G new GTP option not developped, remain issues on data coming from void: muid, enb_flag, ... + +ocp_gtpv1uTask(): this creates only the thread, doesn't configure anything +gtpv1Init(): creates a listening socket to Linux for a given reception and select a local IP address + +newGtpuCreateTunnel() this function will replace the xxx_create_tunnel_xxx() for various cases +This creates a outgoing context for a teid (in input), it computes and return the incoming teid that will be used for incoming packets +These teids and in a "instance", so in a Linux socket: same teid can co-exist for different sockets + Remain here a lack to fill: the information given in the legacy funtions is not enough to fullfil the data needed by the callback +stuff like enb_flag, but also mui and more important data are not given explicitly by any legacy function (gtpv1u_create_s1u_tunnel), but the legacy and the new interface to lower layer (like pdcp) require this data. +The datamodel is still not fully understood, so this data source remain unknown +A new parameter is the callback function: will be pdpcp_data_req() and gtpv_data_req() (x2 case) for existing implementation and later other call backs like the F1-U implementation. + +incoming packets +the gtp layer retrieves the data, the teid, find out the related data: rnti, bearer and quite a lot of other parameters (not clear why, because it looks like all is statefull, so the lower layer should have the context) +if lower layers can be stateless, it is a good idea to keep the context in the gtp layer and pass it to the callback, but the design remain obfuscated. + # NGAP NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)? About all messages are exchanged with RRC thread diff --git a/executables/main-ocp.c b/executables/main-ocp.c index ae1db7195b..925861c71e 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -73,13 +73,15 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; volatile int oai_exit = 0; double cpuf; +msc_interface_t msc_interface; +THREAD_STRUCT thread_struct; + 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; -int usrp_tx_thread = 0; char * split73_config; int split73; AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0}; @@ -1318,7 +1320,7 @@ int main ( int argc, char **argv ) { // end of CI modifications //getchar(); - if(IS_SOFTMODEM_DOFORMS) + if(IS_SOFTMODEM_DOSCOPE) load_softscope("enb", NULL); itti_wait_tasks_end(); @@ -1327,7 +1329,7 @@ int main ( int argc, char **argv ) { // stop threads if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) { - if(IS_SOFTMODEM_DOFORMS) + if(IS_SOFTMODEM_DOSCOPE) end_forms(); LOG_I(ENB_APP,"stopping MODEM threads\n"); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index b059c6f4e8..c068bef775 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -89,7 +89,7 @@ static int DEFBFW[] = {0x00007fff}; #include "s1ap_eNB.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" - +#include #include "T.h" @@ -119,7 +119,6 @@ uint16_t sl_ahead; extern int emulate_rf; extern int numerology; -extern int usrp_tx_thread; /*************************************************************/ /* Functions to attach and configure RRU */ @@ -1344,12 +1343,17 @@ void *ru_thread( void *param ) { for (aa=0;aanb_rx;aa++) memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa], (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); - + if (IS_SOFTMODEM_DOSCOPE && RC.gNB[0]->scopeData) + ((scopeData_t*)RC.gNB[0]->scopeData)->slotFunc(ru->common.rxdataF[0],proc->tti_rx, RC.gNB[0]->scopeData); // Do PRACH RU processing int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST); uint8_t prachStartSymbol,N_dur; if (prach_id>=0) { + + T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0), + T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2)); + N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt); /* get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value, diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 63c06563d2..fd86565df5 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -85,6 +85,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "x2ap_eNB.h" #include "ngap_gNB.h" #include "gnb_paramdef.h" +#include #include "nfapi/oai_integration/vendor_ext.h" pthread_cond_t nfapi_sync_cond; @@ -92,11 +93,12 @@ pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex extern uint8_t nfapi_mode; // Default to monolithic mode - +THREAD_STRUCT thread_struct; 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; +msc_interface_t msc_interface; volatile int start_gNB = 0; volatile int oai_exit = 0; @@ -114,7 +116,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; //Temp fix for inexistent NR upper layer unsigned char NB_gNB_INST = 1; -static char *itti_dump_file = NULL; int UE_scan = 1; int UE_scan_carrier = 0; @@ -179,7 +180,6 @@ extern void *udp_eNB_task(void *args_p); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; static char *parallel_config = NULL; @@ -809,7 +809,7 @@ if(!IS_SOFTMODEM_NOS1) printf("RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init gNBs\n"); - if(IS_SOFTMODEM_DOFORMS) { + if(IS_SOFTMODEM_DOSCOPE) { sleep(1); scopeParms_t p; p.argc=&argc; diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index d6cfe6b906..18a6fe42d0 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -18,13 +18,9 @@ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_GNB { \ - {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ - {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ - {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ - {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 2854457eee..174d5409bd 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -88,6 +88,8 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "executables/thread-common.h" extern const char *duplex_mode[]; +msc_interface_t msc_interface; +THREAD_STRUCT thread_struct; // Thread variables pthread_cond_t nfapi_sync_cond; @@ -145,7 +147,7 @@ int chain_offset = 0; int card_offset = 0; uint64_t num_missed_slots = 0; // counter for the number of missed slots int transmission_mode = 1; -int usrp_tx_thread = 0; +int numerology = 0; int oaisim_flag = 0; int emulate_rf = 0; @@ -179,6 +181,23 @@ void print_difftimes(void) { LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); } +int create_tasks_nrue(uint32_t ue_nb) { + LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); + itti_wait_ready(1); + + if (ue_nb > 0) { + LOG_I(NR_RRC,"create TASK_RRC_NRUE \n"); + if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for RRC UE failed\n"); + return -1; + } + + } + + itti_wait_ready(0); + return 0; +} + void exit_function(const char *file, const char *function, const int line, const char *s) { int CC_id; @@ -470,7 +489,7 @@ int main( int argc, char **argv ) { configure_linux(); mlockall(MCL_CURRENT | MCL_FUTURE); - if(IS_SOFTMODEM_DOFORMS) { + if(IS_SOFTMODEM_DOSCOPE) { load_softscope("nr",PHY_vars_UE_g[0][0]); } @@ -480,6 +499,12 @@ int main( int argc, char **argv ) { // wait for end of program printf("TYPE TO TERMINATE\n"); + + if (create_tasks_nrue(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + // Sleep a while before checking all parameters have been used // Some are used directly in external threads, asynchronously sleep(20); diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c index 4ddc7870d9..326f7d277f 100644 --- a/executables/ocp-gnb.c +++ b/executables/ocp-gnb.c @@ -61,8 +61,6 @@ uint32_t do_forms=0; unsigned int mmapped_dma=0; int8_t threequarter_fs=0; -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; int chain_offset=0; uint16_t sl_ahead=6; uint16_t sf_ahead=6; @@ -70,16 +68,15 @@ uint32_t timing_advance = 0; int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; int config_sync_var=-1; pthread_mutex_t nfapi_sync_mutex; pthread_cond_t nfapi_sync_cond; int nfapi_sync_var=-1; -uint8_t nfapi_mode = NFAPI_MONOLITHIC; // Default to monolithic mode double cpuf; +THREAD_STRUCT thread_struct; pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; @@ -95,7 +92,8 @@ time_stats_t nfapi_meas; // total tx time time_stats_t softmodem_stats_rx_sf; // total rx time // not used but needed for link openair0_config_t openair0_cfg[MAX_CARDS]; - +uint16_t slot_ahead=6; +msc_interface_t msc_interface; AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; int flexran_agent_start(mid_t mod_id) { @@ -122,7 +120,6 @@ int restart_L1L2(module_id_t gnb_id) { } static int wait_for_sync = 0; -static char *itti_dump_file = NULL; static double snr_dB=20; static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; @@ -996,7 +993,7 @@ int main( int argc, char **argv ) { (void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW); } - if(IS_SOFTMODEM_DOFORMS) { + if(IS_SOFTMODEM_DOSCOPE) { scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]}; load_softscope("nr",&tmp); } diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 1077c0e1ac..fa6b674765 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -45,6 +45,8 @@ static softmodem_params_t softmodem_params; char *parallel_config=NULL; char *worker_config=NULL; +msc_interface_t msc_interface; +int usrp_tx_thread = 0; uint8_t nfapi_mode=0; @@ -86,7 +88,7 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) { void get_common_options(uint32_t execmask) { uint32_t online_log_messages=0; uint32_t glog_level=0 ; - uint32_t start_telnetsrv = 0; + uint32_t start_telnetsrv = 0, start_telnetclt = 0; uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0; uint32_t rfsim = 0, basicsim = 0, do_forms = 0; char *logmem_filename = NULL; @@ -95,21 +97,26 @@ void get_common_options(uint32_t execmask) { checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC; check_execmask(execmask); config_get( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams, - sizeof(cmdline_logparams)/sizeof(paramdef_t)); - config_get( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); - - if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { + + int numparams=sizeof(cmdline_logparams)/sizeof(paramdef_t); + config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams,numparams); + config_get( cmdline_logparams,numparams,NULL); + + if(config_isparamset(cmdline_logparams,config_paramidx_fromname(cmdline_logparams,numparams, CONFIG_FLOG_OPT))) { set_glog_onlinelog(online_log_messages); } - if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { + if(config_isparamset(cmdline_logparams,config_paramidx_fromname(cmdline_logparams,numparams, CONFIG_LOGL_OPT))) { set_glog(glog_level); } if (start_telnetsrv) { load_module_shlib("telnetsrv",NULL,0,NULL); } + + if (start_telnetclt) { + set_softmodem_optmask(SOFTMODEM_TELNETCLT_BIT); + } if (logmem_filename != NULL && strlen(logmem_filename) > 0) { log_mem_filename = &logmem_filename[0]; @@ -140,7 +147,7 @@ void get_common_options(uint32_t execmask) { } if (do_forms) { - set_softmodem_optmask(SOFTMODEM_DOFORMS_BIT); + set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT); } if(parallel_config != NULL) set_parallel_conf(parallel_config); diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 7a7be1de96..e4275a48bb 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -91,6 +91,7 @@ extern "C" #define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" +#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n" #define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -117,6 +118,7 @@ extern "C" #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; +extern int usrp_tx_thread; #define CMDLINE_PARAMS_DESC { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ {"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\ @@ -144,6 +146,7 @@ extern "C" {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ {"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \ + {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \ } @@ -153,23 +156,22 @@ extern "C" #define CONFIG_HLP_LOGV "Set the global log verbosity \n" #define CONFIG_HLP_TELN "Start embedded telnet server \n" #define CONFIG_HLP_MSC "Enable the MSC tracing utility \n" -/*----------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters for LOG utility */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*----------------------------------------------------------------------------------------------------------------------------*/ +#define CONFIG_FLOG_OPT "R" +#define CONFIG_LOGL_OPT "g" +/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters for LOG utility */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ #define START_MSC softmodem_params.start_msc #define CMDLINE_LOGPARAMS_DESC { \ - {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ - {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ - {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ - {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ - {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \ + {CONFIG_FLOG_OPT , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ + {CONFIG_LOGL_OPT , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ + {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ + {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ + {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \ + {"telnetclt", NULL, 0, uptr:&start_telnetclt, defstrval:NULL, TYPE_UINT, 0}, \ } -#define CMDLINE_ONLINELOG_IDX 0 -#define CMDLINE_GLOGLEVEL_IDX 1 -#define CMDLINE_GLOGVERBO_IDX 2 -#define CMDLINE_STARTTELN_IDX 3 /* check function for global log level */ #define CMDLINE_LOGPARAMS_CHECK_DESC { \ @@ -178,6 +180,7 @@ extern "C" { .s5= {NULL} } , \ { .s5= {NULL} } , \ { .s5= {NULL} } , \ + { .s5= {NULL} } , \ } /***************************************************************************************************************************************/ @@ -188,8 +191,9 @@ extern "C" #define SOFTMODEM_RFSIM_BIT (1<<10) #define SOFTMODEM_BASICSIM_BIT (1<<11) #define SOFTMODEM_SIML1_BIT (1<<12) -#define SOFTMODEM_DOFORMS_BIT (1<<15) +#define SOFTMODEM_DOSCOPE_BIT (1<<15) #define SOFTMODEM_RECPLAY_BIT (1<<16) +#define SOFTMODEM_TELNETCLT_BIT (1<<17) #define SOFTMODEM_ENB_BIT (1<<20) #define SOFTMODEM_GNB_BIT (1<<21) #define SOFTMODEM_4GUE_BIT (1<<22) @@ -204,8 +208,9 @@ extern "C" #define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) #define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT) #define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) -#define IS_SOFTMODEM_DOFORMS ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT) +#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT) #define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT) +#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT) #define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT) #define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT) #define IS_SOFTMODEM_4GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT) diff --git a/executables/thread-common.h b/executables/thread-common.h index 6f3af3cfc0..0aaeb3c30e 100644 --- a/executables/thread-common.h +++ b/executables/thread-common.h @@ -3,7 +3,7 @@ #include "PHY/defs_common.h" -THREAD_STRUCT thread_struct; +extern THREAD_STRUCT thread_struct; static inline void set_parallel_conf(char *parallel_conf) { mapping config[]= { diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 4ca02ed929..5ce66aad89 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -73,7 +73,6 @@ extern pthread_mutex_t nfapi_sync_mutex; extern int nfapi_sync_var; extern int sync_var; -char uecap_xer_in; extern void init_eNB_afterRU(void); extern void init_UE_stub(int nb_inst,int,int); @@ -2199,7 +2198,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add pnf.phys[0].udp.tx_port = vnf_p7_port; strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); strcpy(pnf.phys[0].local_addr, pnf_ip_addr); - printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n", + printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n", __FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port, pnf.phys[0].local_addr, pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port, @@ -2250,7 +2249,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, pnf.phys[0].udp.tx_port = vnf_p7_port; strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); strcpy(pnf.phys[0].local_addr, pnf_ip_addr); - printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n", + printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n", __FUNCTION__, config->vnf_ip_addr, config->vnf_p5_port, pnf.phys[0].local_addr, diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index b3ab7cbdbc..61d4847eba 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -21,6 +21,7 @@ #if !defined(NFAPI_PNF_H__) #define NFAPI_PNF_H__ +extern nfapi_ue_release_request_body_t release_rntis; int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); diff --git a/nfapi/open-nFAPI/common/src/debug.c b/nfapi/open-nFAPI/common/src/debug.c index a45d41d7d7..f53be43223 100644 --- a/nfapi/open-nFAPI/common/src/debug.c +++ b/nfapi/open-nFAPI/common/src/debug.c @@ -1,76 +1,76 @@ -/* - * Copyright 2017 Cisco Systems, Inc. - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAX_MSG_LENGTH 2096 -#define TRACE_HEADER_LENGTH 44 - -void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...); - -// initialize the trace function to 0 -void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg; - -nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO; -//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN; - -void nfapi_set_trace_level(nfapi_trace_level_t new_level) -{ - nfapi_trace_level_g = new_level; -} - -void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...) -{ - char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH]; - uint32_t num_chars; - va_list p_args; - struct timeval tv; - pthread_t tid = pthread_self(); - - (void)gettimeofday(&tv, NULL); - - num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid); - - if (num_chars > TRACE_HEADER_LENGTH) - { - printf("trace_dbg: Error, num_chars is too large: %d", num_chars); - return; - } - - va_start(p_args, format); - if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args))) - { - if (level <= NFAPI_TRACE_WARN) - { - printf("%s", trace_buff); - } - printf("%s", trace_buff); - } - va_end(p_args); -} +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_MSG_LENGTH 2096 +#define TRACE_HEADER_LENGTH 44 + +void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...); + +// initialize the trace function to 0 +void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg; + +nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO; +//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN; + +void nfapi_set_trace_level(nfapi_trace_level_t new_level) +{ + nfapi_trace_level_g = new_level; +} + +void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...) +{ + char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH]; + uint32_t num_chars; + va_list p_args; + struct timeval tv; + pthread_t tid = pthread_self(); + + (void)gettimeofday(&tv, NULL); + + num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid); + + if (num_chars > TRACE_HEADER_LENGTH) + { + printf("trace_dbg: Error, num_chars is too large: %u", num_chars); + return; + } + + va_start(p_args, format); + if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args))) + { + if (level <= NFAPI_TRACE_WARN) + { + printf("%s", trace_buff); + } + printf("%s", trace_buff); + } + va_end(p_args); +} diff --git a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp index 1c2f0bef80..4fe5065cea 100644 --- a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp +++ b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp @@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) { if(instance->tick == 1000) { if(instance->tx_byte_count > 0) { - printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count); + printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count); instance->tx_byte_count = 0; } @@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) { millisec = now_ts.tv_nsec / 1e6; if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) { - printf("*** missing millisec %d %d\n", last_millisec, millisec); + printf("*** missing millisec %u %u\n", last_millisec, millisec); catchup = millisec - last_millisec - 1; } diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c index 2a7b789650..fffd04ea3c 100644 --- a/openair1/PHY/CODING/3gpplte_sse.c +++ b/openair1/PHY/CODING/3gpplte_sse.c @@ -44,8 +44,6 @@ //#define DEBUG_TURBO_ENCODER 1 //#define CALLGRIND 1 -unsigned short threegpplte_interleaver_output; -unsigned long long threegpplte_interleaver_tmp; #if defined(__x86_64__) || defined(__i386__) struct treillis { diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index e1ca906b55..bc1c0dac56 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -798,11 +798,11 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, n is the size in bits of the coded block, with the tail */ int n2; llr_t y8[3*(n+16)] __attribute__((aligned(16))); - llr_t systematic0[n+16] __attribute__ ((aligned(16))); - llr_t systematic1[n+16] __attribute__ ((aligned(16))); - llr_t systematic2[n+16] __attribute__ ((aligned(16))); - llr_t yparity1[n+16] __attribute__ ((aligned(16))); - llr_t yparity2[n+16] __attribute__ ((aligned(16))); + llr_t systematic0[n+32] __attribute__ ((aligned(16))); + llr_t systematic1[n+32] __attribute__ ((aligned(16))); + llr_t systematic2[n+32] __attribute__ ((aligned(16))); + llr_t yparity1[n+32] __attribute__ ((aligned(16))); + llr_t yparity2[n+32] __attribute__ ((aligned(16))); llr_t ext[n+128] __attribute__((aligned(16))); llr_t ext2[n+128] __attribute__((aligned(16))); llr_t alpha[(n+16)*8] __attribute__ ((aligned(16))); @@ -811,7 +811,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, llr_t m10[n+16] __attribute__ ((aligned(16))); // int *pi2_p,*pi4_p,*pi5_p,*pi6_p; int *pi4_p,*pi5_p,*pi6_p; - llr_t *s,*s1,*s2,*yp1,*yp2,*yp; + llr_t *s1,*s2,*yp1,*yp2,*yp; unsigned int i,j,iind;//,pi; unsigned char iteration_cnt=0; unsigned int crc,oldcrc,crc_len; @@ -927,7 +927,6 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, yp128 = (int8x16_t *)y8; #endif - s = systematic0; s1 = systematic1; s2 = systematic2; yp1 = yparity1; @@ -938,7 +937,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, for (i=0; i<16 ; i++ ) for (j=0; jn) { /* - s[n]=0;s[n+1]=0;s[n+2]=0;s[n+3]=0; - s[n+4]=0;s[n+5]=0;s[n+6]=0;s[n+7]=0; + systematic0[n]=0;systematic0[n+1]=0;systematic0[n+2]=0;systematic0[n+3]=0; + systematic0[n+4]=0;s[n+5]=0;s[n+6]=0;s[n+7]=0; s1[n]=0;s1[n+1]=0;s1[n+2]=0;s1[n+3]=0; s1[n+4]=0;s1[n+5]=0;s1[n+6]=0;s1[n+7]=0; s2[n]=0;s2[n+1]=0;s2[n+2]=0;s2[n+3]=0; @@ -961,26 +960,26 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, // Termination for (i=n2; i 1280, 2401 -> 2560\n"); printf("block length %d: \n", block_length); @@ -704,25 +702,25 @@ int main(int argc, char *argv[]) printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std); printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max); printf("\n"); - printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz); - printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2))); - printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/cpu_freq_GHz); + printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz()); + printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2))); + printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/get_cpu_freq_GHz()); printf("\n"); - printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz); - printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2))); - printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/cpu_freq_GHz); + printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz()); + printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2))); + printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/get_cpu_freq_GHz()); fprintf(fd,"%f %f %f %f %f %f %f %f %f %f %f %f %d \n", SNR, (double)decoded_errors[i]/(double)n_trials , (double)errors_bit/(double)n_trials/(double)block_length/(double)n_segments , errors_bit_uncoded/(double)n_trials/(double)n_segments , - (double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz, - sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)), - (double)time_optim->max/1000.0/cpu_freq_GHz, - (double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz, - sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)), - (double)time_decoder->max/1000.0/cpu_freq_GHz, + (double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(), + sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)), + (double)time_optim->max/1000.0/get_cpu_freq_GHz(), + (double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(), + sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)), + (double)time_decoder->max/1000.0/get_cpu_freq_GHz(), dec_iter->n_iter_mean, dec_iter->n_iter_std, dec_iter->n_iter_max diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index d9adf3e24f..e43ba507ab 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -113,7 +113,6 @@ int main(int argc, char *argv[]) //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) time_stats_t timeEncoder,timeDecoder; opp_enabled=1; - cpu_freq_GHz = get_cpu_freq_GHz(); reset_meas(&timeEncoder); reset_meas(&timeDecoder); randominit(0); @@ -324,9 +323,9 @@ if (logFlag){ #endif //Iteration times are in microseconds. - timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0)); - timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0)); - if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0))); + timeEncoderCumulative+=(timeEncoder.diff/(get_cpu_freq_GHz()*1000.0)); + timeDecoderCumulative+=(timeDecoder.diff/(get_cpu_freq_GHz()*1000.0)); + if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(get_cpu_freq_GHz()*1000.0)), (timeDecoder.diff/(get_cpu_freq_GHz()*1000.0))); if (nBitError<0) { blockErrorCumulative++; @@ -348,7 +347,7 @@ if (logFlag){ printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n", decoderListSize, SNR, ((double)blockErrorCumulative/iterations), ((double)bitErrorCumulative / (iterations*testLength)), - (double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0)); + (double)timeEncoder.diff/timeEncoder.trials/(get_cpu_freq_GHz()*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(get_cpu_freq_GHz()*1000.0)); //(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations); if (blockErrorCumulative==0 && bitErrorCumulative==0) break; diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c index 02d5dc64e0..f750d24977 100644 --- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c +++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c @@ -13,7 +13,6 @@ int main(int argc, char *argv[]) { time_stats_t timeEncoder,timeDecoder; opp_enabled=1; - cpu_freq_GHz = get_cpu_freq_GHz(); reset_meas(&timeEncoder); reset_meas(&timeDecoder); randominit(0); @@ -141,8 +140,8 @@ int main(int argc, char *argv[]) SNR, ((double)bitErrorCumulative / (iterations*messageLength)), ((double)blockErrorCumulative/iterations), - ((double)timeEncoder.diff/timeEncoder.trials)/(cpu_freq_GHz), - ((double)timeDecoder.diff/timeDecoder.trials)/(cpu_freq_GHz*1000.0)); + ((double)timeEncoder.diff/timeEncoder.trials)/(get_cpu_freq_GHz()), + ((double)timeDecoder.diff/timeDecoder.trials)/(get_cpu_freq_GHz()*1000.0)); blockErrorCumulative=0; bitErrorCumulative=0; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c index 785b588b9f..3226c97f87 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c @@ -39,7 +39,7 @@ #include "nrLDPC_bnProc.h" #define NR_LDPC_ENABLE_PARITY_CHECK -#define NR_LDPC_PROFILER_DETAIL +//#define NR_LDPC_PROFILER_DETAIL #ifdef NR_LDPC_DEBUG_MODE #include "nrLDPC_tools/nrLDPC_debug.h" diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index 0d765a18b3..655878cfaa 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -37,266 +37,82 @@ // Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs) #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" -int* sync_corr_ue0 = NULL; -int* sync_corr_ue1 = NULL; -int* sync_corr_ue2 = NULL; -int sync_tmp[2048*4] __attribute__((aligned(32))); -short syncF_tmp[2048*2] __attribute__((aligned(32))); +static struct complex16 *primary_synch0_time __attribute__((aligned(32))); +static struct complex16 *primary_synch1_time __attribute__((aligned(32))); +static struct complex16 *primary_synch2_time __attribute__((aligned(32))); +static void doIdft(int size, short *in, short *out) { + switch (size) { + case 6: + idft(IDFT_128,in,out,1); + break; -int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *common_vars -{ - int i,k; + case 25: + idft(IDFT_512,in,out,1); + break; - sync_corr_ue0 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti); - sync_corr_ue1 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti); - sync_corr_ue2 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti); + case 50: + idft(IDFT_1024,in,out,1); + break; + + case 75: + idft(IDFT_1536,in,out,1); + break; - if (sync_corr_ue0) { -#ifdef DEBUG_PHY - LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue0); -#endif - //common_vars->sync_corr = sync_corr; - } else { - LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue0 not allocated\n"); - return(-1); + case 100: + idft(IDFT_2048,in,out,1); + break; + + default: + LOG_E(PHY,"Unsupported N_RB_DL %d\n",size); + abort(); + break; + } } - if (sync_corr_ue1) { -#ifdef DEBUG_PHY - LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue1); -#endif - //common_vars->sync_corr = sync_corr; - } else { - LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue1 not allocated\n"); - return(-1); +static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSize) { + int k=ofdmSize-36; + + for (int i=0; i<72; i++) { + out[k].r = in[i].r>>1; //we need to shift input to avoid overflow in fft + out[k].i = in[i].i>>1; + k++; + + if (k >= ofdmSize) { + k++; // skip DC carrier + k-=ofdmSize; + } + } } - if (sync_corr_ue2) { -#ifdef DEBUG_PHY - LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue2); -#endif - //common_vars->sync_corr = sync_corr; - } else { - LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue2 not allocated\n"); - return(-1); - } - - // primary_synch0_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int)); - primary_synch0_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2); - - if (primary_synch0_time) { - // bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int)); - bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2); -#ifdef DEBUG_PHY - LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time allocated at %p\n", primary_synch0_time); -#endif - } else { - LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time not allocated\n"); - return(-1); - } - - // primary_synch1_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int)); - primary_synch1_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2); - - if (primary_synch1_time) { - // bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int)); - bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2); -#ifdef DEBUG_PHY - LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time allocated at %p\n", primary_synch1_time); -#endif - } else { - LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time not allocated\n"); - return(-1); - } - - // primary_synch2_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int)); - primary_synch2_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2); - - if (primary_synch2_time) { - // bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int)); - bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2); -#ifdef DEBUG_PHY - LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time allocated at %p\n", primary_synch2_time); -#endif - } else { - LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time not allocated\n"); - return(-1); - } - - +int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) { // LTE_UE_COMMON *common_vars + struct complex16 syncF_tmp[2048]__attribute__((aligned(32)))= {0}; + int sz=frame_parms->ofdm_symbol_size*sizeof(*primary_synch0_time); + AssertFatal( NULL != (primary_synch0_time = (struct complex16 *)malloc16(sz)),""); + bzero(primary_synch0_time,sz); + AssertFatal( NULL != (primary_synch1_time = (struct complex16 *)malloc16(sz)),""); + bzero(primary_synch1_time,sz); + AssertFatal( NULL != (primary_synch2_time = (struct complex16 *)malloc16(sz)),""); + bzero(primary_synch2_time,sz); // generate oversampled sync_time sequences - k=frame_parms->ofdm_symbol_size-36; - - for (i=0; i<72; i++) { - syncF_tmp[2*k] = primary_synch0[2*i]>>2; //we need to shift input to avoid overflow in fft - syncF_tmp[2*k+1] = primary_synch0[2*i+1]>>2; - k++; - - if (k >= frame_parms->ofdm_symbol_size) { - k++; // skip DC carrier - k-=frame_parms->ofdm_symbol_size; - } - } - - switch (frame_parms->N_RB_DL) { - case 6: - idft(IDFT_128,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 25: - idft(IDFT_512,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 50: - idft(IDFT_1024,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - - case 75: - idft(IDFT_1536,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, - 1); /// complex output - break; - case 100: - idft(IDFT_2048,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - default: - LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL); - break; - } - - for (i=0; iofdm_symbol_size; i++) - ((int32_t*)primary_synch0_time)[i] = sync_tmp[i]; - - k=frame_parms->ofdm_symbol_size-36; - - for (i=0; i<72; i++) { - syncF_tmp[2*k] = primary_synch1[2*i]>>2; //we need to shift input to avoid overflow in fft - syncF_tmp[2*k+1] = primary_synch1[2*i+1]>>2; - k++; - - if (k >= frame_parms->ofdm_symbol_size) { - k++; // skip DC carrier - k-=frame_parms->ofdm_symbol_size; - } - } - - switch (frame_parms->N_RB_DL) { - case 6: - idft(IDFT_128,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 25: - idft(IDFT_512,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 50: - idft(IDFT_1024,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - - case 75: - idft(IDFT_1536,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 100: - idft(IDFT_2048,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - default: - LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL); - break; - } - - for (i=0; iofdm_symbol_size; i++) - ((int32_t*)primary_synch1_time)[i] = sync_tmp[i]; - - k=frame_parms->ofdm_symbol_size-36; - - for (i=0; i<72; i++) { - syncF_tmp[2*k] = primary_synch2[2*i]>>2; //we need to shift input to avoid overflow in fft - syncF_tmp[2*k+1] = primary_synch2[2*i+1]>>2; - k++; - - if (k >= frame_parms->ofdm_symbol_size) { - k++; // skip DC carrier - k-=frame_parms->ofdm_symbol_size; - } - } - - switch (frame_parms->N_RB_DL) { - case 6: - idft(IDFT_128,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 25: - idft(IDFT_512,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 50: - idft(IDFT_1024,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - - case 75: - idft(IDFT_1536,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - case 100: - idft(IDFT_2048,(short*)syncF_tmp, /// complex input - (short*)sync_tmp, /// complex output - 1); - break; - default: - LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL); - break; - } - - for (i=0; iofdm_symbol_size; i++) - ((int32_t*)primary_synch2_time)[i] = sync_tmp[i]; - + copyPrimary( syncF_tmp, (struct complex16 *) primary_synch0, frame_parms->ofdm_symbol_size); + doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch0_time); + copyPrimary( syncF_tmp, (struct complex16 *) primary_synch1, frame_parms->ofdm_symbol_size); + doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch1_time); + copyPrimary( syncF_tmp, (struct complex16 *) primary_synch2, frame_parms->ofdm_symbol_size); + doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch2_time); if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){ LOG_M("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1); LOG_M("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1); LOG_M("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1); } + return (1); } -void lte_sync_time_free(void) -{ - if (sync_corr_ue0) { - LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue0); - free(sync_corr_ue0); - } - - if (sync_corr_ue1) { - LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue1); - free(sync_corr_ue1); - } - - if (sync_corr_ue2) { - LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue2); - free(sync_corr_ue2); - } - +void lte_sync_time_free(void) { if (primary_synch0_time) { LOG_D(PHY,"Freeing primary_sync0_time ...\n"); free(primary_synch0_time); @@ -312,126 +128,81 @@ void lte_sync_time_free(void) free(primary_synch2_time); } - sync_corr_ue0 = NULL; - sync_corr_ue1 = NULL; - sync_corr_ue2 = NULL; primary_synch0_time = NULL; primary_synch1_time = NULL; primary_synch2_time = NULL; } -static inline int abs32(int x) -{ +static inline int abs32(int x) { return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1])); } +static inline double absF(struct complexd x) { + return x.r*x.r+x.i*x.i; +} + +#define complexNull(c) bzero((void*) &(c), sizeof(c)) #define SHIFT 17 int lte_sync_time(int **rxdata, ///rx data in time domain LTE_DL_FRAME_PARMS *frame_parms, - int *eNB_id) -{ + int *eNB_id) { // perform a time domain correlation using the oversampled sync sequence - unsigned int n, ar, s, peak_pos, peak_val, sync_source; int result,result2; - int sync_out[3] = {0,0,0},sync_out2[3] = {0,0,0}; - int tmp[3] = {0,0,0}; + struct complexd sync_out[3]= {0}, sync_out2[3]= {0}; int length = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti>>1; - - //LOG_D(PHY,"[SYNC TIME] Calling sync_time.\n"); - AssertFatal(sync_corr_ue0 != NULL, - "sync_corr_ue0 not yet allocated! Exiting.\n"); - AssertFatal(sync_corr_ue1 != NULL, - "sync_corr_ue0 not yet allocated! Exiting.\n"); - AssertFatal(sync_corr_ue2 != NULL, - "sync_corr_ue0 not yet allocated! Exiting.\n"); - peak_val = 0; peak_pos = 0; sync_source = 0; - for (n=0; nofdm_symbol_size-frame_parms->nb_prefix_samples)) { if (n<(length-frame_parms->ofdm_symbol_size)) { - //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; for (ar=0; arnb_antennas_rx; ar++) { - - result = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); - result2 = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT); - - ((short*)sync_corr_ue0)[2*n] += ((short*) &result)[0]; - ((short*)sync_corr_ue0)[2*n+1] += ((short*) &result)[1]; - ((short*)sync_corr_ue0)[2*(length+n)] += ((short*) &result2)[0]; - ((short*)sync_corr_ue0)[(2*(length+n))+1] += ((short*) &result2)[1]; - ((short*)sync_out)[0] += ((short*) &result)[0]; - ((short*)sync_out)[1] += ((short*) &result)[1]; - ((short*)sync_out2)[0] += ((short*) &result2)[0]; - ((short*)sync_out2)[1] += ((short*) &result2)[1]; + result = dot_product((short *)primary_synch0_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); + result2 = dot_product((short *)primary_synch0_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT); + sync_out[0].r += ((short *) &result)[0]; + sync_out[0].i += ((short *) &result)[1]; + sync_out2[0].r += ((short *) &result2)[0]; + sync_out2[0].i += ((short *) &result2)[1]; } for (ar=0; arnb_antennas_rx; ar++) { - result = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); - result2 = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT); - ((short*)sync_corr_ue1)[2*n] += ((short*) &result)[0]; - ((short*)sync_corr_ue1)[2*n+1] += ((short*) &result)[1]; - ((short*)sync_corr_ue1)[2*(length+n)] += ((short*) &result2)[0]; - ((short*)sync_corr_ue1)[(2*(length+n))+1] += ((short*) &result2)[1]; - - ((short*)sync_out)[2] += ((short*) &result)[0]; - ((short*)sync_out)[3] += ((short*) &result)[1]; - ((short*)sync_out2)[2] += ((short*) &result2)[0]; - ((short*)sync_out2)[3] += ((short*) &result2)[1]; + result = dot_product((short *)primary_synch1_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); + result2 = dot_product((short *)primary_synch1_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT); + sync_out[1].r += ((short *) &result)[0]; + sync_out[1].i += ((short *) &result)[1]; + sync_out2[1].r += ((short *) &result2)[0]; + sync_out2[1].i += ((short *) &result2)[1]; } for (ar=0; arnb_antennas_rx; ar++) { - - result = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); - result2 = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT); - ((short*)sync_corr_ue2)[2*n] += ((short*) &result)[0]; - ((short*)sync_corr_ue2)[2*n+1] += ((short*) &result)[1]; - ((short*)sync_corr_ue2)[2*(length+n)] += ((short*) &result2)[0]; - ((short*)sync_corr_ue2)[(2*(length+n))+1] += ((short*) &result2)[1]; - ((short*)sync_out)[4] += ((short*) &result)[0]; - ((short*)sync_out)[5] += ((short*) &result)[1]; - ((short*)sync_out2)[4] += ((short*) &result2)[0]; - ((short*)sync_out2)[5] += ((short*) &result2)[1]; + result = dot_product((short *)primary_synch2_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); + result2 = dot_product((short *)primary_synch2_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT); + sync_out[2].r += ((short *) &result)[0]; + sync_out[2].i += ((short *) &result)[1]; + sync_out2[2].r += ((short *) &result2)[0]; + sync_out2[2].i += ((short *) &result2)[1]; } - } // calculate the absolute value of sync_corr[n] - sync_corr_ue0[n] = abs32(sync_corr_ue0[n]); - sync_corr_ue0[n+length] = abs32(sync_corr_ue0[n+length]); - sync_corr_ue1[n] = abs32(sync_corr_ue1[n]); - sync_corr_ue1[n+length] = abs32(sync_corr_ue1[n+length]); - sync_corr_ue2[n] = abs32(sync_corr_ue2[n]); - sync_corr_ue2[n+length] = abs32(sync_corr_ue2[n+length]); - for (s=0; s<3; s++) { - tmp[s] = (abs32(sync_out[s])>>1) + (abs32(sync_out2[s])>>1); + double tmp = absF(sync_out[s]) + absF(sync_out2[s]); - if (tmp[s]>peak_val) { - peak_val = tmp[s]; + if (tmp>peak_val) { + peak_val = tmp; peak_pos = n; sync_source = s; /* @@ -443,42 +214,22 @@ int lte_sync_time(int **rxdata, ///rx data in time domain } *eNB_id = sync_source; - - LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2); - - - if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){ - static int debug_cnt; - if (debug_cnt == 0) { - LOG_M("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2); - LOG_M("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2); - LOG_M("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2); - LOG_M("rxdata0.m","rxd0",rxdata[0],length<<1,1,1); - // exit(-1); - } else { - debug_cnt++; - } -} + LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val/2,dB_fixed(peak_val/2)/2); return(peak_pos); } -int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars -{ +int ru_sync_time_init(RU_t *ru) { // LTE_UE_COMMON *common_vars /* int16_t dmrs[2048]; int16_t *dmrsp[2] = {dmrs,NULL}; */ - int32_t dmrs[ru->frame_parms->ofdm_symbol_size*14] __attribute__((aligned(32))); //int32_t *dmrsp[2] = {&dmrs[(3-ru->frame_parms->Ncp)*ru->frame_parms->ofdm_symbol_size],NULL}; int32_t *dmrsp[2] = {&dmrs[0],NULL}; - generate_ul_ref_sigs(); - - ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t)); - ru->dmrs_corr = (uint64_t*)malloc16_clear(ru->frame_parms->samples_per_tti*10*sizeof(uint64_t)); - + ru->dmrssync = (int16_t *)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t)); + ru->dmrs_corr = (uint64_t *)malloc16_clear(ru->frame_parms->samples_per_tti*10*sizeof(uint64_t)); generate_drs_pusch(NULL, NULL, ru->frame_parms, @@ -491,35 +242,39 @@ int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars 0); switch (ru->frame_parms->N_RB_DL) { - case 6: - idft(IDFT_128,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), - ru->dmrssync, /// complex output - 1); - break; - case 25: - idft(IDFT_512,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), - ru->dmrssync, /// complex output - 1); - break; - case 50: - idft(IDFT_1024,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), - ru->dmrssync, /// complex output - 1); - break; - - case 75: - idft(IDFT_1536,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), - ru->dmrssync, - 1); /// complex output - break; - case 100: - idft(IDFT_2048,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), - ru->dmrssync, /// complex output - 1); - break; - default: - AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms->N_RB_DL); - break; + case 6: + idft(IDFT_128,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), + ru->dmrssync, /// complex output + 1); + break; + + case 25: + idft(IDFT_512,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), + ru->dmrssync, /// complex output + 1); + break; + + case 50: + idft(IDFT_1024,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), + ru->dmrssync, /// complex output + 1); + break; + + case 75: + idft(IDFT_1536,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), + ru->dmrssync, + 1); /// complex output + break; + + case 100: + idft(IDFT_2048,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]), + ru->dmrssync, /// complex output + 1); + break; + + default: + AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms->N_RB_DL); + break; } return(0); @@ -527,10 +282,11 @@ int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars void ru_sync_time_free(RU_t *ru) { - AssertFatal(ru->dmrssync!=NULL,"ru->dmrssync is NULL\n"); free(ru->dmrssync); - if (ru->dmrs_corr) free(ru->dmrs_corr); + + if (ru->dmrs_corr) + free(ru->dmrs_corr); } //#define DEBUG_PHY @@ -539,10 +295,8 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain LTE_DL_FRAME_PARMS *frame_parms, uint32_t length, uint32_t *peak_val_out, - uint32_t *sync_corr_eNB) -{ + uint32_t *sync_corr_eNB) { // perform a time domain correlation using the oversampled sync sequence - unsigned int n, ar, peak_val, peak_pos; uint64_t mean_val; int result; @@ -556,21 +310,21 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } switch (eNB_id) { - case 0: - primary_synch_time = (short*)primary_synch0_time; - break; + case 0: + primary_synch_time = (short *)primary_synch0_time; + break; - case 1: - primary_synch_time = (short*)primary_synch1_time; - break; + case 1: + primary_synch_time = (short *)primary_synch1_time; + break; - case 2: - primary_synch_time = (short*)primary_synch2_time; - break; + case 2: + primary_synch_time = (short *)primary_synch2_time; + break; - default: - LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n"); - return (-1); + default: + LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n"); + return (-1); } peak_val = 0; @@ -578,21 +332,16 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain mean_val = 0; for (n=0; nofdm_symbol_size-frame_parms->nb_prefix_samples)) { - //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; for (ar=0; arnb_antennas_rx; ar++) { - - result = dot_product((short*)primary_synch_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); + result = dot_product((short *)primary_synch_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); //((short*)sync_corr)[2*n] += ((short*) &result)[0]; //((short*)sync_corr)[2*n+1] += ((short*) &result)[1]; sync_corr_eNB[n] += abs32(result); - } - } /* @@ -610,7 +359,6 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } mean_val/=length; - *peak_val_out = peak_val; if (peak_val <= (40*(uint32_t)mean_val)) { @@ -620,88 +368,91 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain LOG_I(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val); return(peak_pos); } - } -static inline int64_t abs64(int64_t x) -{ - return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t) -((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1])); +static inline int64_t abs64(int64_t x) { + return (((int64_t)((int32_t *)&x)[0])*((int64_t)((int32_t *)&x)[0]) + ((int64_t) + ((int32_t *)&x)[1])*((int64_t)((int32_t *)&x)[1])); } int ru_sync_time(RU_t *ru, int64_t *lev, - int64_t *avg) -{ + int64_t *avg) { LTE_DL_FRAME_PARMS *frame_parms = ru->frame_parms; RU_CALIBRATION *calibration = &ru->calibration; - // perform a time domain correlation using the oversampled sync sequence - int length = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; - // circular copy of beginning to end of rxdata buffer. Note: buffer should be big enough upon calling this function - for (int ar=0;arnb_rx;ar++) memcpy((void*)&ru->common.rxdata[ar][2*length], - (void*)&ru->common.rxdata[ar][0], - frame_parms->ofdm_symbol_size); - + for (int ar=0; arnb_rx; ar++) + memcpy((void *)&ru->common.rxdata[ar][2*length], + (void *)&ru->common.rxdata[ar][0], + frame_parms->ofdm_symbol_size); + int32_t maxlev0=0; int maxpos0=0; int64_t avg0=0; int64_t result; int64_t dmrs_corr; - int maxval=0; - for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) { + + for (int i=0; i<2*(frame_parms->ofdm_symbol_size); i++) { maxval = max(maxval,ru->dmrssync[i]); maxval = max(maxval,-ru->dmrssync[i]); } if (ru->state == RU_CHECK_SYNC) { - for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) { - maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]); - maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]); - } + for (int i=0; i<2*(frame_parms->ofdm_symbol_size); i++) { + maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]); + maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]); + } } int shift = log2_approx(maxval); for (int n=0; nnb_rx; ar++) { - result = dot_product64(ru->dmrssync, - (int16_t*) &ru->common.rxdata[ar][n], - frame_parms->ofdm_symbol_size, - shift); - - if (ru->state == RU_CHECK_SYNC) { - result = dot_product64((int16_t*) &calibration->drs_ch_estimates_time[ar], - (int16_t*) &ru->common.rxdata[ar][n], + (int16_t *) &ru->common.rxdata[ar][n], frame_parms->ofdm_symbol_size, shift); + + if (ru->state == RU_CHECK_SYNC) { + result = dot_product64((int16_t *) &calibration->drs_ch_estimates_time[ar], + (int16_t *) &ru->common.rxdata[ar][n], + frame_parms->ofdm_symbol_size, + shift); } + dmrs_corr += abs64(result); } - if (ru->dmrs_corr != NULL) ru->dmrs_corr[n] = dmrs_corr; + + if (ru->dmrs_corr != NULL) + ru->dmrs_corr[n] = dmrs_corr; // tmpi holds ++...+ + if (dmrs_corr>maxlev0) { + maxlev0 = dmrs_corr; + maxpos0 = n; + } - if (dmrs_corr>maxlev0) { maxlev0 = dmrs_corr; maxpos0 = n; } avg0 += dmrs_corr; } - avg0/=(length/4); + avg0/=(length/4); int dmrsoffset = frame_parms->samples_per_tti + (3*frame_parms->ofdm_symbol_size)+(3*frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0; - - if ((int64_t)maxlev0 > (10*avg0)) {*lev = maxlev0; *avg=avg0; return((length+maxpos0-dmrsoffset)%length);} + + if ((int64_t)maxlev0 > (10*avg0)) { + *lev = maxlev0; + *avg=avg0; + return((length+maxpos0-dmrsoffset)%length); + } return(-1); } diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c index c5e48d8364..596760541b 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold.c @@ -56,7 +56,7 @@ void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14] (((1+(Nid_cell<<1))*(1 + (((frame_parms->Ncp==0)?4:3)*l) + (7*(1+ns))))<<10); //cinit //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit //n = 0 - x1 = 1+ (1<<31); + x1 = 1+ (1U<<31); x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); // skip first 50 double words (1600 bits) @@ -103,7 +103,7 @@ void lte_gold_ue_spec(uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_ //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit //n = 0 // printf("cinit (ns %d, l %d) => %d\n",ns,l,x2); - x1 = 1+ (1<<31); + x1 = 1+ (1U<<31); x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); // skip first 50 double words (1600 bits) @@ -143,7 +143,7 @@ void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_ //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit //n = 0 //printf("cinit (ns %d, l %d) => %d\n",ns,l,x2); - x1 = 1+ (1<<31); + x1 = 1+ (1U<<31); x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); //skip first 50 double words (1600 bits) diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c index b057f6a403..78f0fd93fe 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c @@ -59,7 +59,7 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl //n = 0 // printf("cinit (sfn %d, l %d) => %d\n",sfn,l,x2); // Initializing the Sequence - x1 = 1+ (1<<31); + x1 = 1+ (1U<<31); x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); // skip first 50 double words (1600 bits) // printf("n=0 : x1 %x, x2 %x\n",x1,x2); @@ -90,7 +90,7 @@ void lte_gold_mbsfn_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold for (sfn=0; sfn<10; sfn++) { x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + (7*(1+sfn))))<<9); //cinit - x1 = 1+ (1<<31); + x1 = 1+ (1U<<31); x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); for (n=1; n<50; n++) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index d48164e07d..b03f59fb78 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -121,7 +121,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, for (n=0; n<(1+(G>>5)); n++) { #ifdef DEBUG_SCRAMBLING - for (int k=0; k<32; k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1)); + for (int k=0; k<32; k++) printf("scrambling %d : %x xor %x = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1)); #endif e[0] = (e[0]) ^ (s&1); diff --git a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c index b249052cbf..a23f8db4f2 100644 --- a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c +++ b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c @@ -41,7 +41,7 @@ extern inline uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t res { // Init value for x1: x1(0) = 1, x1(n) = 0, n=1,2,...,30 // x1(31) = [x1(3) + x1(0)]mod2 = 1 - *x1 = 1 + (1<<31); + *x1 = 1 + (1U<<31); // Init value for x2: cinit = sum_{i=0}^30 x2*2^i // x2(31) = [x2(3) + x2(2) + x2(1) + x2(0)]mod2 // = (*x2>>3) ^ (*x2>>2) + (*x2>>1) + *x2 diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 92fe777201..476d7028b1 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -374,7 +374,7 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, int n; if (reset) { - *x1 = 1+ (1<<31); + *x1 = 1+ (1U<<31); *x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31); // skip first 50 double words (1600 bits) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c index e6960273c7..9c0edb467c 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c @@ -170,6 +170,7 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms, Msc_RS = msrsb * 6; k0 = ( ( (int16_t)(frame_parms->N_RB_UL>>1) - (int16_t)(msrs0>>1) ) * 12 ) + kTC; + AssertFatal(msrsb,"divide by 0"); nb = (4*n_RRC/msrsb)%Nb; for (b=0; b<=Bsrs; b++) { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 967868f803..625519b953 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -61,6 +61,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, debug_ch_est = fopen("debug_ch_est.txt","w"); #endif + //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; + uint8_t nushift; int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; @@ -128,7 +130,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// if (pusch_pdu->transform_precoding == transform_precoder_disabled) { - nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); } else { // if transform precoding or SC-FDMA is enabled in Uplink diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index 03a37e2b27..2e270318f8 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -150,7 +150,7 @@ void pseudo_random_sequence_optimised(unsigned int size, uint32_t *c, uint32_t c unsigned int n,x1,x2; /* init of m-sequences */ - x1 = 1+ (1<<31); + x1 = 1+ (1U<<31); x2 = cinit; x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); diff --git a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c index b0f9e6d03c..9ed2bd949f 100644 --- a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c +++ b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c @@ -21,6 +21,18 @@ #include "nr_refsig.h" #include "nr_mod_table.h" +short nr_qpsk_mod_table[8]; + +int32_t nr_16qam_mod_table[16]; +#if defined(__SSE2__) +__m128i nr_qpsk_byte_mod_table[2048]; +#endif + +int64_t nr_16qam_byte_mod_table[1024]; + +int64_t nr_64qam_mod_table[4096]; + +int32_t nr_256qam_mod_table[512]; void nr_generate_modulation_table() { float sqrt2 = 0.70711; diff --git a/openair1/PHY/NR_REFSIG/nr_mod_table.h b/openair1/PHY/NR_REFSIG/nr_mod_table.h index aa8b99f584..2c6964fe96 100644 --- a/openair1/PHY/NR_REFSIG/nr_mod_table.h +++ b/openair1/PHY/NR_REFSIG/nr_mod_table.h @@ -29,16 +29,16 @@ #define NR_MOD_TABLE_QAM64_OFFSET 23 #define NR_MOD_TABLE_QAM256_OFFSET 87 -short nr_qpsk_mod_table[8]; +extern short nr_qpsk_mod_table[8]; -int32_t nr_16qam_mod_table[16]; +extern int32_t nr_16qam_mod_table[16]; #if defined(__SSE2__) -__m128i nr_qpsk_byte_mod_table[2048]; +extern __m128i nr_qpsk_byte_mod_table[2048]; #endif -int64_t nr_16qam_byte_mod_table[1024]; +extern int64_t nr_16qam_byte_mod_table[1024]; -int64_t nr_64qam_mod_table[4096]; +extern int64_t nr_64qam_mod_table[4096]; -int32_t nr_256qam_mod_table[512]; +extern int32_t nr_256qam_mod_table[512]; #endif diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 19b9736bcb..b32d48a2e9 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -120,8 +120,7 @@ EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE] ; /* profiling structure */ -EXTERN double cpuf; -time_stats_t generic_time[TIME_LAST]; +EXTERN time_stats_t generic_time[TIME_LAST]; #ifndef DEFINE_HEADER_ONLY diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h index 44d30da8f3..43ec0c03dc 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h @@ -58,7 +58,7 @@ #define INDEX_SB_LESS_32 (4) /* index of dftsizes array for which subcarrier number is less than 36 */ -const uint16_t ul_allocated_re[SRS_SB_CONF] /* number of uplink allocated resource elements */ +EXTERN const uint16_t ul_allocated_re[SRS_SB_CONF] /* number of uplink allocated resource elements */ /* this table is derivated from TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration which gives m_SRS_b then all possible values of sequence length is */ /* M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC with K_TC = 2 or K_TC = 4 as specified in TS 38.211 6.4.1.4.3 */ #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H @@ -82,7 +82,7 @@ m_SRS_b 224 116, 240 256 264 272 144 152 160 168 176 184 ; /* table of largest prime number lower than uplink allocated resource elements "ul_allocated_re" */ -const uint16_t ref_ul_primes[SRS_SB_CONF] +EXTERN const uint16_t ref_ul_primes[SRS_SB_CONF] #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H = { /* 6, 12, 18, 24, 30, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, */ @@ -101,10 +101,10 @@ const uint16_t ref_ul_primes[SRS_SB_CONF] ; /* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */ -int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; +EXTERN int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; /* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */ -const char phi_M_ZC_6[6*U_GROUP_NUMBER] +EXTERN const char phi_M_ZC_6[6*U_GROUP_NUMBER] #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H = { /* 0 1 2 3 4 5 */ @@ -142,7 +142,7 @@ const char phi_M_ZC_6[6*U_GROUP_NUMBER] #endif ; /* Table 5.2.2.2-2: Definition of phi ( n ) for M ZC = 12 */ -const char phi_M_ZC_12[12*U_GROUP_NUMBER] +EXTERN const char phi_M_ZC_12[12*U_GROUP_NUMBER] #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H = { /* 0 1 2 3 4 5 6 7 8 9 10 11 */ @@ -181,7 +181,7 @@ const char phi_M_ZC_12[12*U_GROUP_NUMBER] ; /* Table 5.2.2.2-3: Definition of phi (n ) for M_ZC = 18 */ -const char phi_M_ZC_18[18*U_GROUP_NUMBER] +EXTERN const char phi_M_ZC_18[18*U_GROUP_NUMBER] #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H = { /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 */ @@ -220,7 +220,7 @@ const char phi_M_ZC_18[18*U_GROUP_NUMBER] ; /* Table 5.2.2.2-4: Definition of phi (n ) for M_ZC = 24 */ -const char phi_M_ZC_24[24*U_GROUP_NUMBER] +EXTERN const char phi_M_ZC_24[24*U_GROUP_NUMBER] #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H = { /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 */ @@ -260,10 +260,10 @@ const char phi_M_ZC_24[24*U_GROUP_NUMBER] /************** FUNCTION ******************************************/ -int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq); +EXTERN int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq); -int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling); +EXTERN int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling); /*! \brief This function generate the sounding reference symbol (SRS) for the uplink. @param tables of srs @@ -278,7 +278,7 @@ void free_ul_reference_signal_sequences(void); #define MAX_INDEX_DMRS_UL_ALLOCATED_REs 53 -const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs] +EXTERN const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs] /* Number of possible DMRS REs based on PRBs allocated for PUSCH. Array has values until 273 RBs (100Mhz BW) Number of PUSCH RBs allocated should be able to be expressed as 2topowerofn*3topowerofn*5tothepowerofn According to 3GPP spec 38.211 section 6.3.1.4 @@ -307,7 +307,7 @@ const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs] /* Table of largest prime number N_ZC < possible DMRS REs M_ZC, this array has values until 100Mhz According to 3GPP spec 38.211 section 5.2.2.1 Table used in calculating DMRS low papr type1 sequence for transform precoding */ -const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] +EXTERN const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H = { /*DMRS REs 6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96, */ @@ -331,8 +331,8 @@ const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] ; /// PUSCH DMRS for transform precoding -int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; -int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +EXTERN int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +EXTERN int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res); void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling); void free_gnb_lowpapr_sequences(void); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 35c4698761..2d43fb5aed 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -152,7 +152,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, else { nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData; } - n_dmrs = (rel15->rbSize+rel15->rbStart)*nb_re_dmrs; + n_dmrs = (rel15->BWPStart+rel15->rbStart+rel15->rbSize)*nb_re_dmrs; uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100 uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos); @@ -266,6 +266,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, #endif /// DMRS QPSK modulation + // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { if (rel15->dlDmrsSymbPos & (1 << l)) { nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated @@ -318,11 +319,24 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, /// DMRS QPSK modulation uint8_t k_prime=0; uint16_t n=0; - if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion - if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) - dmrs_idx = rel15->rbStart*6; - else - dmrs_idx = rel15->rbStart*4; + + if ((dmrs_symbol_map & (1 << l))){ // DMRS time occasion + // The reference point for is subcarrier 0 of the lowest-numbered resource block in CORESET 0 if the corresponding + // PDCCH is associated with CORESET 0 and Type0-PDCCH common search space and is addressed to SI-RNTI + // 3GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources + if (rel15->rnti==SI_RNTI) { + if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) { + dmrs_idx = rel15->rbStart*6; + } else { + dmrs_idx = rel15->rbStart*4; + } + } else { + if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) { + dmrs_idx = (rel15->rbStart+rel15->BWPStart)*6; + } else { + dmrs_idx = (rel15->rbStart+rel15->BWPStart)*4; + } + } } // Update l_prime in the case of double DMRS config @@ -507,7 +521,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; } else { - LOG_W(PHY,"beam index for PDSCH allocation already taken\n"); + LOG_D(PHY,"beam index for PDSCH allocation already taken\n"); } }// dlsch loop diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 8248de7416..34c647810d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -774,7 +774,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, else { preamble_shift -= NCS; - + if (preamble_shift < 0) preamble_shift+=N_ZC; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index edca81d501..c1bca8d2a0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -326,7 +326,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, #endif uint8_t is_dmrs_re; - start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; + start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size; nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; #ifdef __AVX2__ int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); @@ -1178,7 +1178,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, } - bwp_start_subcarrier = (rel15_ul->rb_start*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; + bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 76a48f38ae..909d0b8954 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -657,6 +657,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, + bool is_SI, unsigned char Ns, unsigned short p, unsigned char symbol, @@ -694,7 +695,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, #endif // generate pilot for gNB port number 1000+p - uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart; + uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12; + if (is_SI) { + rb_offset -= BWPStart; + } uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; int8_t delta = get_delta(p, config_type); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 6c461ef448..1466fabe5d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -70,6 +70,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, + bool is_SI, unsigned char Ns, unsigned short p, unsigned char symbol, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 35c4a6e8cb..35baef1792 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -52,7 +52,7 @@ * set as command line argument, see lte-softmodem.c * default value: 0 */ -int16_t nr_dlsch_demod_shift = 0; +int32_t nr_dlsch_demod_shift = 0; //int16_t interf_unaw_shift = 13; //#define DEBUG_HARQ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 3d8c975a5c..60b87fae08 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -137,7 +137,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t mod_order = pusch_pdu->qam_mod_order; uint16_t rnti = pusch_pdu->rnti; uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data; - uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB; + uint16_t start_sc = frame_parms->first_carrier_offset + (start_rb+pusch_pdu->bwp_start)*NR_NB_SC_PER_RB; if (start_sc >= frame_parms->ofdm_symbol_size) start_sc -= frame_parms->ofdm_symbol_size; @@ -195,7 +195,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////DMRS Modulation///////////////////////// /////////// uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; - uint16_t n_dmrs = (start_rb+nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); + uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16))); /////////// //////////////////////////////////////////////////////////////////////// @@ -355,16 +355,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (pusch_pdu->transform_precoding == transform_precoder_disabled){ if (dmrs_type == pusch_dmrs_type1) - dmrs_idx = start_rb*6; + dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; else - dmrs_idx = start_rb*4; - - // Perform this on gold sequence, not required when SC FDMA operation is done, + dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; + + // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part + // Perform this on gold sequence, not required when SC FDMA operation is done, nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated } else { - dmrs_idx = 0; - } + dmrs_idx = 0; + } } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { diff --git a/openair1/PHY/TOOLS/calibration_scope.c b/openair1/PHY/TOOLS/calibration_scope.c new file mode 100644 index 0000000000..da1acb5175 --- /dev/null +++ b/openair1/PHY/TOOLS/calibration_scope.c @@ -0,0 +1,387 @@ +#include +#include +#include "executables/softmodem-common.h" +#include "executables/nr-softmodem-common.h" +#include +#include + +#define TPUT_WINDOW_LENGTH 100 +#define ScaleZone 4 + +const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW}; +const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED}; + +typedef struct { + int16_t r; + int16_t i; +} scopeSample_t; +#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i) +typedef struct { + void ** samplesRx; + openair0_device *rfdevice; +} calibData_t; + +typedef struct OAIgraph { + FL_OBJECT *graph; + FL_OBJECT *text; + float maxX; + float maxY; + float minX; + float minY; + int x; + int y; + int w; + int h; + int waterFallh; + double *waterFallAvg; + boolean_t initDone; + int iteration; + void (*funct) (struct OAIgraph *graph, calibData_t *); +} OAIgraph_t; + + +/* Forms and Objects */ +typedef struct { + calibData_t * context; + FL_FORM *phy_scope; + OAIgraph_t graph[20]; + FL_OBJECT *button_0; +} OAI_phy_scope_t; + +typedef struct { + FL_FORM *stats_form; + void *vdata; + char *cdata; + long ldata; + FL_OBJECT *stats_text; + FL_OBJECT *stats_button; +} FD_stats_form; + +static void drawsymbol(FL_OBJECT *obj, int id, + FL_POINT *p, int n, int w, int h) { + fl_points( p, n, FL_YELLOW); +} + +#define WATERFALL 10000 + +static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { + if (type==WATERFALL) { + graph->waterFallh=h-15; + graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh); + + for (int i=0; i< graph->waterFallh; i++) + graph->waterFallAvg[i]=0; + + graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label); + graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label); + fl_set_object_lcolor(graph->text,FL_WHITE); + fl_set_object_color(graph->text, FL_BLACK, FL_BLACK); + fl_set_object_lalign(graph->text, FL_ALIGN_CENTER ); + } else { + graph->graph=fl_add_xyplot(type, x, y, w, h, label); + fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color + fl_set_object_color(graph->graph, FL_BLACK, pointColor); + + for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++) + fl_set_xyplot_symbol(graph->graph, i, drawsymbol); + } + + graph->x=x; + graph->y=y; + graph->w=w; + graph->h=h; + graph->maxX=0; + graph->maxY=0; + graph->minX=0; + graph->minY=0; + graph->initDone=false; + graph->iteration=0; +} + +static OAIgraph_t calibrationCommonGraph( void (*funct) (OAIgraph_t *graph, calibData_t *context), + int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { + OAIgraph_t graph; + commonGraph(&graph, type, x, y, w, h, label, pointColor); + graph.funct=funct; + return graph; +} + + +static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) { + if ( maxX > graph->maxX || minX < graph->minX || + abs(maxX-graph->maxX)>abs(graph->maxX)/2 || + abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) { + graph->maxX/=2; + graph->minX/=2; + graph->maxX=max(graph->maxX,maxX); + graph->minX=min(graph->minX,minX); + fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2); + } + + if ( maxY > graph->maxY || minY < graph->minY || + abs(maxY-graph->maxY)>abs(graph->maxY)/2 || + abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) { + graph->maxY/=2; + graph->minY/=2; + graph->maxY=max(graph->maxY,maxY); + graph->minY=min(graph->minY,minY); + fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2); + } +} + +static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) { + float *old_x; + float *old_y; + int old_len=-1; + + if (graph->iteration >1) + fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len); + + if (old_len != len) { + LOG_W(HW,"allocating graph of %d scope\n", len); + float values[len]; + float time[len]; + + // make time in case we will use it + for (int i=0; igraph,time,values,len,"","",""); + else + fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]); + + fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len); + AssertFatal(old_len==len,""); + } + + *x=old_x; + *y=old_y; +} + +static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) { + fl_redraw_object(graph->graph); + + if ( NoAutoScale && graph->iteration%NoAutoScale == 0) { + float maxX=0, maxY=0, minX=0, minY=0; + + for (int k=0; kiteration++; +} + +static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { + if ( values == NULL ) + return; + fl_winset(FL_ObjWin(graph->graph)); + const int samplesPerPixel=datasize/graph->w; + int displayPart=graph->waterFallh-ScaleZone; + int row=graph->iteration%displayPart; + double avg=0; + + for (int i=0; i < displayPart; i++) + avg+=graph->waterFallAvg[i]; + + avg/=displayPart; + graph->waterFallAvg[row]=0; + + for (int pix=0; pixw; pix++) { + scopeSample_t *end=values+(pix+1)*samplesPerPixel; + end-=2; + AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize); + double val=0; + + for (scopeSample_t *s=values+(pix)*samplesPerPixel; + s waterFallAvg[row]+=val/graph->w; + int col=0; + + if (val > avg*2 ) + col=1; + + if (val > avg*10 ) + col=2; + + if (val > avg*100 ) + col=3; + + fl_point(pix, graph->iteration%displayPart, water_colors[col]); + } + + if (graph->initDone==false) { + for ( int i=0; i < graph->waterFallh; i++ ) + for ( int j = 0 ; j < graph->w ; j++ ) + fl_point(j, i, FL_BLACK); + + for ( int i=1; iwaterFallh; j++) + fl_point(i*(graph->w/divisions),j, FL_WHITE); + + graph->initDone=true; + } + + fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg)); + graph->iteration++; +} + +static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) { + float *values, *time; + oai_xygraph_getbuff(graph, &time, &values, len, 0); + + for (int ant=0; antsamplesRx[0], + 0, 0, + "X axis:one frame in time"); +} +static void gNBfreqWaterFall (OAIgraph_t *graph, calibData_t *context) { + //use 1st antenna + genericWaterFall(graph, (scopeSample_t *)context->samplesRx[0], + 0, 0, + "X axis:one frame in time"); +} +static void timeResponse (OAIgraph_t *graph, calibData_t *context) { + #if 0 + const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size; + float *values, *time; + oai_xygraph_getbuff(graph, &time, &values, len, 0); + const int ant=0; // display antenna 0 for each UE + + for (int ue=0; uepusch_vars[ue]->ul_ch_estimates_time[ant]; + + if (data != NULL) { + for (int i=0; iframe_parms; + int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot; + + for (int ue=0; uepusch_vars[ue]->rxdataF_comp[0]; + float *I, *Q; + oai_xygraph_getbuff(graph, &I, &Q, sz, ue); + + if (pusch_comp) { + for (int k=0; kcontext=context; + // Define form + fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 ); + // This the whole UI box + obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" ); + fl_set_object_color( obj, FL_BLACK, FL_WHITE ); + int curY=0,x,y,w,h; + // Received signal + fdui->graph[0] = calibrationCommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100, + "Received Signal (Time-Domain, one frame)", FL_RED ); + + // Time-domain channel response + //fdui->graph[1] = calibrationCommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100, "SRS Frequency Response (samples, abs)", FL_RED ); + fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h); + curY+=h; + // Frequency-domain channel response + fdui->graph[1] = calibrationCommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100, + "Channel Frequency domain (RE, one frame)", FL_RED ); + fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h); + curY+=h+20; + // LLR of PUSCH + //fdui->graph[3] = calibrationCommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW ); + // I/Q PUSCH comp + fdui->graph[2] = calibrationCommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200, + "PUSCH I/Q of MF Output", FL_YELLOW ); + fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h); + curY+=h; + //fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h); + curY+=h; + fdui->graph[3].graph=NULL; + fl_end_form( ); + fdui->phy_scope->fdui = fdui; + fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB"); + return fdui; +} + +void calibrationScope(OAI_phy_scope_t *form) { + int i=0; + + while (form->graph[i].graph) { + form->graph[i].funct(form->graph+i, form->context); + i++; + } + + //fl_check_forms(); +} + +static void *scopeThread(void *arg) { + calibData_t * context = (calibData_t *)arg; + size_t stksize=0; + pthread_attr_t atr; + pthread_attr_init(&atr); + pthread_attr_getstacksize(&atr, &stksize); + pthread_attr_setstacksize(&atr,32*1024*1024 ); + sleep(3); // no clean interthread barriers + int fl_argc=1; + char *name="Calibration-scope"; + fl_initialize (&fl_argc, &name, NULL, 0, 0); + OAI_phy_scope_t *form = createScopeCalibration(context); + + while (!oai_exit) { + calibrationScope(form); + usleep(99*1000); + } + + return NULL; +} + +void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice) { + pthread_t forms_thread; + calibData_t * tmp=(calibData_t *) malloc(sizeof(*tmp)); + tmp->samplesRx=samplesRx; + tmp->rfdevice=rfdevice; + threadCreate(&forms_thread, scopeThread, (void*) tmp, "scope", -1, OAI_PRIORITY_RT_LOW); +} diff --git a/openair1/PHY/TOOLS/calibration_scope.h b/openair1/PHY/TOOLS/calibration_scope.h new file mode 100644 index 0000000000..052a1a6b6e --- /dev/null +++ b/openair1/PHY/TOOLS/calibration_scope.h @@ -0,0 +1,5 @@ +#ifndef CALIB_SCOPE_H +#define CALIB_SCOPE_H + +void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice); +#endif diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c new file mode 100644 index 0000000000..982ca9d254 --- /dev/null +++ b/openair1/PHY/TOOLS/calibration_test.c @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include + + +volatile int oai_exit=false; +unsigned int mmapped_dma=0; +int single_thread_flag; +uint32_t timing_advance; +int8_t threequarter_fs; +int usrp_tx_thread; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int opp_enabled; +static double snr_dB=20; +THREAD_STRUCT thread_struct; +#include + +int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;} +void nfapi_setmode(nfapi_mode_t nfapi_mode) {} +void set_taus_seed(unsigned int seed_init){}; + +int main(int argc, char **argv) { + ///static configuration for NR at the moment + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + set_softmodem_sighandler(); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + logInit(); + paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; + + CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); + get_common_options(SOFTMODEM_GNB_BIT ); + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); + configure_linux(); + + + int N_RB=50; + int subCarrierFreq=30e3; + int sampling_rate=30.72e6; + int DFT=2048; + int TxAdvanceInDFTSize=12; + int antennas=1; + uint64_t freq=3619.200e6; + int rxGain=90; + int txGain=90; + int filterBand=40e6; + char * usrp_addrs="type=b200"; + + openair0_config_t openair0_cfg= { + //! Module ID for this configuration + .Mod_id=0, + //! device log level + .log_level=0, + //! duplexing mode + .duplex_mode=0, + //! number of downlink resource blocks + .num_rb_dl=N_RB, + //! number of samples per frame + .samples_per_frame=0, + //! the sample rate for both transmit and receive. + .sample_rate=sampling_rate, + //device is doing mmapped DMA transfers + .mmapped_dma=0, + //! offset in samples between TX and RX paths + .tx_sample_advance=0, + //! samples per packet on the fronthaul interface + .samples_per_packet=1024, + //! number of RX channels (=RX antennas) + .rx_num_channels=antennas, + //! number of TX channels (=TX antennas) + .tx_num_channels=antennas, + //! \brief Center frequency in Hz for RX. + //! index: [0..rx_num_channels[ + .rx_freq={freq,freq,freq,freq}, + //! \brief Center frequency in Hz for TX. + //! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels + .tx_freq={freq,freq,freq,freq}, + //! \brief memory + //! \brief Pointer to Calibration table for RX gains + .rx_gain_calib_table=NULL, + //! mode for rxgain (ExpressMIMO2) + .rxg_mode={0}, + //! \brief Gain for RX in dB. + //! index: [0..rx_num_channels] + .rx_gain={rxGain,rxGain,rxGain,rxGain}, + //! \brief Gain offset (for calibration) in dB + //! index: [0..rx_num_channels] + .rx_gain_offset={0}, + //! gain for TX in dB + .tx_gain={txGain,txGain,txGain,txGain}, + //! RX bandwidth in Hz + .rx_bw=filterBand, + //! TX bandwidth in Hz + .tx_bw=filterBand, + //! clock source + .clock_source=external,//internal gpsdo external + //! timing_source + .time_source=internal, //internal gpsdo external + //! Manual SDR IP address + //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + .sdr_addrs=usrp_addrs, + //! Auto calibration flag + .autocal={0}, + //! rf devices work with x bits iqs when oai have its own iq format + //! the two following parameters are used to convert iqs + .iq_txshift=0, + .iq_rxrescale=0, + //! Configuration file for LMS7002M + .configFilename="", + //! remote IP/MAC addr for Ethernet interface + .remote_addr="", + //! remote port number for Ethernet interface + .remote_port=0, + //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE) + .my_addr=0, + //! local port number for Ethernet interface (eNB/BBU, UE) + .my_port=0, + //! record player configuration, definition in record_player.h + .recplay_mode=0, + .recplay_conf=NULL, + //! number of samples per tti + .samples_per_tti=0, + //! check for threequarter sampling rate + .threequarter_fs=0, + }; + //----------------------- + openair0_device rfdevice= { + /*!tx write thread*/ + //.write_thread={0}, + /*!brief Module ID of this device */ + .Mod_id=0, + /*!brief Component Carrier ID of this device */ + .CC_id=0, + /*!brief Type of this device */ + .type=NONE_DEV, + /*!brief Transport protocol type that the device supports (in case I/Q samples need to be transported) */ + .transp_type=NONE_TP, + /*!brief Type of the device's host (RAU/RRU) */ + .host_type=MIN_HOST_TYPE, + /* !brief RF frontend parameters set by application */ + .openair0_cfg=NULL, //set by device_init + /* !brief ETH params set by application */ + .eth_params=NULL, + //! record player data, definition in record_player.h + .recplay_state=NULL, + /* !brief Indicates if device already initialized */ + .is_init=0, + /*!brief Can be used by driver to hold internal structure*/ + .priv=NULL, + /* Functions API, which are called by the application*/ + /*! \brief Called to start the transceiver. Return 0 if OK, < 0 if error + @param device pointer to the device structure specific to the RF hardware target + */ + .trx_start_func=NULL, + + /*! \brief Called to configure the device + @param device pointer to the device structure specific to the RF hardware target + */ + .trx_config_func=NULL, + + /*! \brief Called to send a request message between RAU-RRU on control port + @param device pointer to the device structure specific to the RF hardware target + @param msg pointer to the message structure passed between RAU-RRU + @param msg_len length of the message + */ + .trx_ctlsend_func=NULL, + + /*! \brief Called to receive a reply message between RAU-RRU on control port + @param device pointer to the device structure specific to the RF hardware target + @param msg pointer to the message structure passed between RAU-RRU + @param msg_len length of the message + */ + .trx_ctlrecv_func=NULL, + + /*! \brief Called to send samples to the RF target + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at whicch the first sample MUST be sent + @param buff Buffer which holds the samples (2 dimensional) + @param nsamps number of samples to be sent + @param number of antennas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied + */ + .trx_write_func=NULL, + + /*! \brief Called to send samples to the RF target + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at whicch the first sample MUST be sent + @param buff Buffer which holds the samples (1 dimensional) + @param nsamps number of samples to be sent + @param antenna_id index of the antenna if the device has multiple anteannas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied + */ + .trx_write_func2=NULL, + + /*! \brief Receive samples from hardware. + * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param num_antennas number of antennas from which to receive samples + * \returns the number of sample read + */ + + .trx_read_func=NULL, + + /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns. + * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param antenna_id Index of antenna from which samples were received + * \returns the number of sample read + */ + .trx_read_func2=NULL, + + /*! \brief print the device statistics + * \param device the hardware to use + * \returns 0 on success + */ + /*! \brief print the device statistics + * \param device the hardware to use + * \returns 0 on success + */ + .trx_get_stats_func=NULL, + + /*! \brief Reset device statistics + * \param device the hardware to use + * \returns 0 in success + */ + .trx_reset_stats_func=NULL, + + /*! \brief Terminate operation of the transceiver -- free all associated resources + * \param device the hardware to use + */ + .trx_end_func=NULL, + + /*! \brief Stop operation of the transceiver + */ + .trx_stop_func=NULL, + + /* Functions API related to UE*/ + + /*! \brief Set RX feaquencies + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + * \param exmimo_dump_config dump EXMIMO configuration + * \returns 0 in success + */ + .trx_set_freq_func=NULL, + + /*! \brief Set gains + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + * \returns 0 in success + */ + .trx_set_gains_func=NULL, + + /*! \brief RRU Configuration callback + * \param idx RU index + * \param arg pointer to capabilities or configuration + */ + .configure_rru=NULL, + /*! \brief Pointer to generic RRU private information + */ + .thirdparty_priv=NULL, + .thirdparty_init=NULL, + /*! \brief Callback for Third-party RRU Cleanup routine + \param device the hardware configuration to use + */ + .thirdparty_cleanup=NULL, + + /*! \brief Callback for Third-party start streaming routine + \param device the hardware configuration to use + */ + .thirdparty_startstreaming=NULL, + + /*! \brief RRU Configuration callback + * \param idx RU index + * \param arg pointer to capabilities or configuration + */ + .trx_write_init=NULL, + /* \brief Get internal parameter + * \param id parameter to get + * \return a pointer to the parameter + */ + .get_internal_parameter=NULL, + }; + + openair0_device_load(&rfdevice,&openair0_cfg); + + void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) ); + void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) ); + + for (int i=0; ilte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - if (otg_enabled) { + if (0) { fl_set_button(form_enb[CC_id][UE_id]->button_0,1); fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON"); } else { diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index acd22bc78d..d28bb1b8ba 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -27,7 +27,6 @@ #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #define TPUT_WINDOW_LENGTH 100 -int otg_enabled; FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW}; @@ -57,11 +56,9 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) { static void dl_traffic_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "DL Traffic ON"); - otg_enabled = 1; fl_set_object_color(button, FL_GREEN, FL_GREEN); } else { fl_set_object_label(button, "DL Traffic OFF"); - otg_enabled = 0; fl_set_object_color(button, FL_RED, FL_RED); } } @@ -131,7 +128,6 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) { fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" ); fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); fl_set_button(fdui->button_0,0); - otg_enabled = 0; fl_set_object_label(fdui->button_0, "DL Traffic OFF"); fl_set_object_color(fdui->button_0, FL_RED, FL_RED); fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 ); @@ -153,7 +149,6 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, int16_t **chest_t; int16_t **chest_f; int16_t *pusch_llr; - int32_t *pusch_comp; int32_t *pucch1_comp; int32_t *pucch1_thres; int32_t *pucch1ab_comp; @@ -184,12 +179,11 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero bit = malloc(coded_bits_per_codeword*sizeof(float)); - - rxsig_t = (int16_t**) phy_vars_enb->RU_list[0]->common.rxdata; + rxsig_t = (int16_t **) phy_vars_enb->RU_list[0]->common.rxdata; chest_t = (int16_t **) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates; chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates; pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int32_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; + int16_t *pusch_comp= (int16_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id]; pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id]; pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id]; diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index d44f8e325b..a9caf8713b 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -32,8 +32,7 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_ue_max[NUMBER_OF_UE_MAX] = {0}; -static void ia_receiver_on_off( FL_OBJECT *button, long arg) -{ +static void ia_receiver_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "IA Receiver ON"); // PHY_vars_UE_g[0][0]->use_ia_receiver = 1; @@ -45,8 +44,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) } } -static void dl_traffic_on_off( FL_OBJECT *button, long arg) -{ +static void dl_traffic_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "DL Traffic ON"); otg_enabled = 1; @@ -58,9 +56,7 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) } } -static void sic_receiver_on_off( FL_OBJECT *button, long arg) -{ - +static void sic_receiver_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "SIC Receiver ON"); use_sic_receiver = 1; @@ -72,8 +68,7 @@ static void sic_receiver_on_off( FL_OBJECT *button, long arg) } } -FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) -{ +FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) { FL_OBJECT *obj; FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui ); // Define form @@ -145,8 +140,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) void phy_scope_eNB(FD_lte_phy_scope_enb *form, PHY_VARS_eNB *phy_vars_enb, - int UE_id) -{ + int UE_id) { int eNB_id = 0; int i,i2,arx,atx,ind,k; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms; @@ -176,24 +170,27 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, int coded_bits_per_codeword = 0; uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2 int mcs = 0; + // choose max MCS to compute coded_bits_per_codeword if (phy_vars_enb->ulsch[UE_id]!=NULL) { for (harq_pid=0; harq_pid<3; harq_pid++) { mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs); } } + coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti; - chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero + chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); + llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero bit = malloc(coded_bits_per_codeword*sizeof(float)); - rxsig_t = (int16_t**) phy_vars_enb->common_vars.rxdata[eNB_id]; - chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; - chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; - pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; - pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; - pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; - pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; + rxsig_t = (int16_t **) phy_vars_enb->common_vars.rxdata[eNB_id]; + chest_t = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; + chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; + pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr; + pusch_comp = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; + pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id]; + pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id]; + pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id]; + // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { if (rxsig_t[0] != NULL) { @@ -201,48 +198,61 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1]))); time[i] = (float) i; } + fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","",""); } + for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); } } } + // Channel Impulse Response if (chest_t != NULL) { ymax = 0; + if (chest_t[0] !=NULL) { for (i=0; i<(frame_parms->ofdm_symbol_size); i++) { - i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; - time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); + i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; + time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1])); + if (chest_t_abs[0][i] > ymax) ymax = chest_t_abs[0][i]; } + fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","",""); } + for (arx=1; arxofdm_symbol_size>>3); i++) { chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1])); + if (chest_t_abs[arx][i] > ymax) ymax = chest_t_abs[arx][i]; } + fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]); fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT); } } + // Avoid flickering effect // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); fl_set_xyplot_ybounds(form->chest_t,0,ymax); } + // Channel Frequency Response if (chest_f != NULL) { ind = 0; + for (atx=0; atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3); fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); + for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); } + // other tx antennas if (nb_antennas_tx > 1) { if (nb_antennas_rx > 1) { @@ -279,17 +292,21 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, } } } + // PUSCH LLRs if (pusch_llr != NULL) { for (i=0; ipusch_llr,bit,llr,coded_bits_per_codeword,"","",""); } + // PUSCH I/Q of MF Output if (pusch_comp!=NULL) { ind=0; + for (k=0; ksymbols_per_tti; k++) { for (i=0; i<12*frame_parms->N_RB_UL; i++) { I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i]; @@ -297,8 +314,10 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, ind++; } } + fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","",""); } + // PUSCH I/Q of MF Output if (pucch1ab_comp!=NULL) { for (ind=0; ind<10240; ind++) { @@ -308,6 +327,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, B_pucch[ind] = ind; C_pucch[ind] = (float)pucch1_thres[ind]; } + fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED); @@ -315,6 +335,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000); fl_set_xyplot_ybounds(form->pucch_comp1,0,80); } + // PUSCH Throughput memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); @@ -329,509 +350,564 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, free(chest_f_abs); } -FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) -{ - FL_OBJECT *obj; - FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui ); - // Define form - fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 ); - // This the whole UI box - obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" ); - fl_set_object_color( obj, FL_BLACK, FL_BLACK ); - // Received signal - fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); - fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); - fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color - fl_set_xyplot_ybounds(fdui->rxsig_t,30,70); - // Time-domain channel response - fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); - fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); - fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color - // Frequency-domain channel response - fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); - fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); - fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color - fl_set_xyplot_ybounds( fdui->chest_f,30,70); - /* - // LLR of PBCH - fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" ); - fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN ); - fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pbch_llr,2); - fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR); - fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920); - // I/Q PBCH comp - fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" ); - fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN ); - fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pbch_comp,2); - fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100); - fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100); - // LLR of PDCCH - fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" ); - fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN ); - fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pdcch_llr,2); - // I/Q PDCCH comp - fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" ); - fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN ); - fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pdcch_comp,2); - fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR); - */ - int offset=240; - // LLR of PDSCH - fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); - fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW ); - fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pdsch_llr,2); - fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR); - // I/Q PDSCH comp - fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" ); - fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW ); - fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pdsch_comp,2); - // LLR of PDSCH - fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); - fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW ); - fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2); - fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR); - // I/Q PDSCH comp - fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" ); - fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW ); - fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color - fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2); - /* - // Throughput on PDSCH - fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" ); - fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX ); - fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE ); - fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color - */ - // Generic UE Button - fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" ); - fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); - //use_sic_receiver = 0; - fl_set_button(fdui->button_0,0); - fl_set_object_label(fdui->button_0, "SIC Receiver OFF"); - fl_set_object_color(fdui->button_0, FL_RED, FL_RED); - fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 ); - fl_hide_object(fdui->button_0); - - fl_end_form( ); - fdui->lte_phy_scope_ue->fdui = fdui; - return fdui; +FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { + FL_OBJECT *obj; + FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui ); + // Define form + fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 ); + // This the whole UI box + obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" ); + fl_set_object_color( obj, FL_BLACK, FL_BLACK ); + // Received signal + fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); + fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color + fl_set_xyplot_ybounds(fdui->rxsig_t,30,70); + // Time-domain channel response + fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); + fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color + // Frequency-domain channel response + fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); + fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color + fl_set_xyplot_ybounds( fdui->chest_f,30,70); + /* + // LLR of PBCH + fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN ); + fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pbch_llr,2); + fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR); + fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920); + // I/Q PBCH comp + fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN ); + fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pbch_comp,2); + fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100); + fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100); + // LLR of PDCCH + fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN ); + fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdcch_llr,2); + // I/Q PDCCH comp + fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN ); + fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdcch_comp,2); + fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR); + */ + int offset=240; + // LLR of PDSCH + fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_llr,2); + fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR); + // I/Q PDSCH comp + fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_comp,2); + // LLR of PDSCH + fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2); + fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR); + // I/Q PDSCH comp + fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2); + /* + // Throughput on PDSCH + fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" ); + fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE ); + fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color + */ + // Generic UE Button + fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" ); + fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); + //use_sic_receiver = 0; + fl_set_button(fdui->button_0,0); + fl_set_object_label(fdui->button_0, "SIC Receiver OFF"); + fl_set_object_color(fdui->button_0, FL_RED, FL_RED); + fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 ); + fl_hide_object(fdui->button_0); + fl_end_form( ); + fdui->lte_phy_scope_ue->fdui = fdui; + return fdui; } void phy_scope_UE(FD_lte_phy_scope_ue *form, PHY_VARS_UE *phy_vars_ue, int eNB_id, int UE_id, - uint8_t subframe) -{ - int i,arx,atx,ind,k; - LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; - int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; - uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; - uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB; - int16_t **rxsig_t; - int16_t **chest_t; - int16_t **chest_f; - int16_t *pdsch_llr,*pdsch_llr1; - int16_t *pdsch_comp,*pdsch_comp1; - int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1; - int8_t *pdcch_llr; - int16_t *pdcch_comp; - int8_t *pbch_llr; - int16_t *pbch_comp; - float Re,Im,ymax=1; - int num_pdcch_symbols=3; - float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch; - float *I, *Q; - float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES]; - float **chest_t_abs; - float time[FRAME_LENGTH_COMPLEX_SAMPLES]; - float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; - int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx; - uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id]; - int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1; - int mod0,mod1; - int mcs0 = 0; - int mcs1=0; - unsigned char harq_pid = 0; - int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid; - if (harq_pid>=8) - return; - mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs; - // Button 0 - /* - if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { - // we are in TM5 - fl_show_object(form->button_0); - } - */ - } - fl_show_object(form->button_0); - if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) { - harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid; - if (harq_pid>=8) - return; - mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs; - } - if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) { - num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols; - } - // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { - mod0 = get_Qm(mcs0); - coded_bits_per_codeword0 = get_G(frame_parms, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - get_Qm(mcs0), - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, - num_pdcch_symbols, - frame, - subframe, - beamforming_mode); - } else { - coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - mod0=0; - } - if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) { - mod1 = get_Qm(mcs1); - coded_bits_per_codeword1 = get_G(frame_parms, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, - get_Qm(mcs1), - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl, - num_pdcch_symbols, - frame, - subframe, - beamforming_mode); - } else { - coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - mod1=0; - } - I = (float*) calloc(nsymb_ce*2,sizeof(float)); - Q = (float*) calloc(nsymb_ce*2,sizeof(float)); - chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*)); - for (arx=0;arxofdm_symbol_size,sizeof(float)); - } - chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. - llr0 = (float*) malloc(coded_bits_per_codeword0*sizeof(float)); - memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero - bit0 = malloc(coded_bits_per_codeword0*sizeof(float)); + uint8_t subframe) { + int i,arx,atx,ind,k; + LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; + int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; + uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; + uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB; + int16_t **rxsig_t; + int16_t **chest_t; + int16_t **chest_f; + int16_t *pdsch_llr,*pdsch_llr1; + int16_t *pdsch_comp,*pdsch_comp1; + int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1; + int8_t *pdcch_llr; + int16_t *pdcch_comp; + int8_t *pbch_llr; + int16_t *pbch_comp; + float Re,Im,ymax=1; + int num_pdcch_symbols=3; + float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch; + float *I, *Q; + float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES]; + float **chest_t_abs; + float time[FRAME_LENGTH_COMPLEX_SAMPLES]; + float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; + int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx; + uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id]; + int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1; + int mod0,mod1; + int mcs0 = 0; + int mcs1=0; + unsigned char harq_pid = 0; + int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. - llr1 = (float*) malloc(coded_bits_per_codeword1*sizeof(float)); - memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero - bit1 = malloc(coded_bits_per_codeword1*sizeof(float)); - llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero - bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); - rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata; - chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id]; - chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; - pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; - pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; - pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; - pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; - pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 - pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1 - pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0]; - //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0]; - //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1]; - pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0]; - //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0]; - pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0]; - pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0]; - pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0]; - pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0]; - fl_freeze_form(form->lte_phy_scope_ue); - // Received signal in time domain of receive antenna 0 - if (rxsig_t != NULL) { - if (rxsig_t[0] != NULL) { - for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","",""); - } - for (arx=1;arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); - } - } + if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid; + + if (harq_pid>=8) + return; + + mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs; + // Button 0 + /* + if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { + // we are in TM5 + fl_show_object(form->button_0); + } + */ + } + + fl_show_object(form->button_0); + + if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) { + harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid; + + if (harq_pid>=8) + return; + + mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs; + } + + if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) { + num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols; + } + + // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { + mod0 = get_Qm(mcs0); + coded_bits_per_codeword0 = get_G(frame_parms, + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs0), + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe, + beamforming_mode); + } else { + coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod0=0; + } + + if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) { + mod1 = get_Qm(mcs1); + coded_bits_per_codeword1 = get_G(frame_parms, + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs1), + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe, + beamforming_mode); + } else { + coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod1=0; + } + + I = (float *) calloc(nsymb_ce*2,sizeof(float)); + Q = (float *) calloc(nsymb_ce*2,sizeof(float)); + chest_t_abs = (float **) malloc(nb_antennas_rx*sizeof(float *)); + + for (arx=0; arxofdm_symbol_size,sizeof(float)); + } + + chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); + //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. + llr0 = (float *) malloc(coded_bits_per_codeword0*sizeof(float)); + memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero + bit0 = malloc(coded_bits_per_codeword0*sizeof(float)); + //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. + llr1 = (float *) malloc(coded_bits_per_codeword1*sizeof(float)); + memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero + bit1 = malloc(coded_bits_per_codeword1*sizeof(float)); + llr_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero + bit_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); + rxsig_t = (int16_t **) phy_vars_ue->common_vars.rxdata; + chest_t = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id]; + chest_f = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; + pbch_llr = (int8_t *) phy_vars_ue->pbch_vars[eNB_id]->llr; + pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; + pdcch_llr = (int8_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; + pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; + pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 + pdsch_llr1 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1 + pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0]; + //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0]; + //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1]; + pdsch_comp1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0]; + //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0]; + pdsch_mag0 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0]; + pdsch_mag1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0]; + pdsch_magb0 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0]; + pdsch_magb1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0]; + fl_freeze_form(form->lte_phy_scope_ue); + + // Received signal in time domain of receive antenna 0 + if (rxsig_t != NULL) { + if (rxsig_t[0] != NULL) { + for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","",""); } + + for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); + } + } + } + // Channel Impulse Response (still repeated format) if (chest_t != NULL) { ymax = 0; + if (chest_t[0] !=NULL) { for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) { chest_t_abs[0][i] = (float) (chest_t[0][4*i]*chest_t[0][4*i]+chest_t[0][4*i+1]*chest_t[0][4*i+1]); + if (chest_t_abs[0][i] > ymax) ymax = chest_t_abs[0][i]; } + fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","",""); } + for (arx=1; arxofdm_symbol_size>>3); i++) { chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]); + if (chest_t_abs[arx][i] > ymax) ymax = chest_t_abs[arx][i]; } + fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]); fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT); } } - // Avoid flickering effect - // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); - fl_set_xyplot_ybounds(form->chest_t,0,ymax); + + // Avoid flickering effect + // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); + fl_set_xyplot_ybounds(form->chest_t,0,ymax); + } + + // Channel Frequency Response (includes 5 complex sample for filter) + if (chest_f != NULL) { + ind = 0; + + for (atx=0; atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); - //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2); - // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2); - fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); - fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); - for (arx=1;arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); - } - // other tx antennas - if (nb_antennas_tx > 1) { - if (nb_antennas_rx > 1) { - for (atx=1;atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); - } - } - } else { // 1 rx antenna - atx=1; arx=0; - fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); - } - } + + // tx antenna 0 + fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); + //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2); + // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2); + fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); + fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); + + for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); } - /* - // PBCH LLRs - if (pbch_llr != NULL) { - for (i=0; i<1920;i++) { - llr_pbch[i] = (float) pbch_llr[i]; - bit_pbch[i] = (float) i; + + // other tx antennas + if (nb_antennas_tx > 1) { + if (nb_antennas_rx > 1) { + for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } } - fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","",""); + } else { // 1 rx antenna + atx=1; + arx=0; + fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } } - // PBCH I/Q of MF Output - if (pbch_comp!=NULL) { - for (i=0; i<72*2; i++) { - I[i] = pbch_comp[2*i]; - Q[i] = pbch_comp[2*i+1]; - } - fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","",""); - } - // PDCCH LLRs - if (pdcch_llr != NULL) { - for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) { - llr_pdcch[i] = (float) pdcch_llr[i]; - bit_pdcch[i] = (float) i; - } - fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); - fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); - } - // PDCCH I/Q of MF Output - if (pdcch_comp!=NULL) { - for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) { - I[i] = pdcch_comp[2*i]; - Q[i] = pdcch_comp[2*i+1]; - } - fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); - } - */ - // PDSCH LLRs CW0 - if (pdsch_llr != NULL) { - for (i=0; ipdsch_llr,0,coded_bits_per_codeword0); - fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","",""); + } + + /* + // PBCH LLRs + if (pbch_llr != NULL) { + for (i=0; i<1920;i++) { + llr_pbch[i] = (float) pbch_llr[i]; + bit_pbch[i] = (float) i; + } + fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","",""); + } + // PBCH I/Q of MF Output + if (pbch_comp!=NULL) { + for (i=0; i<72*2; i++) { + I[i] = pbch_comp[2*i]; + Q[i] = pbch_comp[2*i+1]; + } + fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","",""); + } + // PDCCH LLRs + if (pdcch_llr != NULL) { + for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) { + llr_pdcch[i] = (float) pdcch_llr[i]; + bit_pdcch[i] = (float) i; + } + fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); + fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + } + // PDCCH I/Q of MF Output + if (pdcch_comp!=NULL) { + for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) { + I[i] = pdcch_comp[2*i]; + Q[i] = pdcch_comp[2*i+1]; + } + fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); + } + */ + // PDSCH LLRs CW0 + if (pdsch_llr != NULL) { + for (i=0; ipdsch_llr,0,coded_bits_per_codeword0); + fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","",""); + } + // PDSCH I/Q of MF Output - if (pdsch_comp!=NULL) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { - I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i]; - Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; - ind++; - } - } - fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","",""); + if (pdsch_comp!=NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i]; + Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + ind++; + } } - if (pdsch_mag0 != NULL) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + + fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","",""); + } + + if (pdsch_mag0 != NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { I[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); Q[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); ind++; - } - } - fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN); + } } - if (pdsch_magb0 != NULL) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + + fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN); + } + + if (pdsch_magb0 != NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { I[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); Q[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); ind++; - } - } - fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED); + } } - if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + + fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED); + } + + if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { I[ind] = - (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+ - pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])* - cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+ + pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])* + cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); Q[ind] = - (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ - pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* - sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ + pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* + sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); ind++; - } - } - fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE); + } } - // PDSCH LLRs CW1 - if (pdsch_llr1 != NULL) { - for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1); - fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","",""); + + fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE); + } + + // PDSCH LLRs CW1 + if (pdsch_llr1 != NULL) { + for (i=0; isymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { - I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i]; - Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; - ind++; - } - } - fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","",""); + + fl_set_xyplot_xbounds(form->pdsch_llr1,0,coded_bits_per_codeword1); + fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","",""); + } + + // PDSCH I/Q of MF Output + if (pdsch_comp1!=NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i]; + Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + ind++; + } } - if (pdsch_mag1 != NULL) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + + fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","",""); + } + + if (pdsch_mag1 != NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { I[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); Q[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); ind++; - } - } - fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN); + } } - if (pdsch_magb1 != NULL) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + + fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN); + } + + if (pdsch_magb1 != NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { I[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); Q[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); ind++; - } - } - fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED); + } } - if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) { - ind=0; - for (k=0; ksymbols_per_tti; k++) { - for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + + fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED); + } + + if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { I[ind] = - (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+ - pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])* - cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+ + pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])* + cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); Q[ind] = - (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ - pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* - sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ + pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* + sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); ind++; - } - } - fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE); + } } - /* - // PDSCH Throughput - memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); - memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); - tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; - tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; - if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) { - tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1]; - } - fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); - fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); - */ - fl_unfreeze_form(form->lte_phy_scope_ue); - fl_check_forms(); - free(I); - free(Q); - free(chest_f_abs); - free(llr0); - free(bit0); - free(llr1); - free(bit1); - free(bit_pdcch); - free(llr_pdcch); - //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0 - /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){ - for (int i = 0; i<8; ++i) - for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j ) - phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0; + fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE); + } - for (int m=0; mpdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0; - }*/ + /* + // PDSCH Throughput + memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); + memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); + tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; + tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; + if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) { + tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1]; + } + fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); + fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); + */ + fl_unfreeze_form(form->lte_phy_scope_ue); + fl_check_forms(); + free(I); + free(Q); + free(chest_f_abs); + free(llr0); + free(bit0); + free(llr1); + free(bit1); + free(bit_pdcch); + free(llr_pdcch); + //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0 + /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){ + for (int i = 0; i<8; ++i) + for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j ) + phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0; + + for (int m=0; mpdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0; + }*/ } diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index b45c1abf0b..90a252dc98 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -38,10 +38,7 @@ int otg_enabled; const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW}; const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED}; -typedef struct { - int16_t r; - int16_t i; -} scopeSample_t; +typedef struct complex16 scopeSample_t; #define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i) typedef struct OAIgraph { @@ -59,7 +56,7 @@ typedef struct OAIgraph { double *waterFallAvg; boolean_t initDone; int iteration; - void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id); + void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id); void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id); } OAIgraph_t; @@ -135,7 +132,7 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_ graph->iteration=0; } -static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id), +static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, scopeData_t *p, int UE_id), int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { OAIgraph_t graph; commonGraph(&graph, type, x, y, w, h, label, pointColor); @@ -226,7 +223,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { if ( values == NULL ) - return; + return; + fl_winset(FL_ObjWin(graph->graph)); const int samplesPerPixel=datasize/graph->w; int displayPart=graph->waterFallh-ScaleZone; @@ -242,7 +240,7 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in for (int pix=0; pixw; pix++) { scopeSample_t *end=values+(pix+1)*samplesPerPixel; end-=2; - AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize); + AssertFatal(end <= values+datasize,"diff : %u", end-values+datasize); double val=0; for (scopeSample_t *s=values+(pix)*samplesPerPixel; @@ -278,7 +276,7 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in graph->initDone=true; } - fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg)); + fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, 0/*sqrt(avg)*/); graph->iteration++; } @@ -297,10 +295,10 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc } } -static void gNBWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { - NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms; +static void gNBWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { + NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms; //use 1st antenna - genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0], + genericWaterFall(graph, (scopeSample_t *)p->ru->common.rxdata[0], frame_parms->samples_per_frame, frame_parms->slots_per_frame, "X axis:one frame in time"); } @@ -318,31 +316,35 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy } */ -static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { - const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size; +static void timeResponse (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { + const int len=2*p->gNB->frame_parms.ofdm_symbol_size; float *values, *time; oai_xygraph_getbuff(graph, &time, &values, len, 0); const int ant=0; // display antenna 0 for each UE for (int ue=0; uepusch_vars[ue]->ul_ch_estimates_time[ant]; + if ( p->gNB->pusch_vars && p->gNB->pusch_vars[ue] && + p->gNB->pusch_vars[ue]->ul_ch_estimates_time && + p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant] ) { + scopeSample_t *data= (scopeSample_t *)p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant]; - if (data != NULL) { - for (int i=0; iframe_parms; +static void gNBfreqWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { + NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms; //use 1st antenna - genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP, + genericWaterFall(graph, (scopeSample_t *)p->rxdataF, frame_parms->samples_per_frame_wCP, frame_parms->slots_per_frame, - "X axis: Frequency domain, one frame"); + "X axis: Frequency domain, one subframe"); } /* @@ -354,16 +356,18 @@ static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU } */ -static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { +static void puschLLR (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { //int Qm = 2; int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti; for (int ue=0; uepusch_vars[ue]->llr; - float *llr, *bit; - oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue); + if ( p->gNB->pusch_vars && + p->gNB->pusch_vars[ue] && + p->gNB->pusch_vars[ue]->llr ) { + int16_t *pusch_llr = (int16_t *)p->gNB->pusch_vars[ue]->llr; + float *llr, *bit; + oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue); - if (pusch_llr) { for (int i=0; iframe_parms; +static void puschIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { + NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms; int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot; for (int ue=0; uepusch_vars[ue]->rxdataF_comp[0]; - float *I, *Q; - oai_xygraph_getbuff(graph, &I, &Q, sz, ue); + if ( p->gNB->pusch_vars && + p->gNB->pusch_vars[ue] && + p->gNB->pusch_vars[ue]->rxdataF_comp && + p->gNB->pusch_vars[ue]->rxdataF_comp[0] ) { + scopeSample_t *pusch_comp = (scopeSample_t *) p->gNB->pusch_vars[ue]->rxdataF_comp[0]; + float *I, *Q; + oai_xygraph_getbuff(graph, &I, &Q, sz, ue); - if (pusch_comp) { for (int k=0; kpucch1ab_stats[UE_id]; @@ -419,10 +426,10 @@ static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *ph */ } -static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { +static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { } -static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { +static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { // PUSCH Throughput /* float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; @@ -437,7 +444,6 @@ static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_ // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax); */ } - static OAI_phy_scope_t *create_phy_scope_gnb(void) { FL_OBJECT *obj; OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1); @@ -486,11 +492,9 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) { fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB"); return fdui; } - static const int scope_enb_num_ue = 1; void phy_scope_gNB(OAI_phy_scope_t *form, - PHY_VARS_gNB *phy_vars_gnb, - RU_t *phy_vars_ru, + scopeData_t *p, int UE_id) { static OAI_phy_scope_t *rememberForm=NULL; @@ -505,15 +509,14 @@ void phy_scope_gNB(OAI_phy_scope_t *form, int i=0; while (form->graph[i].graph) { - form->graph[i].gNBfunct(form->graph+i, phy_vars_gnb, phy_vars_ru, UE_id); + form->graph[i].gNBfunct(form->graph+i, p, UE_id); i++; } //fl_check_forms(); } - static void *scope_thread_gNB(void *arg) { - scopeParms_t *p=(scopeParms_t *) arg; + scopeData_t *p=(scopeData_t *) arg; //# ifdef ENABLE_XFORMS_WRITE_STATS // FILE *gNB_stats = fopen("gNB_stats.txt", "w"); //#endif @@ -530,20 +533,31 @@ static void *scope_thread_gNB(void *arg) { OAI_phy_scope_t *form_gnb = create_phy_scope_gnb(); while (!oai_exit) { - phy_scope_gNB(form_gnb, p->gNB, p->ru, nb_ue); + phy_scope_gNB(form_gnb, p, nb_ue); usleep(99*1000); } return NULL; } - -void gNBinitScope(scopeParms_t *p) { - static scopeParms_t parms; - memcpy(&parms,p,sizeof(parms)); - pthread_t forms_thread; - threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW); +static void copyRxdataF(int32_t *data, int slot, void *scopeData) { + scopeData_t *scope=(scopeData_t *)scopeData; + memcpy(scope->rxdataF + slot*scope->gNB->frame_parms.samples_per_slot_wCP, + data, + scope->gNB->frame_parms.samples_per_slot_wCP); } +void gNBinitScope(scopeParms_t *p) { + AssertFatal(p->gNB->scopeData=malloc(sizeof(scopeData_t)),""); + scopeData_t *scope=(scopeData_t *) p->gNB->scopeData; + scope->argc=p->argc; + scope->argv=p->argv; + scope->ru=p->ru; + scope->gNB=p->gNB; + scope->slotFunc=copyRxdataF; + AssertFatal(scope->rxdataF=(int32_t *) calloc(p->gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t),1),""); + pthread_t forms_thread; + threadCreate(&forms_thread, scope_thread_gNB, p->gNB->scopeData, "scope", -1, OAI_PRIORITY_RT_LOW); +} static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Received signal in time domain of receive antenna 0 genericWaterFall(graph, @@ -552,7 +566,6 @@ static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eN phy_vars_ue->frame_parms.slots_per_frame, "X axis: one frame time"); } - /* replaced by waterfall static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Received signal in time domain of receive antenna 0 @@ -561,14 +574,12 @@ static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int phy_vars_ue->frame_parms.samples_per_frame); } */ - static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Channel Impulse Response genericPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx, (const scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time, phy_vars_ue->frame_parms.ofdm_symbol_size>>3); } - static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) { NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms; //use 1st antenna @@ -578,7 +589,6 @@ static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int phy_vars_ue->frame_parms.slots_per_frame, "X axis: one frame frequency" ); } - /* static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Channel Frequency Response (includes 5 complex sample for filter) @@ -614,7 +624,6 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10); } */ - static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PBCH LLRs if ( !phy_vars_ue->pbch_vars[eNB_id]->llr) @@ -630,7 +639,6 @@ static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10); } - static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PBCH I/Q of MF Output if (!phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]) @@ -665,15 +673,14 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i AssertFatal(base <= 180*3,""); oai_xygraph(graph,I,Q,base,0, 10); } - static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PDCCH LLRs if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr) return; - int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols - int Qm = 2; - int coded_bits_per_codeword = num_re*Qm; + //int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols + //int Qm = 2; + int coded_bits_per_codeword = 2*4*100*12; //num_re*Qm; float *llr, *bit; oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0); int base=0; @@ -691,7 +698,6 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, ""); oai_xygraph(graph,bit,llr,base,0,10); } - static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PDCCH I/Q of MF Output if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0]) @@ -716,7 +722,6 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i AssertFatal(base <= nb*RX_NB_TH_MAX, ""); oai_xygraph(graph,I,Q,base,0,10); } - static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PDSCH LLRs if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0]) @@ -744,7 +749,6 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB //fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); oai_xygraph(graph,bit,llr,base,0,10); } - static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PDSCH I/Q of MF Output if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0]) @@ -772,7 +776,6 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ AssertFatal(base <= sz*RX_NB_TH_MAX, ""); oai_xygraph(graph,I,Q,sz*RX_NB_TH_MAX,0,10); } - static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { /* float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; @@ -796,7 +799,6 @@ static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); */ } - static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) { FL_OBJECT *obj; OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1); @@ -866,7 +868,6 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) { fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, buf); return fdui; } - void phy_scope_nrUE(OAI_phy_scope_t *form, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, @@ -890,8 +891,6 @@ void phy_scope_nrUE(OAI_phy_scope_t *form, //fl_check_forms(); } - - static void *nrUEscopeThread(void *arg) { PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg; size_t stksize; @@ -915,13 +914,10 @@ static void *nrUEscopeThread(void *arg) { pthread_exit((void *)arg); } - void nrUEinitScope(PHY_VARS_NR_UE *ue) { pthread_t forms_thread; threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW); } - - void nrscope_autoinit(void *dataptr) { AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context"); @@ -956,7 +952,6 @@ static void reset_stats_gNB(FL_OBJECT *button, } } } - static FD_stats_form *create_form_stats_form(int ID) { FL_OBJECT *obj; FD_stats_form *fdui = calloc(( sizeof *fdui ),1); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h index 84b9e66908..e34ddf2c20 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.h +++ b/openair1/PHY/TOOLS/nr_phy_scope.h @@ -33,13 +33,7 @@ //#include "PHY/impl_defs_top.h" #include "PHY/defs_nr_UE.h" -typedef struct { - int *argc; - char **argv; - RU_t *ru; - PHY_VARS_gNB *gNB; -} scopeParms_t; - +#include extern RAN_CONTEXT_t RC; #endif diff --git a/openair1/PHY/TOOLS/phy_scope_interface.c b/openair1/PHY/TOOLS/phy_scope_interface.c index af237b2325..7cd68c53d2 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.c +++ b/openair1/PHY/TOOLS/phy_scope_interface.c @@ -35,6 +35,7 @@ #include "phy_scope_interface.h" #define SOFTSCOPE_ENDFUNC_IDX 0 + static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}}; int load_softscope(char *exectype, void *initarg) { diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h index adf04d5ea4..8b747d575d 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.h +++ b/openair1/PHY/TOOLS/phy_scope_interface.h @@ -29,7 +29,26 @@ * \note * \warning */ +#ifndef __PHY_SCOPE_INTERFACE_H__ +#define __PHY_SCOPE_INTERFACE_H__ +#include +typedef struct { + int *argc; + char **argv; + RU_t *ru; + PHY_VARS_gNB *gNB; +} scopeParms_t; +typedef struct scopeData_s { + int *argc; + char **argv; + RU_t *ru; + PHY_VARS_gNB *gNB; + int32_t * rxdataF; + void (*slotFunc)(int32_t* data, int slot, void * scopeData); +} scopeData_t; + int load_softscope(char *exectype, void *initarg); int end_forms(void) ; +#endif diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index cfa3b93007..ef1444572d 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -26,9 +26,12 @@ // global var for openair performance profiler int opp_enabled = 0; +double cpu_freq_GHz __attribute__ ((aligned(32))); +double cpu_freq_GHz __attribute__ ((aligned(32)))=0.0; double get_cpu_freq_GHz(void) { + if (cpu_freq_GHz <1 ) { time_stats_t ts = {0}; reset_meas(&ts); ts.trials++; @@ -37,6 +40,7 @@ double get_cpu_freq_GHz(void) ts.diff = (rdtsc_oai()-ts.in); cpu_freq_GHz = (double)ts.diff/1000000000; printf("CPU Freq is %f \n", cpu_freq_GHz); + } return cpu_freq_GHz; } diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index 2deab40f27..e2ceef8405 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -33,7 +33,7 @@ #include // global var to enable openair performance profiler extern int opp_enabled; -double cpu_freq_GHz __attribute__ ((aligned(32)));; +extern double cpu_freq_GHz __attribute__ ((aligned(32)));; #if defined(__x86_64__) || defined(__i386__) typedef struct { diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index db7ac3d813..4c68c15cb6 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -44,6 +44,11 @@ struct complex { double y; }; +struct complexd { + double r; + double i; +}; + struct complexf { float r; float i; diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 27765a8548..1a8016054a 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -867,8 +867,9 @@ typedef enum { NOT_SYNCHED=0, PRACH=1, RA_RESPONSE=2, - PUSCH=3, - RESYNCH=4 + RA_WAIT_CR=3, + PUSCH=4, + RESYNCH=5 } UE_MODE_t; #define FOREACH_PARALLEL(GEN) \ diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 2f6c4324b0..a165aa1984 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -664,6 +664,7 @@ typedef struct { int prach_I0; } PHY_MEASUREMENTS_gNB; +#define MAX_NUM_NR_PRACH_PREAMBLES 64 #define MAX_NUM_NR_RX_RACH_PDUS 4 #define MAX_NUM_NR_RX_PRACH_PREAMBLES 4 #define MAX_UL_PDUS_PER_SLOT 8 @@ -846,7 +847,7 @@ typedef struct PHY_VARS_gNB_s { tpool_t *threadPool; int nbDecode; uint8_t pusch_proc_threads; - + void * scopeData; } PHY_VARS_gNB; typedef struct LDPCDecode_s { diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index ceb75c2554..fad578c8b0 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -214,10 +214,8 @@ typedef enum { #define NB_SRS_PERIOD (17) -const uint16_t srs_period[NB_SRS_PERIOD] -#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H +static const uint16_t srs_period[NB_SRS_PERIOD] = { 1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560} -#endif ; /// SRS_Resource of SRS_Config information element from 38.331 RRC specifications @@ -796,7 +794,6 @@ typedef struct { uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT]; } initial_pucch_resource_t; -const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE]; /* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */ /* structure with all possible fields for pucch format from 0 to 4 */ typedef struct { @@ -1051,11 +1048,6 @@ typedef struct { #define NB_SR_PERIOD (15) -const uint16_t scheduling_request_periodicity[NB_SR_PERIOD] -#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H -= { 0, 0, 1, 2, 4, 5, 8, 10, 16, 20, 40, 80, 160, 320, 640 } -#endif -; typedef enum { sr_sym2 = 0, diff --git a/openair1/PHY/phy_extern.h b/openair1/PHY/phy_extern.h index 165ed961b3..4ba5e328e3 100644 --- a/openair1/PHY/phy_extern.h +++ b/openair1/PHY/phy_extern.h @@ -48,12 +48,6 @@ extern short primary_synch2[144]; extern unsigned char primary_synch0_tab[72]; extern unsigned char primary_synch1_tab[72]; extern unsigned char primary_synch2_tab[72]; -extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[ -extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[ -extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[ -extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[ -extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[ -extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[ extern int flagMag; //extern short **txdataF_rep_tmp; diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h index 700419c61c..f1704a7902 100644 --- a/openair1/PHY/phy_extern_nr_ue.h +++ b/openair1/PHY/phy_extern_nr_ue.h @@ -55,9 +55,6 @@ extern unsigned char primary_synch2_tab[72]; extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[ extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[ extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[ -extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[ -extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[ -extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[ extern int flagMag; //extern short **txdataF_rep_tmp; diff --git a/openair1/PHY/phy_extern_ue.h b/openair1/PHY/phy_extern_ue.h index 622551c2fe..fdaf6eaa89 100644 --- a/openair1/PHY/phy_extern_ue.h +++ b/openair1/PHY/phy_extern_ue.h @@ -47,12 +47,6 @@ extern short primary_synch2[144]; extern unsigned char primary_synch0_tab[72]; extern unsigned char primary_synch1_tab[72]; extern unsigned char primary_synch2_tab[72]; -extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[ -extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[ -extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[ -extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[ -extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[ -extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[ extern int flagMag; //extern short **txdataF_rep_tmp; diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h index 5e2be8bd8f..dadb1649ec 100644 --- a/openair1/PHY/phy_vars.h +++ b/openair1/PHY/phy_vars.h @@ -33,9 +33,6 @@ char* namepointer_log2; #include "PHY/LTE_REFSIG/primary_synch.h" -int16_t *primary_synch0_time; -int16_t *primary_synch1_time; -int16_t *primary_synch2_time; #include "PHY/LTE_TRANSPORT/transport_vars.h" diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h index e90c2641aa..469a5c4754 100644 --- a/openair1/PHY/phy_vars_ue.h +++ b/openair1/PHY/phy_vars_ue.h @@ -33,9 +33,6 @@ char *namepointer_log2; #include "PHY/LTE_REFSIG/primary_synch.h" -int16_t *primary_synch0_time; -int16_t *primary_synch1_time; -int16_t *primary_synch2_time; PHY_VARS_UE ***PHY_vars_UE_g; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 38307a7b9e..d894061acd 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -40,6 +40,7 @@ #include "common/utils/LOG/log.h" #include #include "common/utils/LOG/vcd_signal_dumper.h" +#include #include "assertions.h" #include "msc.h" @@ -51,7 +52,6 @@ #define MBMS_NFAPI_SCHEDULER -nfapi_ue_release_request_body_t release_rntis; int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) { uint32_t Nre,sumKr,MPR_x100,Kr,r; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index e70c353589..54464446a5 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -84,6 +84,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ } else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0]; + dlsch0->rnti_type = _RA_RNTI_; + dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE; } else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0]; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index df66217e49..60fe897456 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -234,7 +234,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling; - LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", + LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", __FUNCTION__, ue->Mod_id, frame_tx, @@ -771,6 +771,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ uint16_t pdsch_nb_rb = dlsch0_harq->nb_rb; uint16_t s0 = dlsch0_harq->start_symbol; uint16_t s1 = dlsch0_harq->nb_symbols; + bool is_SI = dlsch0->rnti_type == _SI_RNTI_; LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); @@ -780,6 +781,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ nr_pdsch_channel_estimation(ue, proc, 0 /*eNB_id*/, + is_SI, nr_slot_rx, aatx /*p*/, m, @@ -1134,7 +1136,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS); } - LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_slot_rx); + LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ decoded in %d \n", frame_rx, nr_slot_rx, ret); LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS); if(retmax_ldpc_iterations+1){ @@ -1690,9 +1692,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } if ((frame_rx%64 == 0) && (nr_slot_rx==0)) { - printf("============================================\n"); + LOG_I(PHY,"============================================\n"); LOG_I(PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]); - printf("============================================\n"); + LOG_I(PHY,"============================================\n"); } #ifdef NR_PDCCH_SCHED @@ -2068,7 +2070,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t } - if (nr_prach == 1) { + if (nr_prach == GENERATE_PREAMBLE) { if (ue->mac_enabled == 1) { int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); @@ -2114,18 +2116,15 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t if (ue->mac_enabled == 1) nr_Msg1_transmitted(mod_id, ue->CC_id, frame_tx, gNB_id); - } else if (nr_prach == 2) { - + } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) { + LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id); + ue->UE_mode[gNB_id] = RA_WAIT_CR; + } else if (nr_prach == RA_SUCCEEDED) { LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id); - ue->UE_mode[gNB_id] = PUSCH; - - } else if(nr_prach == 3){ - + } else if(nr_prach == RA_FAILED){ LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id); - ue->UE_mode[gNB_id] = PRACH; - } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index edb070f873..0455c481d5 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -40,6 +40,7 @@ #include #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h" +#include #ifndef NO_RAT_NR @@ -54,10 +55,172 @@ #endif +/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */ +static const int sequence_cyclic_shift_1_harq_ack_bit[2] +/* HARQ-ACK Value 0 1 */ +/* Sequence cyclic shift */ = { 0, 6 } +; + +/* TS 36.213 Table 9.2.5-2: Mapping of values for two HARQ-ACK bits and positive SR to sequences */ +static const int sequence_cyclic_shift_2_harq_ack_bits_positive_sr[4] +/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */ +/* Sequence cyclic shift */ = { 1, 4, 10, 7 } +; + uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); +static const uint16_t scheduling_request_periodicity[NB_SR_PERIOD] += { 0, 0, 1, 2, 4, 5, 8, 10, 16, 20, 40, 80, 160, 320, 640 } +; + +/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */ +/* this is a counter of number of pucch format 4 per subframe */ +static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = { 0 } ; + +/* TS 36.213 Table 9.2.5.2-1: Code rate corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */ +/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */ +/* add one additional element set to 0 for parsing the array until this end */ +/* stored values are code rates * 100 */ +//static const int code_rate_r_time_100[8] = { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 } ; + +/* TS 38.213 Table 9.2.3-4: Mapping of values for two HARQ-ACK bits to sequences */ +static const int sequence_cyclic_shift_2_harq_ack_bits[4] +/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */ +/* Sequence cyclic shift */ = { 0, 3, 9, 6 } +; + +/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */ +static const int nb_symbols_excluding_dmrs[NB_SYMBOL_MINUS_FOUR][2][2] += { +/* No additional DMRS Additional DMRS */ +/* PUCCH length No hopping hopping No hopping hopping */ +/* index 0 1 0 1 */ +/* 4 */ {{ 3 , 2 } , { 3 , 2 }}, +/* 5 */ {{ 3 , 3 } , { 3 , 3 }}, +/* 6 */ {{ 4 , 4 } , { 4 , 4 }}, +/* 7 */ {{ 5 , 5 } , { 5 , 5 }}, +/* 8 */ {{ 6 , 6 } , { 6 , 6 }}, +/* 9 */ {{ 7 , 7 } , { 7 , 7 }}, +/* 10 */ {{ 8 , 8 } , { 6 , 6 }}, +/* 11 */ {{ 9 , 9 } , { 7 , 7 }}, +/* 12 */ {{ 10 , 10 } , { 8 , 8 }}, +/* 13 */ {{ 11 , 11 } , { 9 , 9 }}, +/* 14 */ {{ 12 , 12 } , { 10 , 10 }}, +} +; + + +/* TS 36.213 Table 9.2.5-1: Mapping of values for one HARQ-ACK bit and positive SR to sequences */ +static const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2] +/* HARQ-ACK Value 0 1 */ +/* Sequence cyclic shift */ = { 3, 9 } +; + +static float RSRP_meas_mapping_nr[98] += { + -140, + -139, + -138, + -137, + -136, + -135, + -134, + -133, + -132, + -131, + -130, + -129, + -128, + -127, + -126, + -125, + -124, + -123, + -122, + -121, + -120, + -119, + -118, + -117, + -116, + -115, + -114, + -113, + -112, + -111, + -110, + -109, + -108, + -107, + -106, + -105, + -104, + -103, + -102, + -101, + -100, + -99, + -98, + -97, + -96, + -95, + -94, + -93, + -92, + -91, + -90, + -89, + -88, + -87, + -86, + -85, + -84, + -83, + -82, + -81, + -80, + -79, + -78, + -77, + -76, + -75, + -74, + -73, + -72, + -71, + -70, + -69, + -68, + -67, + -66, + -65, + -64, + -63, + -62, + -61, + -60, + -59, + -58, + -57, + -56, + -55, + -54, + -53, + -52, + -51, + -50, + -49, + -48, + -47, + -46, + -45, + -44, + -43 + } + ; + long binary_search_float_nr( float elements[], @@ -202,6 +365,30 @@ void nr_generate_pucch3_4(int32_t **txdataF, * *********************************************************************/ +/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */ +const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE] += +{ +/* format first symbol Number of symbols PRB offset nb index for set of initial CS */ +/* 0 */ { pucch_format0_nr, 12, 2, 0, 2, { 0, 3, 0, 0 } }, +/* 1 */ { pucch_format0_nr, 12, 2, 0, 3, { 0, 4, 8, 0 } }, +/* 2 */ { pucch_format0_nr, 12, 2, 3, 3, { 0, 4, 8, 0 } }, +/* 3 */ { pucch_format1_nr, 10, 4, 0, 2, { 0, 6, 0, 0 } }, +/* 4 */ { pucch_format1_nr, 10, 4, 0, 4, { 0, 3, 6, 9 } }, +/* 5 */ { pucch_format1_nr, 10, 4, 2, 4, { 0, 3, 6, 9 } }, +/* 6 */ { pucch_format1_nr, 10, 4, 4, 4, { 0, 3, 6, 9 } }, +/* 7 */ { pucch_format1_nr, 4, 10, 0, 2, { 0, 6, 0, 0 } }, +/* 8 */ { pucch_format1_nr, 4, 10, 0, 4, { 0, 3, 6, 9 } }, +/* 9 */ { pucch_format1_nr, 4, 10, 2, 4, { 0, 3, 6, 9 } }, +/* 10 */ { pucch_format1_nr, 4, 10, 4, 4, { 0, 3, 6, 9 } }, +/* 11 */ { pucch_format1_nr, 0, 14, 0, 2, { 0, 6, 0, 0 } }, +/* 12 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } }, +/* 13 */ { pucch_format1_nr, 0, 14, 2, 4, { 0, 3, 6, 9 } }, +/* 14 */ { pucch_format1_nr, 0, 14, 4, 4, { 0, 3, 6, 9 } }, +/* 15 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } }, +} +; + bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq) { uint8_t sr_payload = 0; @@ -788,7 +975,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); } else if (harq_status->send_harq_status == 0) { - LOG_D(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); + LOG_E(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); } else { diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h index 9b53331f50..97d8d73282 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h @@ -60,214 +60,12 @@ /************** VARIABLES *****************************************/ -float RSRP_meas_mapping_nr[98] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -= { - -140, - -139, - -138, - -137, - -136, - -135, - -134, - -133, - -132, - -131, - -130, - -129, - -128, - -127, - -126, - -125, - -124, - -123, - -122, - -121, - -120, - -119, - -118, - -117, - -116, - -115, - -114, - -113, - -112, - -111, - -110, - -109, - -108, - -107, - -106, - -105, - -104, - -103, - -102, - -101, - -100, - -99, - -98, - -97, - -96, - -95, - -94, - -93, - -92, - -91, - -90, - -89, - -88, - -87, - -86, - -85, - -84, - -83, - -82, - -81, - -80, - -79, - -78, - -77, - -76, - -75, - -74, - -73, - -72, - -71, - -70, - -69, - -68, - -67, - -66, - -65, - -64, - -63, - -62, - -61, - -60, - -59, - -58, - -57, - -56, - -55, - -54, - -53, - -52, - -51, - -50, - -49, - -48, - -47, - -46, - -45, - -44, - -43 - } - #endif - ; - -/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */ -const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -= -{ -/* format first symbol Number of symbols PRB offset nb index for set of initial CS */ -/* 0 */ { pucch_format0_nr, 12, 2, 0, 2, { 0, 3, 0, 0 } }, -/* 1 */ { pucch_format0_nr, 12, 2, 0, 3, { 0, 4, 8, 0 } }, -/* 2 */ { pucch_format0_nr, 12, 2, 3, 3, { 0, 4, 8, 0 } }, -/* 3 */ { pucch_format1_nr, 10, 4, 0, 2, { 0, 6, 0, 0 } }, -/* 4 */ { pucch_format1_nr, 10, 4, 0, 4, { 0, 3, 6, 9 } }, -/* 5 */ { pucch_format1_nr, 10, 4, 2, 4, { 0, 3, 6, 9 } }, -/* 6 */ { pucch_format1_nr, 10, 4, 4, 4, { 0, 3, 6, 9 } }, -/* 7 */ { pucch_format1_nr, 4, 10, 0, 2, { 0, 6, 0, 0 } }, -/* 8 */ { pucch_format1_nr, 4, 10, 0, 4, { 0, 3, 6, 9 } }, -/* 9 */ { pucch_format1_nr, 4, 10, 2, 4, { 0, 3, 6, 9 } }, -/* 10 */ { pucch_format1_nr, 4, 10, 4, 4, { 0, 3, 6, 9 } }, -/* 11 */ { pucch_format1_nr, 0, 14, 0, 2, { 0, 6, 0, 0 } }, -/* 12 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } }, -/* 13 */ { pucch_format1_nr, 0, 14, 2, 4, { 0, 3, 6, 9 } }, -/* 14 */ { pucch_format1_nr, 0, 14, 4, 4, { 0, 3, 6, 9 } }, -/* 15 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } }, -} -#endif -; - -/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */ -const int sequence_cyclic_shift_1_harq_ack_bit[2] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -/* HARQ-ACK Value 0 1 */ -/* Sequence cyclic shift */ = { 0, 6 } -#endif -; - -/* TS 38.213 Table 9.2.3-4: Mapping of values for two HARQ-ACK bits to sequences */ -const int sequence_cyclic_shift_2_harq_ack_bits[4] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */ -/* Sequence cyclic shift */ = { 0, 3, 9, 6 } -#endif -; - -/* TS 36.213 Table 9.2.5-1: Mapping of values for one HARQ-ACK bit and positive SR to sequences */ -const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -/* HARQ-ACK Value 0 1 */ -/* Sequence cyclic shift */ = { 3, 9 } -#endif -; - -/* TS 36.213 Table 9.2.5-2: Mapping of values for two HARQ-ACK bits and positive SR to sequences */ -const int sequence_cyclic_shift_2_harq_ack_bits_positive_sr[4] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */ -/* Sequence cyclic shift */ = { 1, 4, 10, 7 } -#endif -; - -/* TS 36.213 Table 9.2.5.2-1: Code rate corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */ -/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */ -/* add one additional element set to 0 for parsing the array until this end */ -/* stored values are code rates * 100 */ -const int code_rate_r_time_100[8] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -= { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 } -#endif -; - #define NB_SYMBOL_MINUS_FOUR (11) #define I_PUCCH_NO_ADDITIONAL_DMRS (0) #define I_PUCCH_ADDITIONAL_DMRS (1) #define I_PUCCH_NO_HOPPING (0) #define I_PUCCH_HOPING (1) -/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */ -const int nb_symbols_excluding_dmrs[NB_SYMBOL_MINUS_FOUR][2][2] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -= { -/* No additional DMRS Additional DMRS */ -/* PUCCH length No hopping hopping No hopping hopping */ -/* index 0 1 0 1 */ -/* 4 */ {{ 3 , 2 } , { 3 , 2 }}, -/* 5 */ {{ 3 , 3 } , { 3 , 3 }}, -/* 6 */ {{ 4 , 4 } , { 4 , 4 }}, -/* 7 */ {{ 5 , 5 } , { 5 , 5 }}, -/* 8 */ {{ 6 , 6 } , { 6 , 6 }}, -/* 9 */ {{ 7 , 7 } , { 7 , 7 }}, -/* 10 */ {{ 8 , 8 } , { 6 , 6 }}, -/* 11 */ {{ 9 , 9 } , { 7 , 7 }}, -/* 12 */ {{ 10 , 10 } , { 8 , 8 }}, -/* 13 */ {{ 11 , 11 } , { 9 , 9 }}, -/* 14 */ {{ 12 , 12 } , { 10 , 10 }}, -} -#endif -; - -/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */ -/* this is a counter of number of pucch format 4 per subframe */ -int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] -#ifdef INIT_VARIABLES_PUCCH_UE_NR_H -= { 0 } -#endif -; /*************** FUNCTIONS ****************************************/ diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h index 796a576aed..5e0be3de89 100644 --- a/openair1/SIMULATION/LTE_PHY/common_sim.h +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -46,13 +46,13 @@ void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastAc } double squareRoot(time_stats_t *ptr) { - double timeBase=1/(1000*cpu_freq_GHz); + double timeBase=1/(1000*get_cpu_freq_GHz()); return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - pow((double)ptr->diff/ptr->trials*timeBase,2)); } void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { - double timeBase=1/(1000*cpu_freq_GHz); + double timeBase=1/(1000*get_cpu_freq_GHz()); printf("%-43s %6.2f us (%d trials)\n", txt, (double)ptr->diff/ptr->trials*timeBase, @@ -69,7 +69,7 @@ void printStatIndent(time_stats_t *ptr, char *txt) { } void printStatIndent2(time_stats_t *ptr, char *txt) { - double timeBase=1/(1000*cpu_freq_GHz); + double timeBase=1/(1000*get_cpu_freq_GHz()); printf(" |__ %-34s %6.2f us (%3d trials)\n", txt, ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, @@ -77,7 +77,7 @@ void printStatIndent2(time_stats_t *ptr, char *txt) { } void printStatIndent3(time_stats_t *ptr, char *txt) { - double timeBase=1/(1000*cpu_freq_GHz); + double timeBase=1/(1000*get_cpu_freq_GHz()); printf(" |__ %-30s %6.2f us (%3d trials)\n", txt, ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 667913d377..8955454282 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -65,11 +65,14 @@ void feptx_ofdm(RU_t *ru, int frame, int subframe); void feptx_prec(RU_t *ru, int frame, int subframe); double cpuf; -#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) //#define MCS_COUNT 23//added for PHY abstraction #include int otg_enabled=0; +THREAD_STRUCT thread_struct; +nfapi_ue_release_request_body_t release_rntis; + /*the following parameters are used to control the processing times calculations*/ double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */ double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */ @@ -1179,7 +1182,7 @@ int main(int argc, char **argv) { DS_TDL, forgetting_factor, rx_sample_offset, - 0); + 0, 0); reset_meas(&eNB2UE[0]->random_channel); reset_meas(&eNB2UE[0]->interp_time); @@ -1193,7 +1196,7 @@ int main(int argc, char **argv) { DS_TDL, forgetting_factor, rx_sample_offset, - 0); + 0, 0); reset_meas(&eNB2UE[n]->random_channel); reset_meas(&eNB2UE[n]->interp_time); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index a585e8efc6..3b4e6782da 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -988,7 +988,7 @@ int main(int argc, char **argv) N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, - 0); + 0, 0); if(num_rounds>1) { for(n=1; n<8; n++) @@ -999,7 +999,7 @@ int main(int argc, char **argv) N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, - 0); + 0, 0); } if (eNB2UE[0]==NULL) { diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 5973f80b55..bd164150c5 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -834,7 +834,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, - 0); + 0, 0); if(num_rounds>1) { for(n=1; n<4; n++) @@ -845,7 +845,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, - 0); + 0, 0); } if (eNB2UE[0]==NULL) { diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index b1f4d933b3..78fd1a293e 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -1290,7 +1290,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, - 0); + 0, 0); reset_meas(&eNB2UE[0]->random_channel); reset_meas(&eNB2UE[0]->interp_time); @@ -1303,7 +1303,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, - 0); + 0, 0); reset_meas(&eNB2UE[n]->random_channel); reset_meas(&eNB2UE[n]->interp_time); } diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c index 00ad03c52d..71286faafb 100644 --- a/openair1/SIMULATION/LTE_PHY/pbchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c @@ -386,7 +386,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 0, - 0); + 0, 0); if (interf1>-20) eNB2UE1 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, @@ -396,7 +396,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 4, - 0); + 0, 0); if (interf2>-20) eNB2UE2 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, @@ -406,7 +406,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 8, - 0); + 0, 0); if (eNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index 004eb24243..bd2c2d66b9 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -708,7 +708,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 0, - 0); + 0, 0); L1_rxtx_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx; eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c index c997aa7639..229764a893 100644 --- a/openair1/SIMULATION/LTE_PHY/prachsim.c +++ b/openair1/SIMULATION/LTE_PHY/prachsim.c @@ -343,7 +343,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), 0.0, delay, - 0); + 0, 0); if (UE2eNB==NULL) { msg("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index 127bfcb533..083a756afb 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -323,7 +323,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), 0.0, 0, - 0); + 0, 0); if (UE2eNB==NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c index 5ceeee7f2f..839d30a8de 100644 --- a/openair1/SIMULATION/LTE_PHY/scansim.c +++ b/openair1/SIMULATION/LTE_PHY/scansim.c @@ -335,7 +335,7 @@ int main(int argc, char **argv) { N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), 0, 0, - 0); + 0, 0); if (eNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 80598b37e4..e8ee7d3d5e 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -724,7 +724,7 @@ int main(int argc, char **argv) { BW, 0, 0, - 0); + 0, 0); if (interf1>-20) eNB2UE1 = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, @@ -733,7 +733,7 @@ int main(int argc, char **argv) { BW, 0, 0, - 0); + 0, 0); if (interf2>-20) eNB2UE2 = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, @@ -742,7 +742,7 @@ int main(int argc, char **argv) { BW, 0, 0, - 0); + 0, 0); if (eNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 80beee4bed..c6049bc31d 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -57,7 +57,7 @@ #include "executables/split_headers.h" double cpuf; -#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) //#define MCS_COUNT 23//added for PHY abstraction #include channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; @@ -70,6 +70,9 @@ node_desc_t *ue_data[NUMBER_OF_UE_MAX]; extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16]; //extern char* namepointer_chMag ; int xforms=0; +THREAD_STRUCT thread_struct; +nfapi_ue_release_request_body_t release_rntis; + FD_lte_phy_scope_enb *form_enb; char title[255]; @@ -734,7 +737,7 @@ int main(int argc, char **argv) { 30e-9, forgetting_factor, delay, - 0); + 0, 0); // set Doppler UE2eNB->max_Doppler = maxDoppler; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 00983553d8..12b0b1d1f0 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -339,7 +339,7 @@ int main(int argc, char **argv) 61.44e6, //N_RB2sampling_rate(N_RB_DL), 40e6, //N_RB2channel_bandwidth(N_RB_DL), DS_TDL, - 0, 0, 0); + 0, 0, 0, 0); if (gNB2UE == NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 0a7ae96e09..9eff4255f3 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -63,7 +63,7 @@ //#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "NR_RRCReconfiguration.h" -#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" #include @@ -83,16 +83,23 @@ uint16_t sf_ahead=4 ; uint16_t sl_ahead=0; //uint8_t nfapi_mode = 0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; +THREAD_STRUCT thread_struct; +nfapi_ue_release_request_body_t release_rntis; +msc_interface_t msc_interface; + // dummy functions int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } -int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, - const int CC_id, - const uint8_t gNB_index, - const int8_t channel, - const uint8_t* pduP, - const sdu_size_t pdu_len) +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, + const int CC_id, + const uint8_t gNB_index, + const frame_t frame, + const sub_frame_t sub_frame, + const rnti_t rnti, + const channel_t channel, + const uint8_t* pduP, + const sdu_size_t pdu_len) { return 0; } @@ -767,7 +774,7 @@ int main(int argc, char **argv) 30e-9, 0, 0, - 0); + 0, 0); if (gNB2UE==NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ee74909a9e..c75a590603 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -479,7 +479,7 @@ int main(int argc, char **argv) 300e-9, 0, 0, - 0); + 0, 0); if (gNB2UE==NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index efbc40cd55..26c1518188 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -37,6 +37,7 @@ #include "SCHED_NR_UE/phy_frame_config_nr.h" #include "PHY/phy_vars_nr_ue.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/MODULATION/nr_modulation.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/INIT/phy_init.h" @@ -47,6 +48,7 @@ #include "OCG_vars.h" #include #include +#include //#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" @@ -65,10 +67,12 @@ extern uint16_t prach_root_sequence_map0_3[838]; openair0_config_t openair0_cfg[MAX_CARDS]; //uint8_t nfapi_mode=0; uint16_t sl_ahead = 0; +msc_interface_t msc_interface; //void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe); /* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +msc_interface_t msc_interface; uint64_t get_softmodem_optmask(void) {return 0;} softmodem_params_t *get_softmodem_params(void) {return 0;} int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } @@ -130,7 +134,18 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } -int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;} +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, + const int CC_id, + const uint8_t gNB_index, + const frame_t frame, + const sub_frame_t sub_frame, + const rnti_t rnti, + const channel_t channel, + const uint8_t* pduP, + const sdu_size_t pdu_len) +{ + return 0; +} void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) { @@ -165,7 +180,7 @@ int main(int argc, char **argv){ double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs, bw; - int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; + int i, l, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0; uint8_t frame = 1, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; @@ -662,7 +677,7 @@ int main(int argc, char **argv){ DS_TDL, 0.0, delay, - 0); + 0, 0); if (UE2gNB==NULL) { printf("Problem generating channel model. Exiting.\n"); @@ -800,7 +815,17 @@ int main(int argc, char **argv){ } } - + for (l = 0; l < frame_parms->symbols_per_slot; l++) { + for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + nr_slot_fep_ul(frame_parms, + ru->common.rxdata[aa], + ru->common.rxdataF[aa], + l, + slot, + ru->N_TA_offset); + } + } + rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot); gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion]; @@ -823,7 +848,8 @@ int main(int argc, char **argv){ LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1); LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); - LOG_M("ru_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); + LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1); + LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); #endif diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 8d79633a6f..4cef1213c9 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -418,7 +418,7 @@ int main(int argc, char **argv) printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); } - UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0); + UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0, 0); if (UE2gNB==NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 6f2af73a1d..f84e553683 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -364,7 +364,7 @@ int main(int argc, char **argv) 61.44e6, //N_RB2sampling_rate(N_RB_DL), 40e6, //N_RB2channel_bandwidth(N_RB_DL), DS_TDL, - 0,0,0); + 0,0,0, 0); if (gNB2UE == NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index fce690ebd2..21351caac1 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -57,7 +57,7 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/utils/threadPool/thread-pool.h" #include "PHY/NR_REFSIG/ptrs_nr.h" -#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" #include @@ -81,11 +81,25 @@ uint16_t sl_ahead=0; double cpuf; //uint8_t nfapi_mode = 0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; +THREAD_STRUCT thread_struct; +nfapi_ue_release_request_body_t release_rntis; +msc_interface_t msc_interface; extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration -int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, - const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, + const int CC_id, + const uint8_t gNB_index, + const frame_t frame, + const sub_frame_t sub_frame, + const rnti_t rnti, + const channel_t channel, + const uint8_t* pduP, + const sdu_size_t pdu_len) +{ + return 0; +} + int generate_dlsch_header(unsigned char *mac_header, unsigned char num_sdus, unsigned short *sdu_lengths, @@ -593,7 +607,7 @@ int main(int argc, char **argv) sampling_frequency, bandwidth, DS_TDL, - 0, 0, 0); + 0, 0, 0, 0); if (UE2gNB == NULL) { printf("Problem generating channel model. Exiting.\n"); diff --git a/openair1/SIMULATION/TOOLS/DOC/arch.md b/openair1/SIMULATION/TOOLS/DOC/arch.md new file mode 100644 index 0000000000..30be337829 --- /dev/null +++ b/openair1/SIMULATION/TOOLS/DOC/arch.md @@ -0,0 +1,9 @@ +# Channel simulation source files + +1. [random_channel.c](../random_channel.c) +1. [sim.h](../sim.h) + + + +[channel simulation main page](channel_simulation.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file diff --git a/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md new file mode 100644 index 0000000000..be2b987b40 --- /dev/null +++ b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md @@ -0,0 +1,13 @@ +# OAI channel simulation feature + +oai includes a channel simulation feature that any component can use to alter time domain samples of a RF channel by applying pre-defined models as defined, for example, in 3GPP TR 36.873 or TR 38.901 + +Definition, configuration and run-time modification of a channel model are implemented in common code included in UEs, gNb, eNB and used when running with the rfsimulator or the L1 simulator. Phy simulators are also using channel simulation but configuration is done via dedicated command line options. The rfsimulator is the only option to get access to all the configurations and run-time modifications features of oai channel simulation. + +## Documentation + +* [runtime usage](rtusage.md) +* [developer usage](devusage.md) +* [module architecture](arch.md) + +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/openair1/SIMULATION/TOOLS/DOC/devusage.md b/openair1/SIMULATION/TOOLS/DOC/devusage.md new file mode 100644 index 0000000000..8fa6b3fe7a --- /dev/null +++ b/openair1/SIMULATION/TOOLS/DOC/devusage.md @@ -0,0 +1,7 @@ +### channel simulation developer usage + + +[Configuring the channel simulation](rtusage.md) + +[channel simulation main page](channel_simulation.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file diff --git a/openair1/SIMULATION/TOOLS/DOC/rtusage.md b/openair1/SIMULATION/TOOLS/DOC/rtusage.md new file mode 100644 index 0000000000..37fc62b496 --- /dev/null +++ b/openair1/SIMULATION/TOOLS/DOC/rtusage.md @@ -0,0 +1,69 @@ +## configuring the channel simulation +Oai channel simulation is using the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify some channel model parameters + +All channel simulation parameters are defined in the `channelmod` section. Most parameters are specific to a channel model and are only used by the rfsimulator. + +### global parameters + +| name | type | default | description | +|:---:|:---:|:---:|:----| +| `max_chan` | integer | `25` | Maximum number of channel model that can be defined in the system. Must be greater than the number of model definitions in the model list loaded at init time. | +| `modellist` | character string | `DefaultChannelList` | Name of the channel models list to load at init time. | + +### Model lists + +Several model lists can be defined in the oai configuration file. One, defined by the `modellist` parameter is loaded at init time. In the configuration file each model list item describes a channel model using a group of parameters: + +| parameter name | type | default | description | +|:---:|:---:|:---:|:----| +| `model name` | character string | mandatory |name of the model, as used in the code to retrieve a model definition| +| `type` | | `AWGN` | name of the channel modelization algorithm applied on rf signal. The list of available model types can be listed via the [telnet server](../../telnetsrv/DOC/telnetsrv.md) or by entering an invalid type name | +| `ploss_dB` | real (float) | | path loss of the channel, in dB | +| `noise_power_dB` | real (double) | | noise of the channel in dB | +| `forgetfact` | real (double) | | | +| `offset` | integer | | | +| `ds_tdl` | real double | | | + +Channel simulation parameters can also be specified on the command line: + +```bash +./lte-softmodem -O ../../../ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --noS1 --rfsim --rfsimulator.options chanmod --rfsimulator.serveraddr enb --telnetsrv --channelmod.modellist modellist_rfsimu_2 --channelmod.modellist_rfsimu_2.[1].offset 120 +``` +### Using the telnet server to modify channel simulator parameters +The telnet server includes a `channelmod` command which can be used to dynamically modify some channel model parameters. This command is only available when channel simulation is enabled (via `rfsimulator.options chanmod` option when running the rfsimulator. `channelmod` command has its own help: + +``` +$ telnet 127.0.0.1 9090 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +softmodem_enb> help +..................................... + module 6 = channelmod: + channelmod help + channelmod show + channelmod modify + module 7 = rfsimu: + rfsimu setmodel +softmodem_enb> channelmod help +channelmod commands can be used to display or modify channel models parameters +channelmod show predef: display predefined model algorithms available in oai +channelmod show current: display the currently used models in the running executable +channelmod modify : set the specified parameters in a current model to the given value + specifies the model, the show current model command can be used to list the current models indexes + can be one of "riceanf", "aoa", "randaoa", "ploss", "noise_power_dB", "offset", "forgetf" +softmodem_enb> + +``` + + + + + + + +The [rfsimulator documentation](../../../../targets/ARCH/rfsimulator/README.md ) has also some specific information when using the channel simulation via this tool. + +[channel simulation main page](channel_simulation.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file diff --git a/openair1/SIMULATION/TOOLS/phase_noise.c b/openair1/SIMULATION/TOOLS/phase_noise.c index 5958a0ccdd..6cc24f23db 100644 --- a/openair1/SIMULATION/TOOLS/phase_noise.c +++ b/openair1/SIMULATION/TOOLS/phase_noise.c @@ -26,6 +26,7 @@ #include "sim.h" +static uint16_t LUTSin[ResolSinCos+1]; /* linear phase noise model */ void phase_noise(double ts, int16_t * InRe, int16_t * InIm) { diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 47597f4d6e..4e26d9a954 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -50,7 +50,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt) static telnetshell_cmddef_t channelmod_cmdarray[] = { {"help","",channelmod_print_help}, {"show","",channelmod_show_cmd}, - {"modify"," ",channelmod_modify_cmd}, + {"modify"," ",channelmod_modify_cmd}, {"","",NULL}, }; @@ -62,13 +62,16 @@ static double snr_dB=25; static double sinr_dB=0; static unsigned int max_chan; static channel_desc_t **defined_channels; +static char modellist_name[MAX_OPTNAME_SIZE]= {0}; + + void fill_channel_desc(channel_desc_t *chan_desc, uint8_t nb_tx, uint8_t nb_rx, uint8_t nb_taps, uint8_t channel_length, double *amps, - double *delays, + double *delays, struct complex **R_sqrt, double Td, double sampling_rate, @@ -136,8 +139,10 @@ void fill_channel_desc(channel_desc_t *chan_desc, if (R_sqrt == NULL) { chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_NTAPS ; + for (i = 0; iR_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; chan_desc->R_sqrt[i][j].y = 0.0; @@ -145,7 +150,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, } } else { chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); - + for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; @@ -175,224 +180,229 @@ void fill_channel_desc(channel_desc_t *chan_desc, double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58}; double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6,-17.0,-20,-21.5,-21.4,-23.6,-20.6,-27}; -double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250}; +double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250}; double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62}; double tdl_a_delays[] = {0.0000, - 0.3819, - 0.4025, - 0.5868, - 0.4610, - 0.5375, - 0.6708, - 0.5750, - 0.7618, - 1.5375, - 1.8978, - 2.2242, - 2.1718, - 2.4942, - 2.5119, - 3.0582, - 4.0810, - 4.4579, - 4.5695, - 4.7966, - 5.0066, - 5.3043, - 9.6586}; + 0.3819, + 0.4025, + 0.5868, + 0.4610, + 0.5375, + 0.6708, + 0.5750, + 0.7618, + 1.5375, + 1.8978, + 2.2242, + 2.1718, + 2.4942, + 2.5119, + 3.0582, + 4.0810, + 4.4579, + 4.5695, + 4.7966, + 5.0066, + 5.3043, + 9.6586 + }; double tdl_a_amps_dB[] = {-13.4, - 0, - -2.2, - -4, - -6, - -8.2, - -9.9, - -10.5, - -7.5, - -15.9, - -6.6, - -16.7, - -12.4, - -15.2, - -10.8, - -11.3, - -12.7, - -16.2, - -18.3, - -18.9, - -16.6, - -19.9, - -29.7}; -#define TDL_A_PATHS 23 + 0, + -2.2, + -4, + -6, + -8.2, + -9.9, + -10.5, + -7.5, + -15.9, + -6.6, + -16.7, + -12.4, + -15.2, + -10.8, + -11.3, + -12.7, + -16.2, + -18.3, + -18.9, + -16.6, + -19.9, + -29.7 + }; double tdl_b_delays[] = {0.0000, - 0.1072, - 0.2155, - 0.2095, - 0.2870, - 0.2986, - 0.3752, - 0.5055, - 0.3681, - 0.3697, - 0.5700, - 0.5283, - 1.1021, - 1.2756, - 1.5474, - 1.7842, - 2.0169, - 2.8294, - 3.0219, - 3.6187, - 4.1067, - 4.2790, - 4.7834}; + 0.1072, + 0.2155, + 0.2095, + 0.2870, + 0.2986, + 0.3752, + 0.5055, + 0.3681, + 0.3697, + 0.5700, + 0.5283, + 1.1021, + 1.2756, + 1.5474, + 1.7842, + 2.0169, + 2.8294, + 3.0219, + 3.6187, + 4.1067, + 4.2790, + 4.7834 + }; double tdl_b_amps_dB[] = {0, - -2.2, - -4, - -3.2, - -9.8, - -1.2, - -3.4, - -5.2, - -7.6, - -3, - -8.9, - -9, - -4.8, - -5.7, - -7.5, - -1.9, - -7.6, - -12.2, - -9.8, - -11.4, - -14.9, - -9.2, - -11.3}; -#define TDL_B_PATHS 23 + -2.2, + -4, + -3.2, + -9.8, + -1.2, + -3.4, + -5.2, + -7.6, + -3, + -8.9, + -9, + -4.8, + -5.7, + -7.5, + -1.9, + -7.6, + -12.2, + -9.8, + -11.4, + -14.9, + -9.2, + -11.3 + }; double tdl_c_delays[] = {0, - 0.2099, - 0.2219, - 0.2329, - 0.2176, - 0.6366, - 0.6448, - 0.6560, - 0.6584, - 0.7935, - 0.8213, - 0.9336, - 1.2285, - 1.3083, - 2.1704, - 2.7105, - 4.2589, - 4.6003, - 5.4902, - 5.6077, - 6.3065, - 6.6374, - 7.0427, - 8.6523}; + 0.2099, + 0.2219, + 0.2329, + 0.2176, + 0.6366, + 0.6448, + 0.6560, + 0.6584, + 0.7935, + 0.8213, + 0.9336, + 1.2285, + 1.3083, + 2.1704, + 2.7105, + 4.2589, + 4.6003, + 5.4902, + 5.6077, + 6.3065, + 6.6374, + 7.0427, + 8.6523 + }; double tdl_c_amps_dB[] = {-4.4, - -1.2, - -3.5, - -5.2, - -2.5, - 0, - -2.2, - -3.9, - -7.4, - -7.1, - -10.7, - -11.1, - -5.1, - -6.8, - -8.7, - -13.2, - -13.9, - -13.9, - -15.8, - -17.1, - -16, - -15.7, - -21.6, - -22.8}; -#define TDL_C_PATHS 24 + -1.2, + -3.5, + -5.2, + -2.5, + 0, + -2.2, + -3.9, + -7.4, + -7.1, + -10.7, + -11.1, + -5.1, + -6.8, + -8.7, + -13.2, + -13.9, + -13.9, + -15.8, + -17.1, + -16, + -15.7, + -21.6, + -22.8 + }; double tdl_d_delays[] = {//0, - 0, - 0.035, - 0.612, - 1.363, - 1.405, - 1.804, - 2.596, - 1.775, - 4.042, - 7.937, - 9.424, - 9.708, - 12.525}; + 0, + 0.035, + 0.612, + 1.363, + 1.405, + 1.804, + 2.596, + 1.775, + 4.042, + 7.937, + 9.424, + 9.708, + 12.525 +}; double tdl_d_amps_dB[] = {//-0.2, -//-13.5, - -.00147, - -18.8, - -21, - -22.8, - -17.9, - -20.1, - -21.9, - -22.9, - -27.8, - -23.6, - -24.8, - -30.0, - -27.7}; + //-13.5, + -.00147, + -18.8, + -21, + -22.8, + -17.9, + -20.1, + -21.9, + -22.9, + -27.8, + -23.6, + -24.8, + -30.0, + -27.7 + }; -#define TDL_D_PATHS 13 #define TDL_D_RICEAN_FACTOR .046774 double tdl_e_delays[] = {0, - 0.5133, - 0.5440, - 0.5630, - 0.5440, - 0.7112, - 1.9092, - 1.9293, - 1.9589, - 2.6426, - 3.7136, - 5.4524, - 12.0034, - 20.6519}; + 0.5133, + 0.5440, + 0.5630, + 0.5440, + 0.7112, + 1.9092, + 1.9293, + 1.9589, + 2.6426, + 3.7136, + 5.4524, + 12.0034, + 20.6519 + }; double tdl_e_amps_dB[] = {//-0.03, - //-22.03, - -.00433, - -15.8, - -18.1, - -19.8, - -22.9, - -22.4, - -18.6, - -20.8, - -22.6, - -22.3, - -25.6, - -20.2, - -29.8, - -29.2}; + //-22.03, + -.00433, + -15.8, + -18.1, + -19.8, + -22.9, + -22.4, + -18.6, + -20.8, + -22.6, + -22.3, + -25.6, + -20.2, + -29.8, + -29.2 + }; -#define TDL_E_PATHS 14 #define TDL_E_RICEAN_FACTOR 0.0063096 double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41}; @@ -494,31 +504,101 @@ struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap}; //Rayleigh1_orth_eff_ch_TM4 +void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS_TDL, channel_desc_t *chan_desc ) { + int nb_rx=chan_desc-> nb_rx; + int nb_tx=chan_desc-> nb_tx; + int tdl_pathsby3 = tdl_paths/3; + + if ((tdl_paths%3)>0) + tdl_pathsby3++; + + chan_desc->nb_taps = tdl_paths; + chan_desc->Td = tdl_delays[tdl_paths-1]*DS_TDL; + printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td); + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + + 1 + + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length); + double sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (int i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (int i = 0; inb_taps; i++) { + chan_desc->amps[i] /= sum_amps; + tdl_delays[i] *= DS_TDL; + } + + chan_desc->delays = tdl_delays; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (int i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (int i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (int i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + if (nb_tx==2 && nb_rx==2) { + for (int i = 0; i<(tdl_pathsby3); i++) + chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; + } else if (nb_tx==2 && nb_rx==1) { + for (int i = 0; i<(tdl_pathsby3); i++) + chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0]; + } else if (nb_tx==1 && nb_rx==2) { + for (int i = 0; i<(tdl_pathsby3); i++) + chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; + } else { + for (int i = 0; i<(tdl_pathsby3); i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (int j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + } + } +} + channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, uint8_t nb_rx, SCM_t channel_model, double sampling_rate, double channel_bandwidth, - double DS_TDL, + double DS_TDL, double forgetting_factor, int32_t channel_offset, - double path_loss_dB) { + double path_loss_dB, + float noise_power_dB) { channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t)); - for(int i=0; ichan_idx=i; - break; - } - else { - AssertFatal(i<(max_chan-1), - "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan); - } + + for(int i=0; ichan_idx=i; + break; + } else { + AssertFatal(i<(max_chan-1), + "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan); + } } + uint16_t i,j; double sum_amps; double aoa,ricean_factor,Td,maxDoppler; - int channel_length,nb_taps; chan_desc->modelid = channel_model; chan_desc->nb_tx = nb_tx; @@ -530,13 +610,13 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->path_loss_dB = path_loss_dB; chan_desc->first_run = 1; chan_desc->ip = 0.0; + chan_desc->noise_power_dB = noise_power_dB; LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model); - int tdl_paths=0; - double tdl_ricean_factor = 1; double *tdl_amps_dB; double *tdl_delays; + /* Spatial Channel Models (SCM) channel model from TR 38.901 Section 7.7.2 */ switch (channel_model) { case SCM_A: LOG_W(OCM,"channel model not yet supported\n"); @@ -554,7 +634,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -592,10 +673,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, for (i = 0; i<6; i++) chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; } else { - chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - + for (j = 0; jR_sqrt[i][j].x = 1.0; chan_desc->R_sqrt[i][j].y = 0.0; @@ -615,6 +697,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -652,7 +735,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, for (i = 0; i<6; i++) chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; } else { - chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -666,99 +750,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } break; - + /* tapped delay line (TDL) channel model from TR 38.901 Section 7.7.2 */ +#define tdl_m(MoDel)\ + DevAssert(sizeof(tdl_ ## MoDel ## _amps_dB) == sizeof(tdl_ ## MoDel ## _delays)); \ + tdl_paths=sizeof(tdl_ ## MoDel ## _amps_dB)/sizeof(*tdl_ ## MoDel ## _amps_dB);\ + tdl_delays=tdl_ ## MoDel ## _delays;\ + tdl_amps_dB=tdl_ ## MoDel ## _amps_dB + case TDL_A: + chan_desc->ricean_factor = 1; + tdl_m(a); + tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc); + break; + case TDL_B: - case TDL_C: - case TDL_D: + chan_desc->ricean_factor = 1; + tdl_m(b); + tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc); + break; + + case TDL_C: + chan_desc->ricean_factor = 1; + tdl_m(c); + tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc); + break; + + case TDL_D: + chan_desc->ricean_factor = TDL_D_RICEAN_FACTOR; + tdl_m(d); + tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc); + break; + case TDL_E: - if (channel_model == TDL_A) { - tdl_paths=TDL_A_PATHS; - tdl_delays=tdl_a_delays; - tdl_amps_dB=tdl_a_amps_dB; - }else if (channel_model == TDL_B) { - tdl_paths=TDL_B_PATHS; - tdl_delays=tdl_b_delays; - tdl_amps_dB=tdl_b_amps_dB; - } - else if (channel_model == TDL_C) { - tdl_paths=TDL_C_PATHS; - tdl_delays=tdl_c_delays; - tdl_amps_dB=tdl_c_amps_dB; - printf("Initializing TDL_C channel with %d paths\n",TDL_C_PATHS); - } else if (channel_model == TDL_D) { - tdl_paths=TDL_D_PATHS; - tdl_delays=tdl_d_delays; - tdl_amps_dB=tdl_d_amps_dB; - tdl_ricean_factor = TDL_D_RICEAN_FACTOR; - } else if (channel_model == TDL_E) { - tdl_paths=TDL_E_PATHS-1; - tdl_delays=tdl_e_delays+1; - tdl_amps_dB=tdl_e_amps_dB; - tdl_ricean_factor = TDL_E_RICEAN_FACTOR; - } - - int tdl_pathsby3 = tdl_paths/3; - if ((tdl_paths%3)>0) tdl_pathsby3++; - - chan_desc->nb_taps = tdl_paths; - chan_desc->Td = tdl_delays[tdl_paths-1]*DS_TDL; - printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td); - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length); - sum_amps = 0; - chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] /= sum_amps; - tdl_delays[i] *= DS_TDL; - } - chan_desc->delays = tdl_delays; - chan_desc->ricean_factor = tdl_ricean_factor; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); - chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); - chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); - - for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); - - chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); - - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<(tdl_pathsby3); i++) - chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; - } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<(tdl_pathsby3); i++) - chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0]; - } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<(tdl_pathsby3); i++) - chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; - } else { - for (i = 0; i<(tdl_pathsby3); i++) { - chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); - } - } - + chan_desc->ricean_factor = TDL_E_RICEAN_FACTOR; + tdl_m(e); + tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc); break; case EPA: @@ -768,6 +794,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -786,7 +813,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); - + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); @@ -801,6 +828,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } else { chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -822,6 +850,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -867,7 +896,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } }*/ - break; + break; case EPA_high: chan_desc->nb_taps = 7; @@ -876,6 +905,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -929,7 +959,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -984,6 +1015,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -1017,7 +1049,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } else { chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; - for (i = 0; i<6; i++) { + + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); for (j = 0; jamps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -1071,6 +1105,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } else { chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -1092,6 +1127,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; + for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -1119,6 +1155,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *)); chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6; + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -1628,38 +1665,65 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->nb_paths = 10; return(chan_desc); -} - +} /* channel_desc_t *new_channel_desc_scm */ + +channel_desc_t *find_channel_desc_fromname( char *modelname ) { + for(int i=0; imodel_name,modelname) == 0) + return defined_channels[i]; + } + } + + LOG_E(OCM,"Model %s not found \n", modelname); + return NULL; +} /* channel_desc_t * new_channel_desc_fromconfig */ + + + void free_channel_desc_scm(channel_desc_t *ch) { // Must be made cleanly, a lot of leaks... if (max_chan != 0) defined_channels[ch->chan_idx]=NULL; if(ch->free_flags&CHANMODEL_FREE_AMPS) free(ch->amps); - for (int i = 0; inb_tx*ch->nb_rx; i++) { + + for (int i = 0; inb_tx*ch->nb_rx; i++) { free(ch->ch[i]); free(ch->chF[i]); } - + for (int i = 0; inb_taps; i++) { - free(ch->a[i]); - } + free(ch->a[i]); + } + if(ch->free_flags&CHANMODEL_FREE_DELAY) - free(ch->delays); + free(ch->delays); + if(ch->free_flags&CHANMODEL_FREE_RSQRT_6) - for (int i = 0; i<6; i++) - free(ch->R_sqrt[i]); + for (int i = 0; i<6; i++) + free(ch->R_sqrt[i]); + if(ch->free_flags&CHANMODEL_FREE_RSQRT_NTAPS) - for (int i = 0; inb_taps;i++) - free(ch->R_sqrt[i]); - free(ch->R_sqrt); - free(ch->ch); + for (int i = 0; inb_taps; i++) + free(ch->R_sqrt[i]); + + free(ch->R_sqrt); + free(ch->ch); free(ch->chF); - free(ch->a); - free(ch); + free(ch->a); + free(ch->model_name); + free(ch); } void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) { - cdesc->module_id=module_id; + cdesc->module_id=module_id; +} + +void set_channeldesc_name(channel_desc_t *cdesc,char *modelname) { + if(cdesc->model_name != NULL) + free(cdesc->model_name); + + cdesc->model_name=strdup(modelname); } int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { @@ -1780,14 +1844,14 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x; desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y; - // printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]); + // printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]); } //nb_taps #ifdef DEBUG_CH printf("(%d,%d,%d)->(%e,%e)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); #endif } //channel_length - } + } } //aatx } //aarx @@ -1799,7 +1863,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { return (0); } - + double N_RB2sampling_rate(uint16_t N_RB) { double sampling_rate; @@ -1848,128 +1912,144 @@ double N_RB2channel_bandwidth(uint16_t N_RB) { break; default: - LOG_E(PHY,"Unknown N_PRB\n"); + LOG_E(OCM,"Unknown N_PRB\n"); return(-1); } - return(channel_bandwidth); -} - + return(channel_bandwidth); +} + + static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ) { - prnt("channelmod commands can be used to display or modify channel models parameters\n"); - prnt("channelmod show predef: display predefined model algorithms available in oai\n"); - prnt("channelmod show current: display the currently used models in the running executable\n"); - prnt("channelmod modify : set the specified parameters in a current model to the given value\n"); - prnt(" specifies the model, the show current model command can be used to list the current models indexes\n"); - prnt(" can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"offset\", \"forgetf\"\n"); - return CMDSTATUS_FOUND; + prnt("channelmod commands can be used to display or modify channel models parameters\n"); + prnt("channelmod show predef: display predefined model algorithms available in oai\n"); + prnt("channelmod show current: display the currently used models in the running executable\n"); + prnt("channelmod modify : set the specified parameters in a current model to the given value\n"); + prnt(" specifies the model, the show current model command can be used to list the current models indexes\n"); + prnt(" can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"noise_power_dB\", \"offset\", \"forgetf\"\n"); + return CMDSTATUS_FOUND; } static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) { - char *module_id_str[]=MODULEID_STR_INIT; - if (cd->module_id != 0) { - prnt("model owner: %s\n",module_id_str[cd->module_id]); - } - prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate); - prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n", - cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No")); - prnt("max Doppler: %lf path loss: %lf rchannel offset: %i forget factor; %lf\n", - cd->max_Doppler, cd->path_loss_dB, cd->channel_offset, cd->forgetting_factor); - prnt("Initial phase: %lf nb_path: %i \n", - cd->ip, cd->nb_paths); - for (int i=0; inb_taps ; i++) { - prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]); - } + char *module_id_str[]=MODULEID_STR_INIT; + prnt("model owner: %s\n",(cd->module_id != 0)?module_id_str[cd->module_id]:"not set"); + prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate); + prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n", + cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No")); + prnt("max Doppler: %lf path loss: %lf noise: %lf rchannel offset: %i forget factor; %lf\n", + cd->max_Doppler, cd->path_loss_dB, cd->noise_power_dB, cd->channel_offset, cd->forgetting_factor); + prnt("Initial phase: %lf nb_path: %i \n", + cd->ip, cd->nb_paths); + + for (int i=0; inb_taps ; i++) { + prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]); + } } - - + + static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { - char *subcmd=NULL; + char *subcmd=NULL; int s = sscanf(buff,"%ms\n",&subcmd); if (s>0) { if ( strcmp(subcmd,"predef") == 0) { for (int i=0; channelmod_names[i].name != NULL ; i++) { prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i )); - } + } } else if ( strcmp(subcmd,"current") == 0) { for (int i=0; i < max_chan ; i++) { - if (defined_channels[i] != NULL) { - prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid)); - display_channelmodel(defined_channels[i],debug,prnt); + if (defined_channels[i] != NULL) { + prnt("model %i %s type %s: \n----------------\n", i, (defined_channels[i]->model_name !=NULL)?defined_channels[i]->model_name:"(no name set)", + map_int_to_str(channelmod_names,defined_channels[i]->modelid)); + display_channelmodel(defined_channels[i],debug,prnt); } } } else { - channelmod_print_help(buff, debug, prnt); + channelmod_print_help(buff, debug, prnt); } - free(subcmd); + + free(subcmd); } + return CMDSTATUS_FOUND; } - + static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) { - char *param=NULL, *value=NULL; + char *param=NULL, *value=NULL; int cd_id= -1; int s = sscanf(buff,"%i %ms %ms \n",&cd_id,¶m, &value); + if (cd_id<0 || cd_id >= max_chan) { - prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1); - return CMDSTATUS_FOUND; + prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1); + return CMDSTATUS_FOUND; } + if (defined_channels[cd_id]==NULL) { - prnt("ERROR, %i: Channel model has not been set\n",cd_id); - return CMDSTATUS_FOUND; - } - + prnt("ERROR, %i: Channel model has not been set\n",cd_id); + return CMDSTATUS_FOUND; + } + if (s==3) { if ( strcmp(param,"riceanf") == 0) { - double dbl = atof(value); - if (dbl <0 || dbl > 1) - prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl); - else - defined_channels[cd_id]->ricean_factor=dbl; + double dbl = atof(value); + + if (dbl <0 || dbl > 1) + prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl); + else + defined_channels[cd_id]->ricean_factor=dbl; } else if ( strcmp(param,"aoa") == 0) { - double dbl = atof(value); - if (dbl <0 || dbl >6.28) - prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl); - else - defined_channels[cd_id]->aoa=dbl; + double dbl = atof(value); + + if (dbl <0 || dbl >6.28) + prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl); + else + defined_channels[cd_id]->aoa=dbl; } else if ( strcmp(param,"randaoa") == 0) { - int i = atoi(value); - if (i!=0 && i!=1) - prnt("ERROR: randaoa is a boolean, must be 0 or 1\n"); - else - defined_channels[cd_id]->random_aoa=i; + int i = atoi(value); + + if (i!=0 && i!=1) + prnt("ERROR: randaoa is a boolean, must be 0 or 1\n"); + else + defined_channels[cd_id]->random_aoa=i; } else if ( strcmp(param,"ploss") == 0) { - double dbl = atof(value); - defined_channels[cd_id]->path_loss_dB=dbl; + double dbl = atof(value); + defined_channels[cd_id]->path_loss_dB=dbl; + } else if ( strcmp(param,"noise_power_dB") == 0) { + double dbl = atof(value); + defined_channels[cd_id]->noise_power_dB=dbl; } else if ( strcmp(param,"offset") == 0) { - int i = atoi(value); - defined_channels[cd_id]->channel_offset=i; + int i = atoi(value); + defined_channels[cd_id]->channel_offset=i; } else if ( strcmp(param,"forgetf") == 0) { - double dbl = atof(value); - if (dbl <0 || dbl > 1) - prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl); - else - defined_channels[cd_id]->forgetting_factor=dbl; + double dbl = atof(value); + + if (dbl <0 || dbl > 1) + prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl); + else + defined_channels[cd_id]->forgetting_factor=dbl; } else { - prnt("ERROR: %s, unknown channel parameter\n",param); - return CMDSTATUS_FOUND; + prnt("ERROR: %s, unknown channel parameter\n",param); + return CMDSTATUS_FOUND; } - display_channelmodel(defined_channels[cd_id],debug,prnt); - free(param); - free(value); - random_channel(defined_channels[cd_id],false); + + display_channelmodel(defined_channels[cd_id],debug,prnt); + free(param); + free(value); + random_channel(defined_channels[cd_id],false); } - return CMDSTATUS_FOUND; + + return CMDSTATUS_FOUND; } - -int modelid_fromname(char *modelname) { - int modelid=map_str_to_int(channelmod_names,modelname); - if (modelid < 0) - LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname); + +int modelid_fromstrtype(char *modeltype) { + int modelid=map_str_to_int(channelmod_names,modeltype); + + if (modelid < 0) + LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modeltype); + return modelid; } @@ -1983,18 +2063,61 @@ double channelmod_get_sinr_dB(void) { void init_channelmod(void) { paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC; - int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION); + int numparams=sizeof(channelmod_params)/sizeof(paramdef_t); + int ret = config_get( channelmod_params,numparams,CHANNELMOD_SECTION); AssertFatal(ret >= 0, "configuration couldn't be performed"); - defined_channels=calloc(max_chan,sizeof( channel_desc_t*)); + defined_channels=calloc(max_chan,sizeof( channel_desc_t *)); AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan); - /* look for telnet server, if it is loaded, add the channel modeling commands to it */ add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); if (addcmd != NULL) { addcmd("channelmod",channelmod_vardef,channelmod_cmdarray); } -} +} /* init_channelmod */ + + +int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) { + paramdef_t achannel_params[] = CHANNELMOD_MODEL_PARAMS_DESC; + paramlist_def_t channel_list; + memset(&channel_list,0,sizeof(paramlist_def_t)); + memcpy(channel_list.listname,modellist_name,sizeof(channel_list.listname)-1); + int numparams = sizeof(achannel_params)/sizeof(paramdef_t); + config_getlist( &channel_list,achannel_params,numparams, CHANNELMOD_SECTION); + AssertFatal(channel_list.numelt>0, "List %s.%s not found in config file\n",CHANNELMOD_SECTION,channel_list.listname); + int pindex_NAME = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NAME_PNAME); + int pindex_DT = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_DT_PNAME ); + int pindex_FF = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_FF_PNAME ); + int pindex_CO = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_CO_PNAME ); + int pindex_PL = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_PL_PNAME ); + int pindex_NP = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NP_PNAME ); + int pindex_TYPE = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_TYPE_PNAME); + + for (int i=0; imodel_name = strdup(*(channel_list.paramarray[i][pindex_NAME].strptr)); + LOG_I(OCM,"Model %s type %s allocated from config file, list %s\n",*(channel_list.paramarray[i][pindex_NAME].strptr), + *(channel_list.paramarray[i][pindex_TYPE].strptr), modellist_name); + } /* for loop on channel_list */ + + return channel_list.numelt; +} /* load_channelist */ #ifdef RANDOM_CHANNEL_MAIN #define sampling_rate 5.0 diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 55a78e9778..7696f9202f 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -89,6 +89,7 @@ typedef struct { double path_loss_dB; ///additional delay of channel in samples. int32_t channel_offset; + float noise_power_dB; ///This parameter (0...1) allows for simple 1st order temporal variation. 0 means a new channel every call, 1 means keep channel constant all the time double forgetting_factor; ///needs to be set to 1 for the first call, 0 otherwise. @@ -106,8 +107,10 @@ typedef struct { unsigned int chan_idx; /// id of the channel modeling algorithm int modelid; - /// identifies channel descriptor owner (the module which created this descriptor) + /// identifies channel descriptor owner (the module which created this descriptor channelmod_moduleid_t module_id; + /// name of this descriptor,used for model created from config file at init time + char *model_name; /// flags to properly trigger memory free unsigned int free_flags; } channel_desc_t; @@ -241,12 +244,37 @@ typedef enum { #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CHANNELMOD_SECTION "channelmod" + +/* global channel modelization parameters */ +#define CHANNELMOD_MODELLIST_PARANAME "modellist" + +#define CHANNELMOD_HELP_MODELLIST " channel list name in config file describing the model type and its parameters\n" #define CHANNELMOD_PARAMS_DESC { \ - {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\ - {"sinr_dB", NULL, 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\ - {"max_chan, CONFIG_HLP_MAX_CHAN", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\ + {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\ + {"sinr_dB", NULL, 0, dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\ + {"max_chan", "Max number of runtime models", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\ + {CHANNELMOD_MODELLIST_PARANAME, CHANNELMOD_HELP_MODELLIST, 0, strptr:(char **)&modellist_name, defstrval:"DefaultChannelList", TYPE_STRING, 60 },\ } +/* parameters for one model */ +#define CHANNELMOD_MODEL_NAME_PNAME "model_name" +#define CHANNELMOD_MODEL_TYPE_PNAME "type" +#define CHANNELMOD_MODEL_PL_PNAME "ploss_dB" +#define CHANNELMOD_MODEL_NP_PNAME "noise_power_dB" +#define CHANNELMOD_MODEL_FF_PNAME "forgetfact" +#define CHANNELMOD_MODEL_CO_PNAME "offset" +#define CHANNELMOD_MODEL_DT_PNAME "ds_tdl" + +#define CHANNELMOD_MODEL_PARAMS_DESC { \ + {CHANNELMOD_MODEL_NAME_PNAME, "name of the model\n", 0, strptr:NULL , defstrval:"", TYPE_STRING, 0 },\ + {CHANNELMOD_MODEL_TYPE_PNAME, "name of the model type\n", 0, strptr:NULL , defstrval:"AWGN", TYPE_STRING, 0 },\ + {CHANNELMOD_MODEL_PL_PNAME, "channel path loss in dB\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\ + {CHANNELMOD_MODEL_NP_PNAME, "channel noise in dB\n", 0, dblptr:NULL, defdblval:-50, TYPE_DOUBLE, 0 },\ + {CHANNELMOD_MODEL_FF_PNAME, "channel forget factor ((0 to 1)\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\ + {CHANNELMOD_MODEL_CO_PNAME, "channel offset in samps\n", 0, iptr:NULL, defintval:0, TYPE_INT, 0 },\ + {CHANNELMOD_MODEL_DT_PNAME, "delay spread for TDL models\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 }\ +} + #include "platform_constants.h" typedef struct { @@ -275,12 +303,17 @@ typedef struct { channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, uint8_t nb_rx, SCM_t channel_model, - double sampling_rate, + double sampling_rate, double channel_bandwidth, - double TDL_DS, + double TDL_DS, double forgetting_factor, int32_t channel_offset, - double path_loss_dB); + double path_loss_dB, + float noise_power_dB); + +channel_desc_t *find_channel_desc_fromname( char *modelname ); + + /** \brief free memory allocated for a model descriptor \param ch points to the model, which cannot be used after calling this fuction @@ -293,6 +326,12 @@ void free_channel_desc_scm(channel_desc_t *ch); \param module_id identifies the channel model. should be define as a macro in simu.h */ void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id); +/** +\brief This function set a model name to a model descriptor, can be later used to identify a allocated channel model +\param cdesc points to the model descriptor +\param module_name is the C string to use as model name for the channel pointed by cdesc +*/ +void set_channeldesc_name(channel_desc_t *cdesc,char *modelname); /** \fn void random_channel(channel_desc_t *desc) \brief This routine generates a random channel response (time domain) according to a tapped delay line model. \param desc Pointer to the channel descriptor @@ -452,11 +491,11 @@ void multipath_tv_channel(channel_desc_t *desc, /**@} */ /**@} */ -int modelid_fromname(char *modelname); +int modelid_fromstrtype(char *modeltype); double channelmod_get_snr_dB(void); double channelmod_get_sinr_dB(void); void init_channelmod(void) ; - +int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) ; double N_RB2sampling_rate(uint16_t N_RB); double N_RB2channel_bandwidth(uint16_t N_RB); @@ -468,7 +507,6 @@ double N_RB2channel_bandwidth(uint16_t N_RB); */ //look-up table for the sine (cosine) function #define ResolSinCos 100 -uint16_t LUTSin[ResolSinCos+1]; void InitSinLUT( void ); void phase_noise(double ts, int16_t * InRe, int16_t * InIm); diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 8fde343000..f5b6314fe1 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -175,6 +175,8 @@ typedef struct gtpv1u_enb_end_marker_ind_s { typedef struct { in_addr_t enb_ip_address_for_S1u_S12_S4_up; tcp_udp_port_t enb_port_for_S1u_S12_S4_up; + char addrStr[256]; + char portStr[256]; } Gtpv1uS1Req; typedef struct { diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 9db5d61a11..d6dd6e3b6f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -51,8 +51,6 @@ typedef struct { pthread_mutex_t *mutex; } mac_stats_updates_context_t; -/*Array holding the last stats reports for each eNB. Used for continuous reporting*/ -mac_stats_updates_context_t mac_stats_context[NUM_MAX_ENB]; /*Functions to initialize and destroy the struct required for the *continuous stats update report*/ diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index 5f6432732f..a9236af80b 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -49,8 +49,6 @@ typedef struct /*To Be Extended*/ }rrc_meas_stats; -/* RRC CMI statistics */ -rrc_meas_stats * meas_stats; /* FLEXRAN AGENT-RRC Interface */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index d05fe7ac26..b53a6feda1 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -57,6 +57,7 @@ #include "enb_paramdef.h" #include "proto_agent.h" #include "executables/thread-common.h" +#include extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); @@ -2058,7 +2059,9 @@ int RCconfig_gtpu(void ) { IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U; - itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address); + sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", enb_port_for_S1U); + itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else LOG_E(GTPU,"invalid address for S1U\n"); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index abb5b57e0c..1af59eab87 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -648,18 +648,6 @@ error: * ************************************ */ -int sort_ue_config(const void *a, const void *b) { - const Protocol__FlexUeConfig *fa = a; - const Protocol__FlexUeConfig *fb = b; - - if (fa->rnti < fb->rnti) - return -1; - else if (fa->rnti < fb->rnti) - return 1; - - return 0; -} - int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; Protocol__FlexHeader *header = NULL; diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index ae690c7124..18d32421dd 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -70,7 +70,6 @@ typedef struct { pthread_mutex_t *mutex; } stats_updates_context_t; -stats_updates_context_t stats_context[NUM_MAX_ENB]; /********************************** * FlexRAN protocol messages helper diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c index 0d1c52096d..568a0e32cc 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.c +++ b/openair2/ENB_APP/flexran_agent_net_comm.c @@ -30,7 +30,7 @@ #include "common/utils/LOG/log.h" flexran_agent_channel_t *agent_channel[NUM_MAX_ENB][FLEXRAN_AGENT_MAX]; -flexran_agent_channel_instance_t channel_instance; +static flexran_agent_channel_instance_t channel_instance; int flexran_agent_channel_id = 0; int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c b/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c new file mode 100644 index 0000000000..a5eb850712 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c @@ -0,0 +1,33 @@ +#include +#include +#include +pdcp_enb_t pdcp_enb[MAX_NUM_CCs]; +uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; + +uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; + diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index 67be560778..88f2cb1615 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -62,7 +62,7 @@ {CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0} \ +{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0} \ } #define L1_CC_IDX 0 #define L1_TRANSPORT_N_PREFERENCE_IDX 1 diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b40ff5d9e2..d3dd769807 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -58,6 +58,7 @@ //#include "RRC_config_tools.h" #include "gnb_paramdef.h" #include "NR_MAC_gNB/mac_proto.h" +#include #include "NR_asn_constant.h" #include "executables/thread-common.h" @@ -123,7 +124,37 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon)); scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = CALLOC(1,sizeof(long)); scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero = CALLOC(1,sizeof(long)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = CALLOC(1,sizeof(struct NR_ControlResourceSet)); + + NR_ControlResourceSet_t *coreset0 = CALLOC(1,sizeof(struct NR_ControlResourceSet)); + coreset0->controlResourceSetId = 0; + // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B, + if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6); + coreset0->frequencyDomainResources.buf[0] = 0xff; + coreset0->frequencyDomainResources.buf[1] = 0; + coreset0->frequencyDomainResources.buf[2] = 0; + coreset0->frequencyDomainResources.buf[3] = 0; + coreset0->frequencyDomainResources.buf[4] = 0; + coreset0->frequencyDomainResources.buf[5] = 0; + coreset0->frequencyDomainResources.size = 6; + coreset0->frequencyDomainResources.bits_unused = 3; + coreset0->duration = 1; + coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; + coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved)); + coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6; + coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2; + coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = scc->physCellId; + coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; + if(coreset0->tci_StatesPDCCH_ToAddList == NULL) coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList)); + NR_TCI_StateId_t *tci[8]; + for (int i=0;i<8;i++) { + tci[i]=calloc(1,sizeof(*tci[i])); + *tci[i] = i; + ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]); + } + coreset0->tci_StatesPDCCH_ToReleaseList = NULL; + coreset0->tci_PresentInDCI = NULL; + coreset0->pdcch_DMRS_ScramblingID = NULL; + scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset0; // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = CALLOC(1,sizeof(NR_SearchSpaceId_t)); @@ -1014,20 +1045,23 @@ int RCconfig_nr_gtpu(void ) { MessageDef *message; if (gnb_mode == 1) { // NSA - AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,""); + message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ); + AssertFatal(message!=NULL,""); // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U; } else {// TODO SA - AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ))!=NULL,""); + message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ); + AssertFatal(message!=NULL,""); IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" ); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up); GTPV1U_GNB_NG_REQ(message).gnb_port_for_NGu_up = gnb_port_for_NGU; } - - itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address); + sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU); + itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else LOG_E(GTPU,"invalid address for NGU\n"); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 8b326d58c9..0bf7cb3892 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -324,12 +324,12 @@ typedef enum { /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ #define GNBNETPARAMS_DESC { \ -{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \ -{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0} \ } diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 781347abaa..71f91a67ec 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -337,7 +337,8 @@ config_sib2(int Mod_idP, LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreqP, long *ul_BandwidthP, LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, - struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP, + int dl_Bandwidth) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; @@ -345,7 +346,7 @@ config_sib2(int Mod_idP, cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; cfg->num_tlv++; - cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; + cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[dl_Bandwidth]; cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG; cfg->num_tlv++; cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; @@ -870,7 +871,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, radioResourceConfigCommon_BR, NULL, ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); + mbsfn_SubframeConfigList, + mib->message.dl_Bandwidth); } // mib != NULL if (mobilityControlInfo !=NULL) { diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index 1c5e706218..79202d87e3 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -85,10 +85,6 @@ void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) { ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure } -int32_t **rxdata; -int32_t **txdata; - - int rrc_mac_config_req_ue(module_id_t Mod_idP, int CC_idP, diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h index 517f01d1b9..78524e104d 100644 --- a/openair2/LAYER2/MAC/defs_NB_IoT.h +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -537,9 +537,6 @@ typedef struct { // global variables -nprach_parameters_NB_IoT_t nprach_list[3]; -//DLSF Table -DLSF_INFO_t DLSF_information; #endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index f3a77ed703..1272b16ec0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -84,7 +84,7 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, static uint32_t bytes_in_buffer=0; static uint32_t msi_pmch_stop=0; -uint16_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; +rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; static uint32_t msi_sfs=0; diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index cee6066a9e..cda64ec0e9 100644 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -65,6 +65,7 @@ extern const int cqi_to_mcs[16]; extern uint32_t RRC_CONNECTION_FLAG; extern uint8_t rb_table[34]; +extern rb_id_t mbms_rab_id; #if defined(PRE_SCD_THREAD) @@ -77,4 +78,5 @@ extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; extern mac_rlc_am_muilist_t rlc_am_mui; extern SCHEDULER_MODES global_scheduler_mode; +extern rb_id_t mbms_rab_id; #endif //DEF_H diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 0dedacb11f..9ae8f82a00 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -72,7 +72,7 @@ extern UL_IND_t *UL_INFO; extern int next_ra_frame; extern module_id_t next_Mod_id; -int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; +rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; static int mbms_mch_i=0; //static int num_msi_per_CSA[28]; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 67cf5051ef..ba12d9c5c3 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -335,12 +335,12 @@ typedef struct { #define DL_SCH_LCID_CON_RES_ID 0x3E #define DL_SCH_LCID_PADDING 0x3F -#define UL_SCH_LCID_CCCH 0x00 +#define UL_SCH_LCID_CCCH1 0x00 #define UL_SCH_LCID_SRB1 0x01 #define UL_SCH_LCID_SRB2 0x02 #define UL_SCH_LCID_SRB3 0x03 #define UL_SCH_LCID_DTCH 0x04 -#define UL_SCH_LCID_CCCH_MSG3 0x21 +#define UL_SCH_LCID_CCCH 0x34 #define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 #define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 #define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 941bd04877..7140279a03 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -125,6 +125,152 @@ const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 }; +// for PDSCH from TS 38.214 subclause 5.1.2.1.1 +const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[16][3]={ + {0,2,12}, // row index 1 + {0,2,10}, // row index 2 + {0,2,9}, // row index 3 + {0,2,7}, // row index 4 + {0,2,5}, // row index 5 + {0,9,4}, // row index 6 + {0,4,4}, // row index 7 + {0,5,7}, // row index 8 + {0,5,2}, // row index 9 + {0,9,2}, // row index 10 + {0,12,2}, // row index 11 + {0,1,13}, // row index 12 + {0,1,6}, // row index 13 + {0,2,4}, // row index 14 + {0,4,7}, // row index 15 + {0,8,4} // row index 16 +}; +const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[16][3]={ + {0,3,11}, // row index 1 + {0,3,9}, // row index 2 + {0,3,8}, // row index 3 + {0,3,6}, // row index 4 + {0,3,4}, // row index 5 + {0,10,4}, // row index 6 + {0,6,4}, // row index 7 + {0,5,7}, // row index 8 + {0,5,2}, // row index 9 + {0,9,2}, // row index 10 + {0,12,2}, // row index 11 + {0,1,13}, // row index 12 + {0,1,6}, // row index 13 + {0,2,4}, // row index 14 + {0,4,7}, // row index 15 + {0,8,4} // row index 16 +}; +const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos2[16][3]={ + {0,2,6}, // row index 1 + {0,2,10}, // row index 2 + {0,2,9}, // row index 3 + {0,2,7}, // row index 4 + {0,2,5}, // row index 5 + {0,6,4}, // row index 6 + {0,4,4}, // row index 7 + {0,5,6}, // row index 8 + {0,5,2}, // row index 9 + {0,9,2}, // row index 10 + {0,10,2}, // row index 11 + {0,1,11}, // row index 12 + {0,1,6}, // row index 13 + {0,2,4}, // row index 14 + {0,4,6}, // row index 15 + {0,8,4} // row index 16 +}; +const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos3[16][3]={ + {0,3,5}, // row index 1 + {0,3,9}, // row index 2 + {0,3,8}, // row index 3 + {0,3,6}, // row index 4 + {0,3,4}, // row index 5 + {0,8,2}, // row index 6 + {0,6,4}, // row index 7 + {0,5,6}, // row index 8 + {0,5,2}, // row index 9 + {0,9,2}, // row index 10 + {0,10,2}, // row index 11 + {0,1,11}, // row index 12 + {0,1,6}, // row index 13 + {0,2,4}, // row index 14 + {0,4,6}, // row index 15 + {0,8,4} // row index 16 +}; +const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos2[16][3]={ + {0,2,2}, // row index 1 + {0,4,2}, // row index 2 + {0,6,2}, // row index 3 + {0,8,2}, // row index 4 + {0,10,2}, // row index 5 + {1,2,2}, // row index 6 + {1,4,2}, // row index 7 + {0,2,4}, // row index 8 + {0,4,4}, // row index 9 + {0,6,4}, // row index 10 + {0,8,4}, // row index 11 + {0,10,4}, // row index 12 + {0,2,7}, // row index 13 + {0,2,12}, // row index 14 + {1,2,4}, // row index 15 + {0,0,0} // row index 16 +}; +const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos3[16][3]={ + {0,2,2}, // row index 1 + {0,4,2}, // row index 2 + {0,6,2}, // row index 3 + {0,8,2}, // row index 4 + {0,10,2}, // row index 5 + {1,2,2}, // row index 6 + {1,4,2}, // row index 7 + {0,2,4}, // row index 8 + {0,4,4}, // row index 9 + {0,6,4}, // row index 10 + {0,8,4}, // row index 11 + {0,10,4}, // row index 12 + {0,2,7}, // row index 13 + {0,3,11}, // row index 14 + {1,2,4}, // row index 15 + {0,0,0} // row index 16 +}; +const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos2[16][3]={ + {0,2,2}, // row index 1 + {0,4,2}, // row index 2 + {0,6,2}, // row index 3 + {0,8,2}, // row index 4 + {0,10,2}, // row index 5 + {0,0,0}, // row index 6 + {0,0,0}, // row index 7 + {0,2,4}, // row index 8 + {0,4,4}, // row index 9 + {0,6,4}, // row index 10 + {0,8,4}, // row index 11 + {0,10,4}, // row index 12 + {0,2,7}, // row index 13 + {0,2,12}, // row index 14 + {0,0,6}, // row index 15 + {0,2,6} // row index 16 +}; +const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos3[16][3]={ + {0,2,2}, // row index 1 + {0,4,2}, // row index 2 + {0,6,2}, // row index 3 + {0,8,2}, // row index 4 + {0,10,2}, // row index 5 + {0,0,0}, // row index 6 + {0,0,0}, // row index 7 + {0,2,4}, // row index 8 + {0,4,4}, // row index 9 + {0,6,4}, // row index 10 + {0,8,4}, // row index 11 + {0,10,4}, // row index 12 + {0,2,7}, // row index 13 + {0,3,11}, // row index 14 + {0,0,6}, // row index 15 + {0,2,6} // row index 16 +}; + const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"}; const char *duplex_mode[]={"FDD","TDD"}; @@ -1017,7 +1163,7 @@ int get_format0(uint8_t index, uint8_t unpaired, frequency_range_t frequency_range){ - uint16_t format; + uint16_t format=0; if (unpaired) { if (frequency_range==FR1) format = table_6_3_3_2_3_prachConfig_Index[index][0]; @@ -2166,8 +2312,8 @@ int get_num_dmrs(uint16_t dmrs_mask ) { return(num_dmrs); } /* returns the total DMRS symbols in a slot*/ -uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols){ - return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols)); +uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol){ + return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols,startSymbol)); } // Table 5.1.2.2.1-1 38.214 @@ -2771,7 +2917,7 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { int slots1=period1*(1<tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0); - else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); + else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); } int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) { @@ -2803,24 +2949,28 @@ int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type int slots1=period1*(1<= scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0); - else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); + else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); } -int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols) { +int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol) { int l0; + int ld = NrOfSymbols+startSymbol; if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2; else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3; else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position); if (pdsch_Config == NULL) { // Initial BWP - return(1<dmrs_DownlinkForPDSCH_MappingTypeA && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) { // Relative to start of slot NR_DMRS_DownlinkConfig_t *dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; - AssertFatal(NrOfSymbols>1 && NrOfSymbols < 15,"Illegal NrOfSymbols %d\n",NrOfSymbols); + AssertFatal(ld>1 && ld < 15,"Illegal l_d %d\n",ld); int pos2=0; if (dmrs_config->maxLength == NULL) { // this is Table 7.4.1.1.2-3: PDSCH DM-RS positions l for single-symbol DM-RS @@ -2829,7 +2979,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i return(1<3,"Illegal NrOfSymbols %d for len2 DMRS\n",NrOfSymbols); - if (NrOfSymbols < 10) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<3,"Illegal l_d %d for len2 DMRS\n",ld); + if (ld < 10) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1< #include "NR_MAC_UE/mac_proto.h" #include "NR_MAC-CellGroupConfig.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" +#include "executables/softmodem-common.h" int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu, @@ -309,8 +311,11 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; else cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839; - - cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart; + if (get_softmodem_params()->sa) { + cfg->prach_config.num_prach_fd_occasions_list[i].k1 = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); + } else { + cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); + } cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range); //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ??? @@ -528,11 +533,13 @@ int nr_rrc_mac_config_req_ue( mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex; config_control_ue(mac); if (cell_group_config->spCellConfig->reconfigurationWithSync) { - ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; - mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - config_common_ue(mac,module_id,cc_idP); - mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; - LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); + if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { + ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + } + mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + config_common_ue(mac,module_id,cc_idP); + mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; + LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); } // Setup the SSB to Rach Occasions mapping according to the config diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 933286f95a..098814498e 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -234,9 +234,12 @@ typedef struct { typedef enum { RA_UE_IDLE = 0, - WAIT_RAR = 1, - WAIT_CONTENTION_RESOLUTION = 2, - RA_SUCCEEDED = 3 + GENERATE_IDLE = 0, + GENERATE_PREAMBLE = 1, + WAIT_RAR = 2, + WAIT_CONTENTION_RESOLUTION = 3, + RA_SUCCEEDED = 4, + RA_FAILED = 5 } RA_state_t; typedef struct { @@ -257,8 +260,10 @@ typedef struct { uint8_t RA_attempt_number; /// Random-access procedure flag uint8_t RA_active; + /// Random-access preamble index + int ra_PreambleIndex; /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot - uint8_t generate_nr_prach; + RA_state_t generate_nr_prach; /// Random-access window counter int16_t RA_window_cnt; @@ -289,6 +294,8 @@ typedef struct { uint8_t RA_contention_resolution_timer_active; /// Random-access Contention Resolution Timer count value uint8_t RA_contention_resolution_cnt; + /// Transmitted UE Contention Resolution Identifier + uint8_t cont_res_id[6]; /// BeamfailurerecoveryConfig NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 14d1ea63fb..394ab58fc7 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -178,7 +178,8 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, - uint8_t time_domain_ind); + uint8_t time_domain_ind, + bool use_default); uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c index 27623fe5be..2f4697c25d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c @@ -146,17 +146,11 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_ServingCellConfigCommon_t *scc = mac->scc; - int8_t receivedTargerPower, delta_preamble; - long preambleReceivedTargetPower = 0; - - if (prach_resources->RA_TYPE == RA_4STEP){ - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; - } else if (prach_resources->RA_TYPE == RA_2STEP){ - // msgA-PreambleReceivedTargetPower - LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__); - } + int8_t receivedTargerPower; + int8_t delta_preamble; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format); receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + prach_resources->POWER_OFFSET_2STEP_RA; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 8f234cb585..080a09ad51 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -64,6 +64,8 @@ void init_RA(module_id_t mod_id, RA_config_t *ra = &mac->ra; ra->RA_active = 1; + ra->ra_PreambleIndex = -1; + ra->RA_usedGroupA = 1; ra->RA_RAPID_found = 0; ra->preambleTransMax = 0; ra->first_Msg3 = 1; @@ -79,8 +81,8 @@ void init_RA(module_id_t mod_id, if (rach_ConfigDedicated) { if (rach_ConfigDedicated->cfra){ - LOG_I(MAC, "Initialization of 4-step contention-free random access procedure\n"); - prach_resources->RA_TYPE = RA_4STEP; + LOG_I(MAC, "Initialization of 2-step contention-free random access procedure\n"); + prach_resources->RA_TYPE = RA_2STEP; ra->cfra = 1; } else if (rach_ConfigDedicated->ext1){ if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){ @@ -93,161 +95,152 @@ void init_RA(module_id_t mod_id, } else { LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__); } + } else if (nr_rach_ConfigCommon){ + LOG_I(MAC, "Initialization of 4-step contention-based random access procedure\n"); + prach_resources->RA_TYPE = RA_4STEP; + ra->cfra = 0; } else { LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__); } - if (prach_resources->RA_TYPE == RA_2STEP){ - LOG_E(MAC, "Missing implementation of initialization of 2-step RA specific variables...\n"); - } else if (prach_resources->RA_TYPE == RA_4STEP){ - LOG_D(MAC, "Initialization of 4-step RA specific variables...\n"); - switch (rach_ConfigGeneric->powerRampingStep){ // in dB - case 0: + switch (rach_ConfigGeneric->powerRampingStep){ // in dB + case 0: prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0; break; - case 1: + case 1: prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2; break; - case 2: + case 2: prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4; break; - case 3: + case 3: prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6; break; - } - - switch (rach_ConfigGeneric->preambleTransMax) { - case 0: - ra->preambleTransMax = 3; - break; - case 1: - ra->preambleTransMax = 4; - break; - case 2: - ra->preambleTransMax = 5; - break; - case 3: - ra->preambleTransMax = 6; - break; - case 4: - ra->preambleTransMax = 7; - break; - case 5: - ra->preambleTransMax = 8; - break; - case 6: - ra->preambleTransMax = 10; - break; - case 7: - ra->preambleTransMax = 20; - break; - case 8: - ra->preambleTransMax = 50; - break; - case 9: - ra->preambleTransMax = 100; - break; - case 10: - ra->preambleTransMax = 200; - break; - } - if (nr_rach_ConfigCommon->ext1) { - if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){ - LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__); - } - } } - return; + switch (rach_ConfigGeneric->preambleTransMax) { + case 0: + ra->preambleTransMax = 3; + break; + case 1: + ra->preambleTransMax = 4; + break; + case 2: + ra->preambleTransMax = 5; + break; + case 3: + ra->preambleTransMax = 6; + break; + case 4: + ra->preambleTransMax = 7; + break; + case 5: + ra->preambleTransMax = 8; + break; + case 6: + ra->preambleTransMax = 10; + break; + case 7: + ra->preambleTransMax = 20; + break; + case 8: + ra->preambleTransMax = 50; + break; + case 9: + ra->preambleTransMax = 100; + break; + case 10: + ra->preambleTransMax = 200; + break; + } + if (nr_rach_ConfigCommon->ext1) { + if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){ + LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__); + } + } } void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){ // Determine the SSB to RACH mapping ratio // ======================================= - if (prach_resources->RA_TYPE == RA_4STEP){ - NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB - uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB - int total_preambles_per_ssb; - uint8_t ssb_nb_in_ro; - int numberOfRA_Preambles = 64; - switch (ssb_perRACH_config){ - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: - multiple_ssb_per_ro = false; - ssb_rach_ratio = 8; - ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: - multiple_ssb_per_ro = false; - ssb_rach_ratio = 4; - ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: - multiple_ssb_per_ro = false; - ssb_rach_ratio = 2; - ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 1; - ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 2; - ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 4; - ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 8; - ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 16; - ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; - break; - default: - AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); - break; - } + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB + int total_preambles_per_ssb; + uint8_t ssb_nb_in_ro; + int numberOfRA_Preambles = 64; - if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles) - numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles); + switch (ssb_perRACH_config){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 8; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 4; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 2; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 1; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 2; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 4; + ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 8; + ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 16; + ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); + } - // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration - if ((true == multiple_ssb_per_ro) && - (ssb_rach_ratio > 1)) { - total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio; + if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles) + numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles); - ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro; - ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro; - } - else { - total_preambles_per_ssb = numberOfRA_Preambles; - ra->starting_preamble_nb = 0; - } + // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration + if ((true == multiple_ssb_per_ro) && (ssb_rach_ratio > 1)) { + total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio; + + ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro; + ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro; } else { - LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__); + total_preambles_per_ssb = numberOfRA_Preambles; + ra->starting_preamble_nb = 0; } } -// This routine implements RA premable configuration according to +// This routine implements RA preamble configuration according to // section 5.1 (Random Access procedure) of 3GPP TS 38.321 version 16.2.1 Release 16 void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac, int16_t dl_pathloss){ int messageSizeGroupA = 0; int sizeOfRA_PreamblesGroupA = 0; int messagePowerOffsetGroupB = 0; - int PLThreshold; + int PLThreshold = 0; long deltaPreamble_Msg3 = 0; uint8_t noGroupB = 0; RA_config_t *ra = &mac->ra; @@ -255,23 +248,21 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric; - if (prach_resources->RA_TYPE == RA_4STEP){ + if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){ + deltaPreamble_Msg3 = (*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB + LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3); + } - if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){ - deltaPreamble_Msg3 = (*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB - LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3); - } - - if (!nr_rach_ConfigCommon->groupBconfigured) { - noGroupB = 1; - LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__); - } else { - // RA preambles group B is configured - // - Random Access Preambles group B is configured for 4-step RA type - // - Defining the number of RA preambles in RA Preamble Group A for each SSB - LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__); - sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA; - switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){ + if (!nr_rach_ConfigCommon->groupBconfigured) { + noGroupB = 1; + LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__); + } else { + // RA preambles group B is configured + // - Random Access Preambles group B is configured for 4-step RA type + // - Defining the number of RA preambles in RA Preamble Group A for each SSB + LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__); + sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA; + switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){ /* - Threshold to determine the groups of RA preambles */ case 0: messageSizeGroupA = 56; @@ -337,44 +328,42 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t break; default: AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); - } - - PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; - } - } else { - // todo: - // - groupB-ConfiguredTwoStepRA - // - msgA-DeltaPreamble - LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__); + + PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; + } + /* Msg3 has not been transmitted yet */ if (ra->first_Msg3) { - if (noGroupB) { - // use Group A preamble - prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); - ra->RA_usedGroupA = 1; - } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) { - // Group B is configured and RA preamble Group A is used - // - todo add condition on CCCH_sdu_size for initiation by CCCH - prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); - ra->RA_usedGroupA = 1; - } else { - // Group B preamble is configured and used - // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A - // the remaining belong to RA Preambles Group B - prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); - ra->RA_usedGroupA = 0; + if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) { + if (noGroupB) { + // use Group A preamble + ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); + ra->RA_usedGroupA = 1; + } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) { + // Group B is configured and RA preamble Group A is used + // - todo add condition on CCCH_sdu_size for initiation by CCCH + ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); + ra->RA_usedGroupA = 1; + } else { + // Group B preamble is configured and used + // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A + // the remaining belong to RA Preambles Group B + ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); + ra->RA_usedGroupA = 0; + } } } else { // Msg3 is being retransmitted if (ra->RA_usedGroupA && noGroupB) { - prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); + ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); } else if (ra->RA_usedGroupA && !noGroupB){ - prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); + ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); } else { - prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); + ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); } } + prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex; } // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) @@ -472,6 +461,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint // start contention resolution timer ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8; ra->RA_contention_resolution_timer_active = 1; + ra->ra_state = WAIT_CONTENTION_RESOLUTION; } @@ -503,7 +493,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; - uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload; + uint8_t lcid = UL_SCH_LCID_CCCH; + uint8_t *payload; uint16_t size_sdu = 0; unsigned short post_padding; NR_ServingCellConfigCommon_t *scc = mac->scc; @@ -527,7 +518,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } } - if (prach_resources->init_msg1) { + if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) { if (ra->RA_active == 0) { /* RA not active - checking if RRC is ready to initiate the RA procedure */ @@ -557,6 +548,11 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, if (size_sdu > 0) { + // UE Contention Resolution Identity + // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the + // Random Access Procedure has been successful after reception of Msg4 + memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6); + LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx); ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); @@ -566,7 +562,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, nr_get_RA_window(mac); // Fill in preamble and PRACH resources - if (ra->generate_nr_prach == 1) + if (ra->generate_nr_prach == GENERATE_PREAMBLE) nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer @@ -614,9 +610,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) { - // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213) - nr_ra_succeeded(mod_id, frame, nr_slot_tx); + if(ra->cfra) { + // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213) + nr_ra_succeeded(mod_id, frame, nr_slot_tx); + } else { + ra->generate_nr_prach = GENERATE_IDLE; + } } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) { @@ -638,7 +638,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, ra->RA_backoff_cnt--; - if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == 1) || ra->RA_backoff_cnt == 0){ + if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0){ nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); } @@ -650,7 +650,11 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources); } - return ra->generate_nr_prach; + if(ra->generate_nr_prach != GENERATE_IDLE) { + return ra->generate_nr_prach; + } else { + return ra->ra_state; + } } @@ -744,6 +748,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot); ra->RA_window_cnt = -1; + mac->crnti = ra->t_crnti; } else { @@ -751,6 +756,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ ra->RA_contention_resolution_cnt = -1; ra->RA_contention_resolution_timer_active = 0; + mac->crnti = ra->t_crnti; ra->t_crnti = 0; LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot); @@ -759,7 +765,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id); ra->RA_active = 0; - ra->generate_nr_prach = 2; + ra->generate_nr_prach = GENERATE_IDLE; ra->ra_state = RA_SUCCEEDED; } @@ -774,8 +780,9 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - ra->first_Msg3 = 0; - ra->generate_nr_prach = 3; + ra->first_Msg3 = 1; + ra->ra_PreambleIndex = -1; + ra->generate_nr_prach = RA_FAILED; ra->ra_state = RA_UE_IDLE; prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 11edc6c20d..206788598f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -88,7 +88,11 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t } else { ss = mac->search_space_zero; coreset = mac->coreset0; - rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + if(rnti_type == NR_RNTI_SI) { + rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + } else { + rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0; + } } rel15->coreset.duration = coreset->duration; @@ -144,7 +148,11 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); rel15->rnti = ra->ra_rnti; rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + if (get_softmodem_params()->sa) { + rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } else { // NSA mode is not using the Initial BWP + rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id); break; @@ -153,6 +161,14 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t case NR_RNTI_CS: break; case NR_RNTI_TC: + // we use the initial DL BWP + sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = ra->t_crnti; + rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; + rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_TC, rel15->BWPSize, bwp_id); break; case NR_RNTI_SP_CSI: break; @@ -245,14 +261,22 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){ switch(ra->ra_state){ case WAIT_RAR: - LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n"); - rel15->num_dci_options = 1; - rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; - config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id); - fill_dci_search_candidates(ss, rel15); - break; + LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg2)\n"); + rel15->num_dci_options = 1; + rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; + if (get_softmodem_params()->sa) { + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, -1); + } else { + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id); + } + fill_dci_search_candidates(ss, rel15); + break; case WAIT_CONTENTION_RESOLUTION: - LOG_E(MAC, "In %s: CB-RA not implemented yet. Should not have fallen in this case.\n", __FUNCTION__); + LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg4)\n"); + rel15->num_dci_options = 1; + rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_TC, -1); + fill_dci_search_candidates(ss, rel15); break; default: break; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 8b8fc4e0c2..78328e3888 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -73,10 +73,10 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){ if (rnti == ra->ra_rnti) { rnti_type = NR_RNTI_RA; + } else if (rnti == ra->t_crnti && (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ) { + rnti_type = NR_RNTI_TC; } else if (rnti == mac->crnti) { rnti_type = NR_RNTI_C; - } else if (rnti == ra->t_crnti) { - rnti_type = NR_RNTI_TC; } else if (rnti == 0xFFFE) { rnti_type = NR_RNTI_P; } else if (rnti == 0xFFFF) { @@ -106,7 +106,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_ServingCellConfigCommon_t *scc = mac->scc; frequency_range_t frequency_range; - nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU + nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); //if(mac->mib != NULL){ @@ -188,7 +188,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint8_t *pduP, uint32_t pdu_len) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); - nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); + nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); return 0; } @@ -264,85 +264,15 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, - uint8_t time_domain_ind - ){ + uint8_t time_domain_ind, + bool use_default){ + int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position; // uint8_t k_offset=0; uint8_t sliv_S=0; uint8_t sliv_L=0; - uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?12:11}, // row index 1 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?10:9}, // row index 2 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?9:8}, // row index 3 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?7:6}, // row index 4 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?5:4}, // row index 5 - {0,(dmrs_typeA_pos == 0)?9:10,(dmrs_typeA_pos == 0)?4:4}, // row index 6 - {0,(dmrs_typeA_pos == 0)?4:6, (dmrs_typeA_pos == 0)?4:4}, // row index 7 - {0,5,7}, // row index 8 - {0,5,2}, // row index 9 - {0,9,2}, // row index 10 - {0,12,2}, // row index 11 - {0,1,13}, // row index 12 - {0,1,6}, // row index 13 - {0,2,4}, // row index 14 - {0,4,7}, // row index 15 - {0,8,4} // row index 16 - }; - /*uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?6:5}, // row index 1 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?10:9}, // row index 2 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?9:8}, // row index 3 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?7:6}, // row index 4 - {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?5:4}, // row index 5 - {0,(dmrs_typeA_pos == 0)?6:8, (dmrs_typeA_pos == 0)?4:2}, // row index 6 - {0,(dmrs_typeA_pos == 0)?4:6, (dmrs_typeA_pos == 0)?4:4}, // row index 7 - {0,5,6}, // row index 8 - {0,5,2}, // row index 9 - {0,9,2}, // row index 10 - {0,10,2}, // row index 11 - {0,1,11}, // row index 12 - {0,1,6}, // row index 13 - {0,2,4}, // row index 14 - {0,4,6}, // row index 15 - {0,8,4} // row index 16 - };*/ - /*uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 - {0,2,2}, // row index 1 - {0,4,2}, // row index 2 - {0,6,2}, // row index 3 - {0,8,2}, // row index 4 - {0,10,2}, // row index 5 - {1,2,2}, // row index 6 - {1,4,2}, // row index 7 - {0,2,4}, // row index 8 - {0,4,4}, // row index 9 - {0,6,4}, // row index 10 - {0,8,4}, // row index 11 - {0,10,4}, // row index 12 - {0,2,7}, // row index 13 - {0,(dmrs_typeA_pos == 0)?2:3,(dmrs_typeA_pos == 0)?12:11}, // row index 14 - {1,2,4}, // row index 15 - {0,0,0} // row index 16 - };*/ - /*uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 - {0,2,2}, // row index 1 - {0,4,2}, // row index 2 - {0,6,2}, // row index 3 - {0,8,2}, // row index 4 - {0,10,2}, // row index 5 - {0,0,0}, // row index 6 - {0,0,0}, // row index 7 - {0,2,4}, // row index 8 - {0,4,4}, // row index 9 - {0,6,4}, // row index 10 - {0,8,4}, // row index 11 - {0,10,4}, // row index 12 - {0,2,7}, // row index 13 - {0,(dmrs_typeA_pos == 0)?2:3,(dmrs_typeA_pos == 0)?12:11}, // row index 14 - {0,0,6}, // row index 15 - {0,2,6} // row index 16 - };*/ uint8_t mu_pusch = 1; + // definition table j Table 6.1.2.1.1-4 uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1; uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1 @@ -391,7 +321,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup; else if (mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - if (pdsch_TimeDomainAllocationList) { + if (pdsch_TimeDomainAllocationList && use_default==false) { if (time_domain_ind >= pdsch_TimeDomainAllocationList->list.count) { LOG_E(MAC, "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n", @@ -414,8 +344,15 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, } else {// Default configuration from tables // k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; - sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; - sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; + + if(dmrs_typeA_pos == 0) { + sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[time_domain_ind][1]; + sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[time_domain_ind][2]; + } else { + sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[time_domain_ind][1]; + sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[time_domain_ind][2]; + } + // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; @@ -440,7 +377,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; } - if (pusch_TimeDomainAllocationList) { + if (pusch_TimeDomainAllocationList && use_default==false) { if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) { LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n", time_domain_ind, pusch_TimeDomainAllocationList->list.count); @@ -457,8 +394,8 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, } else { // k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; - sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; - sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; + sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][1]; + sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][2]; // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; @@ -497,7 +434,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); AssertFatal(mac->ULbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); - const uint16_t n_RB_DLBWP = (ra->ra_state == WAIT_RAR) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t n_RB_DLBWP = (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); LOG_D(MAC, "In %s: Processing received DCI format %s (DL BWP %d)\n", __FUNCTION__, dci_formats[dci_format], n_RB_DLBWP); @@ -543,10 +480,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr // Config PUSCH PDU ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - if (ret != -1 && ra->RA_active && mac->crnti){ - nr_ra_succeeded(module_id, frame, slot); - } - } break; @@ -606,10 +539,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr // Config PUSCH PDU ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - if (ret != -1 && ra->RA_active && mac->crnti){ - nr_ra_succeeded(module_id, frame, slot); - } - } break; } @@ -668,7 +597,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; - NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; + NR_PDSCH_Config_t *pdsch_config = NULL; uint16_t BWPSize = 0; if(rnti == SI_RNTI) { @@ -676,7 +605,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs; dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb; dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; - pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2' BWPSize = dlsch_config_pdu_1_0->BWPSize; } else { if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){ @@ -684,9 +612,20 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr } else { dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; } - dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + if( (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) || (rnti == ra->t_crnti) ) { + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (get_softmodem_params()->sa) { + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } else { // NSA mode is not using the Initial BWP + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; + } + } else { + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; + } BWPSize = n_RB_DLBWP; } @@ -697,15 +636,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr return -1; } /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0) { + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val,rnti==SI_RNTI) < 0) { LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); return -1; } /* dmrs symbol positions*/ dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, - dlsch_config_pdu_1_0->start_symbol+dlsch_config_pdu_1_0->number_symbols); - dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; + dlsch_config_pdu_1_0->number_symbols, + dlsch_config_pdu_1_0->start_symbol); + dlsch_config_pdu_1_0->dmrsConfigType = (pdsch_config) ? (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */ if (dlsch_config_pdu_1_0->number_symbols == 2) dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1; @@ -714,7 +654,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr /* VRB_TO_PRB_MAPPING */ dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; /* MCS TABLE INDEX */ - dlsch_config_pdu_1_0->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0; + dlsch_config_pdu_1_0->mcs_table = (pdsch_config) ? ((pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0) : 0; /* MCS */ dlsch_config_pdu_1_0->mcs = dci->mcs; // Basic sanity check for MCS value to check for a false or erroneous DCI @@ -767,7 +707,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr } /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/ - dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = dci->pdsch_to_harq_feedback_timing_indicator.val; + dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = mac->ULbwp[mac->UL_BWP_Id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0]; LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n", dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti, @@ -797,6 +737,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); dl_config->number_pdus = dl_config->number_pdus + 1; + break; } @@ -862,14 +803,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr return -1; } /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0) { + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val,false) < 0) { LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); return -1; } /* dmrs symbol positions*/ dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, - dlsch_config_pdu_1_1->number_symbols); + dlsch_config_pdu_1_1->number_symbols, + dlsch_config_pdu_1_1->start_symbol); dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214, using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */ @@ -1333,7 +1275,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, } //end else break; - + case NR_RNTI_P: /* // Short Messages Indicator  E2 bits @@ -1402,41 +1344,74 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, break; case NR_RNTI_TC: - // indicating a DL DCI format 1bit + + // indicating a DL DCI format - 1 bit pos++; dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 0) return 1; // discard dci, format indicator not corresponding to dci_format - // Freq domain assignment 0-16 bit + + // Freq domain assignment 0-16 bit fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos+=fsize; dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; - // VRB to PRB mapping 1 bit + + // VRB to PRB mapping - 1 bit + pos++; dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1; + // MCS 5bit //bit over 32, so dci_pdu ++ pos+=5; dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; - // New data indicator 1bit + + // New data indicator - 1 bit + pos++; dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1; - // Redundancy version 2bit + + // Redundancy version - 2 bits pos+=2; dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3; - // HARQ process number 4bit + + // HARQ process number - 4 bits pos+=4; dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; - // Downlink assignment index  E2 bits + + // Downlink assignment index - 2 bits pos+=2; dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3; - // TPC command for scheduled PUCCH  E2 bits + + // TPC command for scheduled PUCCH - 2 bits pos+=2; dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; - // PDSCH-to-HARQ_feedback timing indicator  E3 bits + + // PUCCH resource indicator - 3 bits + pos+=3; + dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&7; + + // PDSCH-to-HARQ_feedback timing indicator - 3 bits pos+=3; dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&7; - + + LOG_D(NR_MAC,"N_RB = %i\n", N_RB); + LOG_D(NR_MAC,"dci_size = %i\n", dci_size); + LOG_D(NR_MAC,"fsize = %i\n", fsize); + LOG_D(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator); + LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid); + LOG_D(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val); + LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc); + LOG_D(NR_MAC,"dci_pdu_rel15->pucch_resource_indicator = %i\n", dci_pdu_rel15->pucch_resource_indicator); + LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val); + break; } break; @@ -1800,16 +1775,41 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, // MAC CE case DL_SCH_LCID_CCCH: - // MSG4 RRC Connection Setup 38.331 - // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; + // MSG4 RRC Setup 38.331 + // variable length + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff); + mac_subheader_len = 3; + } else { + mac_sdu_len = ((NR_MAC_SUBHEADER_SHORT *) pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; - mac_subheader_len = 3; - } + } + // Check if it is a valid CCCH message, we get all 00's messages very often + int i = 0; + for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) { + if(pduP[i] != 0) { + break; + } + } + if (i == (mac_subheader_len+mac_sdu_len)) { + LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len); + done = 1; break; + } + + if ( mac_sdu_len > 0 ) { + LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len); + for (int i = 0; i < mac_subheader_len; i++) { + LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]); + } + for (int i = 0; i < mac_sdu_len; i++) { + LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]); + } + nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len); + } + break; case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH: @@ -1916,17 +1916,34 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, break; case DL_SCH_LCID_CON_RES_ID: - // Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16 - // WIP todo: handle CCCH_pdu - mac_ce_len = 6; - - LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pduP[0], pduP[1], pduP[2], pduP[3], pduP[4], pduP[5]); + // Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16 + // MAC Header: 1 byte (R/R/LCID) + // MAC SDU: 6 bytes (UE Contention Resolution Identity) + mac_ce_len = 6; - if (ra->RA_active == 1) { - nr_ra_succeeded(module_idP, frameP, slot); + if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) { + LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n", + module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]); + + bool ra_success = true; + for(int i = 0; icont_res_id[i] != pduP[i+1]) { + ra_success = false; + break; + } } - break; + if ( (ra->RA_active == 1) && ra_success) { + nr_ra_succeeded(module_idP, frameP, slot); + } else if (!ra_success){ + // TODO: Handle failure of RA procedure @ MAC layer + // nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure + ra->ra_state = RA_UE_IDLE; + ra->RA_active = 0; + } + } + + break; case DL_SCH_LCID_PADDING: done = 1; // end of MAC PDU, can ignore the rest. @@ -2044,8 +2061,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, last_size = 3; } } else { // UL CCCH SDU - mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + last_size = 1; } mac_pdu_ptr += last_size; @@ -2221,27 +2239,32 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer uint8_t preamble_index = get_ra_PreambleIndex(mod_id, cc_id, gNB_id); //prach_resources->ra_PreambleIndex; - LOG_D(MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index); + LOG_D(NR_MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index); while (1) { n_subheaders++; if (rarh->T == 1) { n_subPDUs++; - LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id); + LOG_I(NR_MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id); } else { - n_subPDUs++; ra->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; ra->RA_BI_found = 1; - LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ra->RA_backoff_indicator); + LOG_I(NR_MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d ms\n", mod_id, ra->RA_backoff_indicator); + if ( ((NR_RA_HEADER_BI *)rarh)->E == 1) { + rarh += sizeof(NR_RA_HEADER_BI); + continue; + } else { + break; + } } if (rarh->RAPID == preamble_index) { - LOG_I(MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); + LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); ra->RA_RAPID_found = 1; break; } if (rarh->E == 0) { - LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match the intended RAPID...\n", mod_id, preamble_index); + LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] Received RAR preamble (%d) doesn't match the intended RAPID (%d)\n", mod_id, frame, slot, rarh->RAPID, preamble_index); break; } else { rarh += sizeof(NR_MAC_RAR) + 1; @@ -2317,21 +2340,37 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t rnti = mac->crnti; } - #ifdef DEBUG_RAR - LOG_D(MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n", - __FUNCTION__, - frame, - slot, - mod_id, - rar_grant.Msg3_t_alloc, - rar_grant.Msg3_f_alloc, - ul_time_alignment->ta_command, - rar_grant.mcs, - rar_grant.freq_hopping, - tpc_command, - csi_req, - ra->t_crnti); - #endif +#ifdef DEBUG_RAR + LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E); + LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T); + LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID); + + LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R); + LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1); + + LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2); + LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1); + + LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2); + LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3); + LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4); + + LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1); + LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2); + + LOG_I(NR_MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d t_crnti %x \n", + __FUNCTION__, + frame, + slot, + mod_id, + rar_grant.Msg3_t_alloc, + rar_grant.Msg3_f_alloc, + ul_time_alignment->ta_command, + rar_grant.mcs, + rar_grant.freq_hopping, + tpc_command, + ra->t_crnti); +#endif // Schedule Msg3 ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, rar_grant.Msg3_t_alloc); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 844ee95d32..1295b3049b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -500,11 +500,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); // BWP start selection according to 8.3 of TS 38.213 - pusch_config_pdu->bwp_size = ibwp_size; - if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) + if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) { pusch_config_pdu->bwp_start = abwp_start; - else + pusch_config_pdu->bwp_size = abwp_size; + } else { pusch_config_pdu->bwp_start = ibwp_start; + pusch_config_pdu->bwp_size = ibwp_size; + } //// Resource assignment from RAR // Frequency domain allocation according to 8.3 of TS 38.213 @@ -518,7 +520,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, return -1; // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211) - pusch_config_pdu->rb_start += ibwp_start - abwp_start; + //pusch_config_pdu->rb_start += ibwp_start - abwp_start; // Time domain allocation SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); @@ -645,7 +647,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, return -1; } /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val) < 0) { + if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val,false) < 0) { return -1; } @@ -887,7 +889,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; - if (ra->ra_state == WAIT_RAR){ + if (ra->ra_state == WAIT_RAR && !ra->cfra){ memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n"); for (int k = 0; k < TBS_bytes; k++) { @@ -941,7 +943,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in tx_req.tx_request_body[0].pdu_index = j; tx_req.tx_request_body[0].pdu = ulsch_input_buffer; - if (ra->ra_state != RA_SUCCEEDED && !ra->cfra){ + if (ra->ra_state == WAIT_RAR && !ra->cfra){ + LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n"); nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index); } @@ -981,7 +984,7 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon - uint8_t k2; + int k2; if (is_Msg3) { k2 = *pusch_TimeDomainAllocationList->list.array[tda_id]->k2; @@ -1668,7 +1671,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; ra->RA_offset = 2; // to compensate the rx frame offset at the gNB - ra->generate_nr_prach = 0; // Reset flag for PRACH generation + ra->generate_nr_prach = GENERATE_IDLE; // Reset flag for PRACH generation if (is_nr_UL_slot(scc, slotP, mac->frame_type)) { @@ -1685,7 +1688,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) { AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); - ra->generate_nr_prach = 1; + ra->generate_nr_prach = GENERATE_PREAMBLE; format = prach_occasion_info_p->format; format0 = format & 0xff; // single PRACH format diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index d0a8037307..d4bcc2adbc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -208,8 +208,12 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839; cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.tl.tag = NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG; cfg->num_tlv++; - cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); -//k1= msg1_FrequencyStart + 12 (no. of FDM)(RB for PRACH occasion); + cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); + if (get_softmodem_params()->sa) { + cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); + } else { + cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); + } cfg->prach_config.num_prach_fd_occasions_list[i].k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG; cfg->num_tlv++; cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; @@ -449,6 +453,13 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, } } } + } else { + ra->cfra = false; + ra->rnti = 0; + ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES; + ra->preambles.preamble_list = (uint8_t *) malloc(MAX_NUM_NR_PRACH_PREAMBLES*sizeof(uint8_t)); + for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++) + ra->preambles.preamble_list[i] = i; } LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti); } else { // secondaryCellGroup has been updated diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index bc297225af..e051bb5f9d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -65,7 +65,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP, uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; - uint8_t total_RApreambles = 64; + uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES; if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; @@ -130,7 +130,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP, } } - LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", + LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles); return index; @@ -227,7 +227,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) { cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion; cc->num_active_ssb = num_active_ssb; - LOG_I(MAC, + LOG_I(NR_MAC, "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n", cc->total_prach_occasions, cc->num_active_ssb, @@ -313,7 +313,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP format0, scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig); - LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n", + LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n", frameP, slotP, prach_occasion_id, prach_pdu->num_ra, prach_pdu->prach_start_symbol, @@ -444,19 +444,19 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu]; *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot - *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024; // we can't schedule msg2 before sl_ahead since prach int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu]; if ((eff_slot-rach_slot)<=sl_ahead) { *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu]; - *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024; } if (FR==nr_FR2) { int num_tdd_period = *msg2_slot/tdd_period_slot; while((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=beam_index)) { *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu]; - *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024; num_tdd_period = *msg2_slot/tdd_period_slot; } if(tdd_beam_association[num_tdd_period] == -1) @@ -491,13 +491,13 @@ void nr_initiate_ra_proc(module_id_t module_idP, NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - uint8_t total_RApreambles = 64; - uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES; + uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; int pr_found; if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) - total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; - + total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/ num_ssb_per_RO -= 3; total_RApreambles = total_RApreambles/num_ssb_per_RO ; @@ -528,14 +528,15 @@ void nr_initiate_ra_proc(module_id_t module_idP, else ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); - // This should be handled differently when we use the initialBWP for RA ra->bwp_id = 1; - NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList - ->list.array[ra->bwp_id - 1]; + NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP + if(get_softmodem_params()->sa != 1) { + bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - LOG_I(MAC, + LOG_D(NR_MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, @@ -550,26 +551,33 @@ void nr_initiate_ra_proc(module_id_t module_idP, // if the preamble received correspond to one of the listed if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { LOG_E( - MAC, + NR_MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", module_idP, preamble_index); continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc } } - int loop = 0; - LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); + LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); ra->state = Msg2; ra->timing_offset = timing_offset; ra->preamble_slot = slotP; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + NR_SearchSpaceId_t ra_SearchSpace = 0; + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; + if(bwp) { + commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + } else { + commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + } AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + // Common searchspace list for (int i = 0; i < commonSearchSpaceList->list.count; i++) { ss = commonSearchSpaceList->list.array[i]; - if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) + if (ss->searchSpaceId == ra_SearchSpace) ra->ra_ss = ss; } @@ -590,8 +598,11 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra->Msg2_frame = msg2_frame; ra->Msg2_slot = msg2_slot; - LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - if (!ra->cfra) { + LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + + int loop = 0; + // This condition allows for the usage of a preconfigured rnti for the first UE + if (!ra->cfra || ra->rnti == 0) { do { ra->rnti = (taus() % 65518) + 1; loop++; @@ -599,15 +610,16 @@ void nr_initiate_ra_proc(module_id_t module_idP, && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519)); if (loop == 100) { - LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); abort(); } } + ra->RA_rnti = ra_rnti; ra->preamble_index = preamble_index; ra->beam_id = beam_index; - LOG_I(MAC, + LOG_D(NR_MAC, "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB " "index %u\n", module_idP, @@ -621,38 +633,38 @@ void nr_initiate_ra_proc(module_id_t module_idP, return; } } - LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); + LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) -{ - gNB_MAC_INST *mac = RC.nrmac[module_idP]; + void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) + { + gNB_MAC_INST *mac = RC.nrmac[module_idP]; - start_meas(&mac->schedule_ra); - for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - NR_RA_t *ra = &cc->ra[i]; - LOG_D(MAC, "RA[state:%d]\n", ra->state); - switch (ra->state) { - case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); - break; - case Msg4: - // generate_Msg4(module_idP, CC_id, frameP, slotP); - break; - case WAIT_Msg4_ACK: - // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); - break; - default: - break; + start_meas(&mac->schedule_ra); + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); + switch (ra->state) { + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); + break; + case Msg4: + nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra); + break; + case WAIT_Msg4_ACK: + nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); + break; + default: + break; + } } } + stop_meas(&mac->schedule_ra); } - stop_meas(&mac->schedule_ra); -} void nr_get_Msg3alloc(module_id_t module_id, int CC_id, @@ -663,33 +675,33 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_RA_t *ra, int16_t *tdd_beam_association) { - // msg3 is schedulend in mixed slot in the following TDD period + // msg3 is schedulend in mixed slot in the following TDD period - uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes + uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes - int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; - ra->Msg3_tda_id = 16; // initialization to a value above limit + int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; + ra->Msg3_tda_id = 16; // initialization to a value above limit - for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) { - startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); - // we want to transmit in the uplink symbols of mixed slot - if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) { - ra->Msg3_tda_id = i; - break; + for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) { + startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); + // we want to transmit in the uplink symbols of mixed slot + if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) { + ra->Msg3_tda_id = i; + break; + } } - } - AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); + AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); - uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; + uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; - temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 - ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; - if (nr_slots_per_frame[mu]>temp_slot) - ra->Msg3_frame = current_frame; - else - ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]); + temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 + ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; + if (nr_slots_per_frame[mu]>temp_slot) + ra->Msg3_frame = current_frame; + else + ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024; // beam association for FR2 if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { @@ -703,12 +715,12 @@ void nr_get_Msg3alloc(module_id_t module_id, tdd_beam_association[num_tdd_period] = ra->beam_id; } - LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex); + LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex); uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - /* search msg3_nb_rb free RBs */ + /* search msg3_nb_rb free RBs */ int rbSize = 0; int rbStart = 0; while (rbSize < msg3_nb_rb) { @@ -733,7 +745,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; if (ra->state == RA_IDLE) { - LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); + LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); return; } @@ -748,7 +760,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t vrb_map_UL[i + ra->msg3_first_rb] = 1; } - LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot]; AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame @@ -770,7 +782,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; - LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", + LOG_D(NR_MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", frameP, slotP, ra->Msg3_frame, @@ -815,7 +827,8 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 pusch_pdu->resource_alloc = 1; //type 1 - pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211 + //pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211 + pusch_pdu->rb_start = ra->msg3_first_rb; if (ra->msg3_nb_rb > pusch_pdu->bwp_size) AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); else @@ -850,85 +863,87 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { - int mcsIndex; - int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0; - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; - NR_SearchSpace_t *ss = ra->ra_ss; - // This code from this point on will not work on initialBWP or CORESET0 - AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n"); - - AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti); - AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - - uint16_t RA_rnti = ra->RA_rnti; - long locationAndBandwidth; - - // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD - // get the BW of the PDCCH for PDCCH size and RAR PDSCH size - - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int dci10_bw = 0; - - if (ra->coreset0_configured == 1) { - AssertFatal(1==0,"This is a standalone condition\n"); - } - else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP - locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth; - dci10_bw = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE); - } + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + uint8_t time_domain_assignment = 3; + uint8_t mcsIndex = 0; + int rbStart = 0; + int rbSize = 8; + + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_SearchSpace_t *ss = ra->ra_ss; + + long BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP + if(get_softmodem_params()->sa != 1) { + bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + } + + NR_ControlResourceSet_t *coreset = NULL; + if(bwp) { + coreset = get_coreset(bwp, ss, 0); + } else { + coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; + } + + long BWPStart = 0; + if (get_softmodem_params()->sa != 1) { + BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } else { + BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } + uint16_t *vrb_map = cc[CC_id].vrb_map; - int rbStart = 0, rbSize = 6; - for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) { + for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { if (vrb_map[rbStart + i]) { rbStart += i; i = 0; } } - if (rbStart > (dci10_bw - rbSize)) { - LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + + if (rbStart > (BWPSize - rbSize)) { + LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); return; } + // Checking if the DCI allocation is feasible in current subframe nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - // Checking if the DCI allocation is feasible in current subframe: we might - // need to need up to two (PDCCH + PDSCH) messages, so check that we can - // always allocate both (this might be an overestimation, since the PDCCH - // message might already exist) if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti); + LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); return; } - uint8_t nr_of_candidates, aggregation_level; + uint8_t aggregation_level; + uint8_t nr_of_candidates; find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); - NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; - NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */); - int CCEIndex = allocate_nr_CCEs(nr_mac, - bwp, - coreset, - aggregation_level, - 0, // Y - 0, // m - nr_of_candidates); - + int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates); if (CCEIndex < 0) { - LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); + LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); return; } - /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not - * exist, create it. This is especially important if we have multiple RAs, - * and the DLSCH has to reuse them, so we need to mark them */ - const int bwpid = bwp->bwp_Id; + // Calculate number of symbols + int startSymbolIndex, nrOfSymbols; + const int startSymbolAndLength = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated-> + downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup-> + pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n"); + + uint8_t numDmrsCdmGrpsNoData = 2; + if (nrOfSymbols == 2) { + numDmrsCdmGrpsNoData = 1; + } + + // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially + // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them const int coresetid = coreset->controlResourceSetId; - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid]; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid]; if (!pdcch_pdu_rel15) { nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); @@ -937,7 +952,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp); - nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15; + nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15; } nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; @@ -947,49 +962,350 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_req->nPDUs+=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); + LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d\n", + module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state); - NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->RA_rnti); - LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); + AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - // Qm>2 not allowed for RAR - if (get_softmodem_params()->do_ra) - mcsIndex = 9; - else - mcsIndex = 0; - - pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = RA_rnti; - /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control - * message. This is used to associate control information to data and is - * reset every slot. */ + // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control + // information to data and is reset every slot. const int pduindex = nr_mac->pdu_index[CC_id]++; - pdsch_pdu_rel15->pduIndex = pduindex; - - pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; - pdsch_pdu_rel15->CyclicPrefix = 0; - pdsch_pdu_rel15->NrOfCodewords = 1; - pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0); - pdsch_pdu_rel15->qamModOrder[0] = 2; - pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; - if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL) - pdsch_pdu_rel15->mcsTable[0] = 0; + uint8_t mcsTableIdx = 0; + if (bwp==NULL || bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL) + mcsTableIdx = 0; else{ if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) - pdsch_pdu_rel15->mcsTable[0] = 1; + mcsTableIdx = 1; else - pdsch_pdu_rel15->mcsTable[0] = 2; + mcsTableIdx = 2; } + + AssertFatal(numDmrsCdmGrpsNoData == 1 || numDmrsCdmGrpsNoData == 2, + "nr_mac->schedCtrlCommon->numDmrsCdmGrpsNoData %d is not possible", + numDmrsCdmGrpsNoData); + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = ra->RA_rnti; + pdsch_pdu_rel15->pduIndex = pduindex; + pdsch_pdu_rel15->BWPSize = BWPSize; + pdsch_pdu_rel15->BWPStart = BWPStart; + pdsch_pdu_rel15->SubcarrierSpacing = bwp!=NULL ? bwp->bwp_Common->genericParameters.subcarrierSpacing : scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; pdsch_pdu_rel15->rvIndex[0] = 0; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = 0;//Reconfigure Msg2 to use pdsch_dmrs_type1 + pdsch_pdu_rel15->dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; + pdsch_pdu_rel15->VRBtoPRBMapping = 0; + pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, + nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, + nrOfSymbols, + startSymbolIndex); + + int x_Overhead = 0; + uint8_t tb_scaling = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); + + // Fill PDCCH DL DCI PDU + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; + pdcch_pdu_rel15->numDlDci++; + dci_pdu->RNTI = ra->RA_rnti; + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + dci_pdu->AggregationLevel = aggregation_level; + dci_pdu->CceIndex = CCEIndex; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + dci_pdu_rel15_t dci_payload; + dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->BWPSize); + + dci_payload.time_domain_assignment.val = time_domain_assignment; + dci_payload.vrb_to_prb_mapping.val = 0; + dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_payload.tb_scaling = tb_scaling; + + LOG_D(NR_MAC, + "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", + dci_payload.frequency_domain_assignment.val, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->BWPSize, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, + dci_payload.tb_scaling); + + LOG_D(NR_MAC, + "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + pdcch_pdu_rel15->dci_pdu[0].RNTI, + NR_RNTI_RA, + NR_DL_DCI_FORMAT_1_0, + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); + + fill_dci_pdu_rel15(scc, + nr_mac->secondaryCellGroupCommon, + &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], + &dci_payload, + NR_DL_DCI_FORMAT_1_0, + NR_RNTI_RA, + pdsch_pdu_rel15->BWPSize, + ra->bwp_id); + + // DL TX request + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + + // Program UL processing for Msg3 + NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association); + nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); + + if(ra->cfra) { + LOG_I(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + } + + T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP), + T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); + + tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; + tx_req->PDU_index = pduindex; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = tx_req->PDU_length + 2; + nr_mac->TX_req[CC_id].SFN = frameP; + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].Slot = slotP; + + // Mark the corresponding RBs as used + for (int rb = 0; rb < rbSize; rb++) { + vrb_map[rb + rbStart] = 1; + } + + ra->state = WAIT_Msg3; + LOG_I(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + } +} + +void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { + + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + + if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) { + + uint8_t time_domain_assignment = 0; + uint8_t mcsIndex = 0; + + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_SearchSpace_t *ss = ra->ra_ss; + + NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP + if(get_softmodem_params()->sa != 1) { + bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + } + + NR_ControlResourceSet_t *coreset = NULL; + if(bwp) { + coreset = get_coreset(bwp, ss, 0); + } else { + coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; + } + + int UE_id = find_nr_UE_id(module_idP, ra->rnti); + NR_UE_info_t *UE_info = &nr_mac->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + long BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + long BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + // HARQ management + int8_t current_harq_pid = sched_ctrl->dl_harq_pid; + if (current_harq_pid < 0) { + current_harq_pid = sched_ctrl->available_dl_harq.head; + remove_front_nr_list(&sched_ctrl->available_dl_harq); + sched_ctrl->dl_harq_pid = current_harq_pid; + } else { + if (sched_ctrl->harq_processes[current_harq_pid].round == 0) + remove_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + else + remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); + } + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + DevAssert(!harq->is_waiting); + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + harq->is_waiting = true; + ra->harq_pid = current_harq_pid; + + nr_acknack_scheduling(module_idP, UE_id, frameP, slotP); + harq->feedback_slot = sched_ctrl->sched_pucch->ul_slot; + + // Bytes to be transmitted + uint8_t *buf = (uint8_t *) harq->tb; + uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id); + LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length); + uint16_t mac_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, CCCH, ra->rnti, 1, &buf[mac_pdu_length+2]); + ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->R = 0; + ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->F = 0; + ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->LCID = DL_SCH_LCID_CCCH; + ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->L = mac_sdu_length; + mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT); + + LOG_D(NR_MAC,"Encoded RRCSetup Piggyback (%d + 2 bytes), mac_pdu_length %d\n",mac_sdu_length,mac_pdu_length); + + // Calculate number of symbols + int startSymbolIndex, nrOfSymbols; + const int startSymbolAndLength = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated-> + downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup-> + pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n"); + + uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, + nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, + nrOfSymbols, + startSymbolIndex); + + uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos); + + long dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; + uint8_t N_PRB_DMRS = 0; + + AssertFatal(nr_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData == 1 || nr_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData == 2, + "nr_mac->schedCtrlCommon->numDmrsCdmGrpsNoData %d is not possible", + nr_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData); + + if (dmrsConfigType==NFAPI_NR_DMRS_TYPE1) { + N_PRB_DMRS = nr_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; + } + else { + N_PRB_DMRS = nr_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 4; + } + + uint8_t mcsTableIdx = 0; + if (bwp==NULL || bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL) + mcsTableIdx = 0; + else{ + if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) + mcsTableIdx = 1; + else + mcsTableIdx = 2; + } + + int rbStart = 0; + int rbSize = 0; + uint8_t tb_scaling = 0; + uint16_t *vrb_map = cc[CC_id].vrb_map; + do { + rbSize++; + LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",N_PRB_DMRS,N_DMRS_SLOT); + harq->tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), + nr_get_code_rate_dl(mcsIndex, mcsTableIdx), + rbSize, nrOfSymbols, N_PRB_DMRS * N_DMRS_SLOT, 0, tb_scaling,1) >> 3; + } while (rbStart + rbSize < BWPSize && !vrb_map[rbStart + rbSize] && harq->tb_size < mac_pdu_length); + + for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { + if (vrb_map[rbStart + i]) { + rbStart += i; + i = 0; + } + } + + if (rbStart > (BWPSize - rbSize)) { + LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, ra->rnti); + return; + } + + // Checking if the DCI allocation is feasible in current subframe + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { + LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti); + return; + } + + uint8_t aggregation_level; + uint8_t nr_of_candidates; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); + int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates); + if (CCEIndex < 0) { + LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); + return; + } + + // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially + // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them + const int coresetid = coreset->controlResourceSetId; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid]; + if (!pdcch_pdu_rel15) { + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + dl_req->nPDUs += 1; + pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp); + nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15; + } + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + dl_req->nPDUs+=1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); + + AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->rnti); + + AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + + // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control + // information to data and is reset every slot. + const int pduindex = nr_mac->pdu_index[CC_id]++; + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = ra->rnti; + pdsch_pdu_rel15->pduIndex = pduindex; + pdsch_pdu_rel15->BWPSize = BWPSize; + pdsch_pdu_rel15->BWPStart = BWPStart; + pdsch_pdu_rel15->SubcarrierSpacing = bwp!=NULL ? bwp->bwp_Common->genericParameters.subcarrierSpacing : scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round]; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; + pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; @@ -997,23 +1313,13 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->resourceAlloc = 1; pdsch_pdu_rel15->rbStart = rbStart; pdsch_pdu_rel15->rbSize = rbSize; - pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved + pdsch_pdu_rel15->VRBtoPRBMapping = 0; + pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos; - for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) { - startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp); - if (NrOfSymbols_tmp < NrOfSymbols) { - NrOfSymbols = NrOfSymbols_tmp; - StartSymbolIndex = StartSymbolIndex_tmp; - time_domain_assignment = i; // this is short PDSCH added to the config to fit mixed slot - } - } - - AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n"); - - pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols); + int x_Overhead = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1; pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275; @@ -1024,10 +1330,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra /* Fill PDCCH DL DCI PDU */ nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; pdcch_pdu_rel15->numDlDci++; - dci_pdu->RNTI = RA_rnti; - /* TODO: remove next line */ - AssertFatal(ss->searchSpaceType->present != NR_SearchSpace__searchSpaceType_PR_ue_Specific, - "shouldn't the RA SS be common?\n"); + dci_pdu->RNTI = ra->rnti; dci_pdu->ScramblingId = *scc->physCellId; dci_pdu->ScramblingRNTI = 0; dci_pdu->AggregationLevel = aggregation_level; @@ -1037,81 +1340,126 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dci_pdu_rel15_t dci_payload; dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart,dci10_bw); + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->BWPSize); + + dci_payload.format_indicator = 1; dci_payload.time_domain_assignment.val = time_domain_assignment; dci_payload.vrb_to_prb_mapping.val = 0; dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; - dci_payload.tb_scaling = 0; + dci_payload.tb_scaling = tb_scaling; + dci_payload.rv = pdsch_pdu_rel15->rvIndex[0]; + dci_payload.harq_pid = current_harq_pid; + dci_payload.ndi = harq->ndi; + dci_payload.dai[0].val = (sched_ctrl->sched_pucch->dai_c-1)&3; + dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213 + dci_payload.pucch_resource_indicator = sched_ctrl->sched_pucch->resource_indicator; + dci_payload.pdsch_to_harq_feedback_timing_indicator.val = sched_ctrl->sched_pucch->timing_indicator; - LOG_I(MAC, + LOG_D(NR_MAC, "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", dci_payload.frequency_domain_assignment.val, pdsch_pdu_rel15->rbStart, pdsch_pdu_rel15->rbSize, - dci10_bw, + pdsch_pdu_rel15->BWPSize, dci_payload.time_domain_assignment.val, dci_payload.vrb_to_prb_mapping.val, dci_payload.mcs, dci_payload.tb_scaling); - LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti); - - const int dci_format = NR_DL_DCI_FORMAT_1_0; - const int rnti_type = NR_RNTI_RA; - - LOG_I(MAC, - "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + LOG_D(NR_MAC, + "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", pdcch_pdu_rel15->dci_pdu[0].RNTI, - rnti_type, - dci_format, + NR_RNTI_TC, + NR_DL_DCI_FORMAT_1_0, (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, pdcch_pdu_rel15->StartSymbolIndex, pdcch_pdu_rel15->DurationSymbols); fill_dci_pdu_rel15(scc, - ra->secondaryCellGroup, - dci_pdu, + nr_mac->secondaryCellGroupCommon, + &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, - dci_format, - rnti_type, - dci10_bw, + NR_DL_DCI_FORMAT_1_0, + NR_RNTI_TC, + pdsch_pdu_rel15->BWPSize, ra->bwp_id); + // Add padding header and zero rest out if there is space left + if (mac_pdu_length < harq->tb_size) { + NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[mac_pdu_length]; + padding->R = 0; + padding->LCID = DL_SCH_LCID_PADDING; + for(int k = mac_pdu_length+1; ktb_size; k++) { + buf[k] = 0; + } + } + // DL TX request nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; - tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; + memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size); + tx_req->PDU_length = harq->tb_size; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; - tx_req->TLVs[0].length = 8; + tx_req->TLVs[0].length = harq->tb_size + 2; nr_mac->TX_req[CC_id].SFN = frameP; nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].Slot = slotP; - // Program UL processing for Msg3 - nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association); - LOG_I(MAC, "Frame %d, Slot %d: Setting Msg3 reception for Frame %d Slot %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); - nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); - ra->state = WAIT_Msg3; - LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Slot %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + // Mark the corresponding RBs as used + for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) { + vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1; + } - x_Overhead = 0; - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling); + LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); + LOG_D(NR_MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart); + LOG_D(NR_MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing); + LOG_D(NR_MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix); + LOG_D(NR_MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex); + LOG_D(NR_MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols); + for(int n=0;n<6;n++) LOG_D(NR_MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]); + LOG_D(NR_MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType); + LOG_D(NR_MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize); + LOG_D(NR_MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize); + LOG_D(NR_MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType); + LOG_D(NR_MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); + LOG_D(NR_MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); + LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); - T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), - T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */, - T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); - - /* mark the corresponding RBs as used */ - for (int rb = 0; rb < rbSize; rb++) - vrb_map[rb + rbStart] = 1; + ra->state = WAIT_Msg4_ACK; + LOG_I(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); } } -void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){ - - NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0]; - LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); - ra->state = IDLE; +void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) { + + int UE_id = find_nr_UE_id(module_id, ra->rnti); + const int current_harq_pid = ra->harq_pid; + + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid]; + + LOG_D(NR_MAC, "ue %d, rnti %d, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid); + + if (harq->is_waiting == 0) + { + if (harq->round == 0) + { + LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti); + nr_clear_ra_proc(module_id, CC_id, frame, ra); + UE_info->active[UE_id] = true; + } + else + { + ra->state = Msg4; + } + } + +} + +void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra){ + LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); + ra->state = RA_IDLE; ra->timing_offset = 0; ra->RRC_timer = 20; ra->rnti = 0; @@ -1154,9 +1502,10 @@ void nr_fill_rar(uint8_t Mod_idP, uint8_t * dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu){ - LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset); - NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; - NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); + LOG_I(NR_MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset); + NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer; + NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1); + NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2); unsigned char csi_req = 0, tpc_command; //uint8_t N_UL_Hop; uint8_t valid_bits; @@ -1165,6 +1514,16 @@ void nr_fill_rar(uint8_t Mod_idP, tpc_command = 3; // this is 0 dB + /// E/T/R/R/BI subheader /// + // E = 1, MAC PDU includes another MAC sub-PDU (RAPID) + // T = 0, Back-off indicator subheader + // R = 2, Reserved + // BI = 0, 5ms + rarbi->E = 1; + rarbi->T = 0; + rarbi->R = 0; + rarbi->BI = 0; + /// E/T/RAPID subheader /// // E = 0, one only RAR, first and last // T = 1, RAPID @@ -1211,4 +1570,50 @@ void nr_fill_rar(uint8_t Mod_idP, rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff; rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff; +#ifdef DEBUG_RAR + //LOG_I(NR_MAC, "rarbi->E = 0x%x\n", rarbi->E); + //LOG_I(NR_MAC, "rarbi->T = 0x%x\n", rarbi->T); + //LOG_I(NR_MAC, "rarbi->R = 0x%x\n", rarbi->R); + //LOG_I(NR_MAC, "rarbi->BI = 0x%x\n", rarbi->BI); + + LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E); + LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T); + LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID); + + LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R); + LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1); + + LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2); + LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1); + + LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2); + LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3); + LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4); + + LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1); + LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2); +#endif + + int mcs = (unsigned char) (rar->UL_GRANT_4 >> 4); + // time alloc + int Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07); + // frequency alloc + int Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); + // frequency hopping + int freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); + // TA command + int ta_command = rar->TA2 + (rar->TA1 << 5); + // TC-RNTI + int t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); + + LOG_I(NR_MAC, "In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n", + __FUNCTION__, + Msg3_t_alloc, + Msg3_f_alloc, + ta_command, + mcs, + freq_hopping, + tpc_command, + csi_req, + t_crnti); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 444eabb789..3483182088 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -159,7 +159,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, // get MIB every 8 frames if((slotP == 0) && (frameP & 7) == 0) { - mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); + mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]); LOG_D(MAC, "[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", @@ -320,6 +320,7 @@ void schedule_control_sib1(module_id_t module_id, uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; if (gNB_mac->sched_ctrlCommon == NULL){ + LOG_D(NR_MAC,"schedule_control_common: Filling nr_mac->sched_ctrlCommon\n"); gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon)); gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space)); gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset)); @@ -328,7 +329,6 @@ void schedule_control_sib1(module_id_t module_id, fill_default_coresetZero(gNB_mac->sched_ctrlCommon->coreset,servingcellconfigcommon); fill_default_initialDownlinkBWP(gNB_mac->sched_ctrlCommon->active_bwp,servingcellconfigcommon); } - gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; gNB_mac->sched_ctrlCommon->time_domain_allocation = time_domain_allocation; gNB_mac->sched_ctrlCommon->mcsTableIdx = mcsTableIdx; @@ -351,11 +351,15 @@ void schedule_control_sib1(module_id_t module_id, const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs; int rbStart = type0_PDCCH_CSS_config->cset_start_rb; - // Calculate number of symbols - struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength; - int startSymbolIndex, nrOfSymbols; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + int startSymbolIndex = 0; + int nrOfSymbols = 0; + if(gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position == 0) { + startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->time_domain_allocation][1]; + nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->time_domain_allocation][2]; + } else { + startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->time_domain_allocation][1]; + nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->time_domain_allocation][2]; + } if (nrOfSymbols == 2) { gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 1; @@ -365,7 +369,7 @@ void schedule_control_sib1(module_id_t module_id, // Calculate number of PRB_DMRS uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; - uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); + uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex); uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); int rbSize = 0; @@ -380,7 +384,6 @@ void schedule_control_sib1(module_id_t module_id, gNB_mac->sched_ctrlCommon->rbSize = rbSize; gNB_mac->sched_ctrlCommon->rbStart = 0; - LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength); LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex); LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols); LOG_D(MAC,"rbSize = %i\n", gNB_mac->sched_ctrlCommon->rbSize); @@ -454,7 +457,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 1; - pdsch_pdu_rel15->dmrsConfigType = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; + pdsch_pdu_rel15->dmrsConfigType = 0; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData; @@ -469,7 +472,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->StartSymbolIndex+pdsch_pdu_rel15->NrOfSymbols); + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->NrOfSymbols, pdsch_pdu_rel15->StartSymbolIndex); LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos); @@ -537,8 +540,6 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { - LOG_D(MAC,"Schedule_nr_sib1: frameP = %i, slotP = %i\n", frameP, slotP); - // TODO: Get these values from RRC const int CC_id = 0; int time_domain_allocation = 0; @@ -574,29 +575,32 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) (type0_PDCCH_CSS_config->num_rbs > 0) && (type0_PDCCH_CSS_config->active == true)) { - LOG_D(MAC,"> SIB1 transmission\n"); + LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index); // Get SIB1 uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8]; - uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload); - LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length); - LOG_D(MAC,"SIB1: \n"); - for (int i=0;isched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + int startSymbolIndex = 0; + int nrOfSymbols = 0; + if(gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position == 0) { + startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->time_domain_allocation][1]; + nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->time_domain_allocation][2]; + } else { + startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->time_domain_allocation][1]; + nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->time_domain_allocation][2]; + } - // Calculate number of PRB_DMRS - uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; - uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, - gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); - uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); + // Calculate number of PRB_DMRS + uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; + uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex); + uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 30a89cce77..7db4080283 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -302,7 +302,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, return offset; } -int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) { +void getStartNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda, int *startSymbol, int *nrOfSymbols) { struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; AssertFatal(tda < tdaList->list.count, @@ -311,9 +311,7 @@ int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) { tdaList->list.count); const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; - int startSymbolIndex, nrOfSymbols; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - return nrOfSymbols; + SLIV2SL(startSymbolAndLength, startSymbol, nrOfSymbols); } nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) { @@ -487,8 +485,12 @@ void pf_dl(module_id_t module_id, sched_ctrl->numDmrsCdmGrpsNoData = 1; uint8_t N_PRB_DMRS = getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); - int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, - sched_ctrl->time_domain_allocation); + int startSymbol; + int nrOfSymbols; + getStartNrOfSymbols(sched_ctrl->active_bwp, + sched_ctrl->time_domain_allocation, + &startSymbol, + &nrOfSymbols); uint32_t tbs = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), 1, // rbSize @@ -574,13 +576,18 @@ void pf_dl(module_id_t module_id, const uint8_t N_PRB_DMRS = getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); - const int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, - sched_ctrl->time_domain_allocation); + int startSymbol; + int nrOfSymbols; + getStartNrOfSymbols(sched_ctrl->active_bwp, + sched_ctrl->time_domain_allocation, + &startSymbol, + &nrOfSymbols); const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon; const uint8_t N_DMRS_SLOT = get_num_dmrs_symbols( sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, - nrOfSymbols); + nrOfSymbols, + startSymbol); int rbSize = 0; uint32_t TBS = 0; @@ -697,7 +704,8 @@ void nr_schedule_ue_spec(module_id_t module_id, getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, RC.nrmac[module_id]->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position , - nrOfSymbols); + nrOfSymbols, + startSymbolIndex); const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(sched_ctrl->active_bwp); const int nrOfLayers = 1; const uint16_t R = nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx); @@ -806,6 +814,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->qamModOrder[0] = Qm; pdsch_pdu->mcsIndex[0] = sched_ctrl->mcs; pdsch_pdu->mcsTable[0] = sched_ctrl->mcsTableIdx; + AssertFatal(harq->round<4,"%d",harq->round); pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round]; pdsch_pdu->TBSize[0] = TBS; @@ -818,7 +827,8 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, - nrOfSymbols); + nrOfSymbols, + startSymbolIndex); pdsch_pdu->dmrsConfigType = dmrsConfigType; pdsch_pdu->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu->SCID = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 6487f391b9..bf8269132a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -164,7 +164,8 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, - NrOfSymbols); + NrOfSymbols, + StartSymbolIndex); /* AssertFatal(k0==0,"k0 is not zero for Initial DL BWP TimeDomain Alloc\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9db78244ba..d4cf603c4f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -178,7 +178,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int coreset_id = coreset->controlResourceSetId; int *cce_list; - if(bwp->bwp_Id == 0) { + if( bwp==NULL || bwp->bwp_Id == 0 ) { cce_list = nr_mac->cce_list[1][0]; } else { cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id]; @@ -563,6 +563,8 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ServingCellConfigCommon_t *scc, NR_BWP_Downlink_t *bwp) { + int sps = 0; + if (bwp) { // This is not the InitialBWP pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); @@ -571,8 +573,18 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, // first symbol //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); - int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + } + else { // this is for InitialBWP + pdcch_pdu->BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdcch_pdu->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + pdcch_pdu->CyclicPrefix = (scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix==NULL) ? 0 : *scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix; + // first symbol + //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); + sps = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; + } AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n"); AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n"); @@ -617,10 +629,6 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, //precoderGranularity pdcch_pdu->precoderGranularity = coreset->precoderGranularity; - } - else { // this is for InitialBWP - AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n"); - } } @@ -1134,6 +1142,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, break; case NR_RNTI_TC: + pos = 1; // indicating a DL DCI format 1bit *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos++); // Freq domain assignment 0-16 bit @@ -1162,9 +1171,27 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, // TPC command for scheduled PUCCH – 2 bits for (int i = 0; i < 2; i++) *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc >> (1 - i)) & 1) << (dci_size - pos++); + // PUCCH resource indicator – 3 bits + for (int i = 0; i < 3; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->pucch_resource_indicator >> (2 - i)) & 1) << (dci_size - pos++); // PDSCH-to-HARQ_feedback timing indicator – 3 bits for (int i = 0; i < 3; i++) *dci_pdu |= (((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val >> (2 - i)) & 1) << (dci_size - pos++); + + LOG_D(NR_MAC,"N_RB = %i\n", N_RB); + LOG_D(NR_MAC,"dci_size = %i\n", dci_size); + LOG_D(NR_MAC,"fsize = %i\n", fsize); + LOG_D(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator); + LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid); + LOG_D(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val); + LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc); + LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val); + break; } break; @@ -1682,7 +1709,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); create_nr_list(&sched_ctrl->feedback_ul_harq, 16); create_nr_list(&sched_ctrl->retrans_ul_harq, 16); - LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n", + LOG_I(MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n", mod_idP, UE_id, rntiP); @@ -1738,7 +1765,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1); if (rnti_to_remove_count == 10) exit(1); rnti_to_remove[rnti_to_remove_count] = rnti; - LOG_W(MAC, "to remove in mac rnti_to_remove[%d]=%d\n", rnti_to_remove_count, rnti); + LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti); rnti_to_remove_count++; if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); } @@ -1758,6 +1785,16 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) } } +void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) { + // Hack to remove UE in the phy (following the same procedure as in function mac_remove_nr_ue) + if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1); + if (rnti_to_remove_count == 10) exit(1); + rnti_to_remove[rnti_to_remove_count] = rnti; + LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti); + rnti_to_remove_count++; + if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); +} + uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { // al values passed to this function are x10 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 247a7e2c45..4413864553 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -181,7 +181,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in else { uint8_t nb_ssb_resources =0; //Finding the CSI_RS or SSB Resources - if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type || + if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type || NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type) { if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) { @@ -191,18 +191,18 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in /*! From Spec 38.331 * nrofReportedRS * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE - * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. + * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. * When the field is absent the UE applies the value 1 */ csi_report->CSI_report_bitlen.nb_ssbri_cri= 1; - }else + }else csi_report->CSI_report_bitlen.nb_ssbri_cri= 2; if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ - + ///We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig nb_ssb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count; csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.array; @@ -226,12 +226,12 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in if (nb_ssb_resources) { csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources)); - csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - } else { + } else { csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0; - csi_report->CSI_report_bitlen.rsrp_bitlen = 0; - csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; + csi_report->CSI_report_bitlen.rsrp_bitlen = 0; + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; } LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n", @@ -270,7 +270,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in csi_report->csi_meas_bitlen.ri_bitlen=0; break; case 2: - /* From Spec 38.212 + /* From Spec 38.212 * If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator * values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6, * TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause @@ -283,7 +283,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - /* Replace dummy with the nrofCQIsPerReport from the CSIreport + /* Replace dummy with the nrofCQIsPerReport from the CSIreport config when equalent ASN structure present */ if (0==*(csi_reportconfig->dummy)){ nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri); @@ -293,7 +293,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in nb_allowed_ri = number_of_bits_set(ri_restriction, &max_ri); ri_bitlen = ceil(log2(nb_allowed_ri)); } - ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; break; case 4: @@ -301,7 +301,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - /* Replace dummy with the nrofCQIsPerReport from the CSIreport + /* Replace dummy with the nrofCQIsPerReport from the CSIreport config when equalent ASN structure present */ if (0==*(csi_reportconfig->dummy)){ nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri); @@ -311,16 +311,16 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in nb_allowed_ri = number_of_bits_set(ri_restriction,&max_ri); ri_bitlen = ceil(log2(nb_allowed_ri)); } - ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; break; case 6: case 8: AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present"); - + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - /* Replace dummy with the nrofCQIsPerReport from the CSIreport + /* Replace dummy with the nrofCQIsPerReport from the CSIreport config when equalent ASN structure present */ if (0==*(csi_reportconfig->dummy)){ nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0),&max_ri); @@ -353,7 +353,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in case 4: case 6: case 8: - /* From Spec 38.212 + /* From Spec 38.212 * If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator * values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6, * TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause @@ -383,7 +383,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in case 4: case 6: case 8: - /* From Spec 38.212 + /* From Spec 38.212 * If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator * values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6, * TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause @@ -392,18 +392,18 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in * But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to * calculate RI for antennas equal or more than two. * */ - + if (max_ri > 4 && max_ri < 8){ if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.present){ if (NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI==csi_reportconfig->reportFreqConfiguration->cqi_FormatIndicator) csi_report->csi_meas_bitlen.cqi_bitlen = 8; - else + else csi_report->csi_meas_bitlen.cqi_bitlen = 4; } }else{ //This condition will work even for type1-multipanel. if (NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI==csi_reportconfig->reportFreqConfiguration->cqi_FormatIndicator) csi_report->csi_meas_bitlen.cqi_bitlen = 4; - else + else csi_report->csi_meas_bitlen.cqi_bitlen = 2; } break; @@ -449,7 +449,7 @@ uint16_t nr_get_csi_bitlen(int Mod_idP, NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type){ CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + - CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * + CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * (CSI_report_bitlen->nb_ssbri_cri -1 ))); } else{ csi_meas_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements @@ -569,7 +569,9 @@ static void handle_dl_harq(module_id_t mod_id, add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid); harq->round = 0; harq->ndi ^= 1; - } else if (harq->round == MAX_HARQ_ROUNDS) { + } else { + harq->round++; + if (harq->round == MAX_HARQ_ROUNDS) { add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid); harq->round = 0; harq->ndi ^= 1; @@ -578,7 +580,7 @@ static void handle_dl_harq(module_id_t mod_id, LOG_D(MAC, "retransmission error for UE %d (total %d)\n", UE_id, stats->dlsch_errors); } else { add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); - harq->round++; + } } } @@ -654,7 +656,7 @@ int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_i //returns the measured RSRP value (upper limit) int get_measured_rsrp(uint8_t index) { //if index is invalid returning minimum rsrp -140 - if((index >= 0 && index <= 15) || index >= 114) + if(index <= 15 || index >= 114) return MIN_RSRP_VALUE; return L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index]; @@ -890,7 +892,7 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig, reportQuantity_type = UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type; LOG_D(PHY,"SFN/SF:%d%d reportQuantity type = %d\n",frame,slot,reportQuantity_type); - if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type || + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type || NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type) { uint8_t csi_ssb_idx = 0; uint8_t diff_rsrp_idx = 0; @@ -922,12 +924,12 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig, reverse_n_bits(payload, cri_ssbri_bitlen); if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type) - sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] = + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] = *(UE_info->csi_report_template[UE_id][csi_report_id].SSB_Index_list[cri_ssbri_bitlen>0?((*payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]); else - sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] = + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] = *(UE_info->csi_report_template[UE_id][csi_report_id].CSI_Index_list[cri_ssbri_bitlen>0?((*payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]); - + *payload >>= cri_ssbri_bitlen; LOG_D(PHY,"SSB_index = %d\n",sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx]); } @@ -946,7 +948,7 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig, } } - if ( !(reportQuantity_type)) + if ( !(reportQuantity_type)) AssertFatal(reportQuantity_type, "reportQuantity is not configured"); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9784b6b79e..a0f937f6a6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -237,13 +237,44 @@ void nr_process_mac_pdu( case UL_SCH_LCID_SRB3: // todo break; - case UL_SCH_LCID_CCCH_MSG3: - // todo - break; + case UL_SCH_LCID_CCCH: - // todo - mac_subheader_len = 2; + case UL_SCH_LCID_CCCH1: + // fixed length + mac_subheader_len = 1; + + if ( rx_lcid == UL_SCH_LCID_CCCH1 ) { + // RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes + mac_sdu_len = 8; + + // Check if it is a valid CCCH1 message, we get all 00's messages very often + int i = 0; + for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) { + if(pdu_ptr[i] != 0) { + break; + } + } + if (i == (mac_subheader_len+mac_sdu_len)) { + LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len); + done = 1; break; + } + } else { + // fixed length of 6 bytes + mac_sdu_len = 6; + } + + nr_mac_rrc_data_ind(module_idP, + CC_id, + frameP, + 0, + 0, + rnti, + CCCH, + pdu_ptr+mac_subheader_len, + mac_sdu_len, + 0); + break; case UL_SCH_LCID_DTCH: // check if LCID is valid at current time. @@ -329,8 +360,16 @@ void handle_nr_ul_harq(module_id_t mod_id, return; remove_front_nr_list(&sched_ctrl->feedback_ul_harq); - sched_ctrl->ul_harq_processes[harq_pid].round++; - add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); + sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false; + if(sched_ctrl->ul_harq_processes[harq_pid].round == MAX_HARQ_ROUNDS) { + sched_ctrl->ul_harq_processes[harq_pid].ndi ^= 1; + sched_ctrl->ul_harq_processes[harq_pid].round = 0; + UE_info->mac_stats[UE_id].ulsch_errors++; + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); + } else { + sched_ctrl->ul_harq_processes[harq_pid].round++; + add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); + } harq_pid = sched_ctrl->feedback_ul_harq.head; } remove_front_nr_list(&sched_ctrl->feedback_ul_harq); @@ -346,7 +385,9 @@ void handle_nr_ul_harq(module_id_t mod_id, harq_pid, crc_pdu->rnti); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); - } else if (harq->round == MAX_HARQ_ROUNDS) { + } else { + harq->round++; + if (harq->round == MAX_HARQ_ROUNDS) { harq->ndi ^= 1; harq->round = 0; LOG_D(MAC, @@ -356,12 +397,12 @@ void handle_nr_ul_harq(module_id_t mod_id, UE_info->mac_stats[UE_id].ulsch_errors++; add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); } else { - harq->round++; LOG_D(MAC, "Ulharq id %d crc failed for RNTI %04x\n", harq_pid, crc_pdu->rnti); add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); + } } } @@ -450,9 +491,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_scheduling_control->sched_ul_bytes = 0; } } - } else { - if (!sduP) // check that CRC passed - return; + } else if(sduP) { + + bool no_sig = true; + for (int k = 0; k < sdu_lenP; k++) { + if(sduP[k]!=0) { + no_sig = false; + break; + } + } + + if(no_sig) { + LOG_W(NR_MAC, "No signal\n"); + } T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */, @@ -466,40 +517,88 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (ra->state != WAIT_Msg3) continue; - // random access pusch with TC-RNTI - if (ra->rnti != current_rnti) { - LOG_W(NR_MAC, - "expected TC-RNTI %04x to match current RNTI %04x\n", + if(no_sig) { + LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state); + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + } else { + + // random access pusch with TC-RNTI + if (ra->rnti != current_rnti) { + LOG_W(NR_MAC, + "expected TC_RNTI %04x to match current RNTI %04x\n", + ra->rnti, + current_rnti); + + if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) { + LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state); + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + } + + continue; + } + + const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup); + UE_info->UE_beam_index[UE_id] = ra->beam_id; + + // re-initialize ta update variables after RA procedure completion + UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; + + LOG_I(NR_MAC, + "reset RA state information for RA-RNTI %04x/index %d\n", ra->rnti, - current_rnti); + i); + + LOG_I(NR_MAC, + "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " + "adding UE MAC Context UE_id %d/RNTI %04x\n", + gnb_mod_idP, + current_rnti, + UE_id, + ra->rnti); + + if(ra->cfra) { + + LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti); + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + UE_info->active[UE_id] = true; + + } else { + + LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP); + LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n"); + for (int k = 0; k < sdu_lenP; k++) { + LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]); + } + + // UE Contention Resolution Identity + // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4 + // First byte corresponds to R/LCID MAC sub-header + memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6); + + nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); + + ra->state = Msg4; + ra->Msg4_frame = ( frameP +2 ) % 1024; + ra->Msg4_slot = 1; + LOG_I(NR_MAC, "Scheduling RA-Msg4 for TC_RNTI %04x (state %d, frame %d, slot %d)\n", ra->rnti, ra->state, ra->Msg4_frame, ra->Msg4_slot); + + } + return; + + } + } + } else { + for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { + NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; + if (ra->state != WAIT_Msg3) continue; - } - const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup); - UE_info->UE_beam_index[UE_id] = ra->beam_id; - LOG_I(NR_MAC, - "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " - "adding UE MAC Context UE_id %d/RNTI %04x\n", - gnb_mod_idP, - current_rnti, - UE_id, - ra->rnti); - LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n"); - for (int k = 0; k < sdu_lenP; k++) { - LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]); - } - - // re-initialize ta update variables afrer RA procedure completion - UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; - - free(ra->preambles.preamble_list); - ra->state = RA_IDLE; - LOG_I(NR_MAC, - "reset RA state information for RA-RNTI %04x/index %d\n", - ra->rnti, - i); - - return; + LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state); + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index f552b6c606..05c180ca2e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -122,7 +122,7 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, int16_t timing_offset); -void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP); +void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra); int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only); @@ -320,6 +320,8 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti); +void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti); + int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, NR_BWP_Downlink_t *bwp, NR_ControlResourceSet_t *coreset, @@ -355,8 +357,18 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); +int nr_write_ce_dlsch_pdu(module_id_t module_idP, + const NR_UE_sched_ctrl_t *ue_sched_ctl, + unsigned char *mac_pdu, + unsigned char drx_cmd, + unsigned char *ue_cont_res_id); + void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); +void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); + +void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra); + void nr_process_mac_pdu( module_id_t module_idP, rnti_t rnti, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index ee2711c6ef..e516217ff1 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -61,6 +61,7 @@ # include "gtpv1u_eNB_task.h" # include "gtpv1u.h" +#include #include "ENB_APP/enb_config.h" @@ -83,9 +84,57 @@ hash_table_t *pdcp_coll_p = NULL; static int mbms_socket = -1; #endif +uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +int pdcp_pc5_sockfd; +struct sockaddr_in prose_ctrl_addr; +struct sockaddr_in prose_pdcp_addr; +struct sockaddr_in pdcp_sin; /* pdcp module parameters and related functions*/ static pdcp_params_t pdcp_params= {0,NULL}; +rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB]; +rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode +unsigned int pdcp_eNB_UE_instance_to_rnti_index; + +signed int pdcp_2_nas_irq; +pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB]; +pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX]; + +static pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +static pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +static sdu_size_t pdcp_input_sdu_remaining_size_to_read; +static sdu_size_t pdcp_output_header_bytes_to_write; +static sdu_size_t pdcp_output_sdu_bytes_to_write; +notifiedFIFO_t pdcp_sdu_list; + +pdcp_enb_t pdcp_enb[MAX_NUM_CCs]; + uint64_t get_pdcp_optmask(void) { return pdcp_params.optmask; @@ -937,7 +986,7 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; - itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); packet_forwarded = TRUE; } } else { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index c8ab4499ee..0c3dd2f04f 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -91,34 +91,34 @@ extern int pdcp_instance_cnt; int init_pdcp_thread(void); void cleanup_pdcp_thread(void); -uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; -uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +extern uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; -uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +extern uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +extern uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; void pdcp_update_perioidical_stats(const protocol_ctxt_t *const ctxt_pP); @@ -138,7 +138,7 @@ typedef struct pdcp_enb_s { } pdcp_enb_t; -pdcp_enb_t pdcp_enb[MAX_NUM_CCs]; +extern pdcp_enb_t pdcp_enb[MAX_NUM_CCs]; typedef struct pdcp_stats_s { time_stats_t pdcp_run; @@ -242,17 +242,18 @@ typedef struct pdcp_mbms_s { * \note None * @ingroup _pdcp */ + boolean_t pdcp_data_req( protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, const mui_t muiP, - const confirm_t confirmP, \ + const confirm_t confirmP, const sdu_size_t sdu_buffer_size, unsigned char *const sdu_buffer, const pdcp_transmission_mode_t mode, - const uint32_t *const sourceL2Id, - const uint32_t *const destinationL2Id + const uint32_t * sourceL2Id, + const uint32_t * destinationL2Id ); /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) @@ -455,10 +456,10 @@ struct pdcp_netlink_element_s { //TTN for D2D (PC5S) #define PDCP_SOCKET_PORT_NO 9999 //temporary value #define PC5_SIGNALLING_PAYLOAD_SIZE 100 //should be updated with a correct value -int pdcp_pc5_sockfd; -struct sockaddr_in prose_ctrl_addr; -struct sockaddr_in prose_pdcp_addr; -struct sockaddr_in pdcp_sin; +extern int pdcp_pc5_sockfd; +extern struct sockaddr_in prose_ctrl_addr; +extern struct sockaddr_in prose_pdcp_addr; +extern struct sockaddr_in pdcp_sin; void pdcp_pc5_socket_init(void); typedef struct { @@ -500,28 +501,18 @@ typedef struct { #define REORDERING_WINDOW_SN_7BIT 64 #define REORDERING_WINDOW_SN_12BIT 2048 -signed int pdcp_2_nas_irq; -pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB]; -pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX]; +extern signed int pdcp_2_nas_irq; +extern pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB]; +extern pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX]; // for UE code conly -rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB]; -rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode -unsigned int pdcp_eNB_UE_instance_to_rnti_index; +extern rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB]; +extern rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode +extern unsigned int pdcp_eNB_UE_instance_to_rnti_index; -pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -sdu_size_t pdcp_output_sdu_bytes_to_write; -sdu_size_t pdcp_output_header_bytes_to_write; -notifiedFIFO_t pdcp_sdu_list; -int pdcp_sent_a_sdu; -pdcp_data_req_header_t pdcp_input_header; -unsigned char pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE]; -sdu_size_t pdcp_input_index_header; -sdu_size_t pdcp_input_sdu_size_read; -sdu_size_t pdcp_input_sdu_remaining_size_to_read; +extern notifiedFIFO_t pdcp_sdu_list; #define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \ ((hash_key_t)mODULE_iD | \ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 687d7b1bfe..8ff3c06cd4 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -78,9 +78,6 @@ extern int nas_sock_fd[MAX_MOBILES_PER_ENB]; extern int nas_sock_mbms_fd; -extern int mbms_rab_id; - - extern struct msghdr nas_msg_tx; extern struct msghdr nas_msg_rx; @@ -113,8 +110,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { * PDCP packet to pick the right socket below */ int rb_id = pdcpHead->rb_id; - int sizeToWrite= sizeof (pdcp_data_ind_header_t) + - pdcpHead->data_size; void * pdcpData=(void*)(pdcpHead+1); if (rb_id == 10) { //hardcoded for PC5-Signaling if( LOG_DEBUGFLAG(DEBUG_PDCP) ) { @@ -128,24 +123,25 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { } else if (UE_NAS_USE_TUN) { //ret = write(nas_sock_fd[pdcpHead->inst], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); if(rb_id == mbms_rab_id){ - ret = write(nas_sock_mbms_fd, pdcpData,sizeToWrite ); + ret = write(nas_sock_mbms_fd, pdcpData, pdcpHead->data_size ); LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n", - ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite); + ret,rb_id,nas_sock_fd[pdcpHead->inst],pdcpHead->data_size); } else { if( LOG_DEBUGFLAG(DEBUG_PDCP) ) - log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n"); - ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,sizeToWrite ); + log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n"); + ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,pdcpHead->data_size ); LOG_T(PDCP,"[UE PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n", - ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite); + ret,rb_id,nas_sock_fd[pdcpHead->inst],pdcpHead->data_size); } } else if (ENB_NAS_USE_TUN) { if( LOG_DEBUGFLAG(DEBUG_PDCP) ) - log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n"); - ret = write(nas_sock_fd[0], pdcpData, sizeToWrite); - LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],sizeToWrite); + log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n"); + ret = write(nas_sock_fd[0], pdcpData, pdcpHead->data_size); + LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],pdcpHead->data_size); } else if (PDCP_USE_NETLINK) { + int sizeToWrite= sizeof (pdcp_data_ind_header_t) + pdcpHead->data_size; memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) pdcpHead, sizeToWrite); nas_nlh_tx->nlmsg_len = sizeToWrite; ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0); @@ -154,7 +150,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]); if( LOG_DEBUGFLAG(DEBUG_PDCP) ) - log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR, + log_dump(PDCP, pdcpData, min(pdcpHead->data_size,30) , LOG_DUMP_CHAR, "Printing first bytes of PDCP SDU before removing it from the list: \n"); delNotifiedFIFO_elt (sdu_p); pdcp_nb_sdu_sent ++; @@ -377,7 +373,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx protocol_ctxt_t ctxt; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; - module_id_t ue_id = 0; pdcp_t *pdcp_p = NULL; static unsigned char pdcp_read_state_g =0; rb_id_t rab_id = 0; @@ -471,30 +466,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx } else { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES - for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { - if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - DEFAULT_RAB_ID); - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA - ,NULL, NULL - ); - } - } + // never finished code, dropped } } else { // ctxt.enb_flag => UE if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c index bf6579955b..cb5f1af28d 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c @@ -319,13 +319,15 @@ error: } int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) { +/* code useless in this status: return 0 anyways rlc_op_status_t result = 0; - //printf("PROTO_AGENT: handling the data_req_ack message\n"); + printf("PROTO_AGENT: handling the data_req_ack message\n"); Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params; Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack; result = data_ack->result; - //printf("PROTO_AGENT: ACK RESULT IS %u\n", result); + printf("PROTO_AGENT: ACK RESULT IS %u\n", result); ack_result = result; +*/ return 0; } diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h index c805b81543..8f553e05e1 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h @@ -62,7 +62,6 @@ typedef int (*proto_agent_message_destruction_callback)( ); -uint32_t ack_result; /********************************** * progRAN protocol messages helper diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c index 9a63427ed5..925c11c8f8 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c @@ -30,7 +30,7 @@ #include "common/utils/LOG/log.h" proto_agent_channel_t *proto_channel[NUMBER_OF_eNB_MAX][ENB_AGENT_MAX]; -proto_agent_channel_instance_t channel_instance; +static proto_agent_channel_instance_t channel_instance; int proto_agent_channel_id = 0; int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id) { diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c index fda84879be..cf77f9ec37 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c @@ -80,6 +80,8 @@ static int g_send_id_read_index[2]; static struct mac_data_ind g_tx_delayed_indications[MAX_TIME_DELAYED_PDU_DUE_TO_HARQ]; static struct mac_data_ind g_rx_delayed_indications[MAX_TIME_DELAYED_PDU_DUE_TO_HARQ]; +static rlc_um_entity_t um_tx; +static rlc_um_entity_t um_rx; static int8_t *g_sdus[] = {"En dépit de son volontarisme affiché, le premier ministre est de plus en plus décrié pour son incompétence. La tension politique et dans l'opinion publique est encore montée d'un cran au Japon, sur fond d'inquiétantes nouvelles, avec du plutonium détecté dans le sol autour de la centrale de Fukushima. Le premier ministre Naoto Kan a solennellement déclaré que son gouvernement était «en état d'alerte maximum». Tout en reconnaissant que la situation restait «imprévisible». Ce volontarisme affiché par le premier ministre - que Nicolas Sarkozy rencontrera demain lors d'une visite au Japon - ne l'a pas empêché d'être la cible de violentes critiques de la part de parlementaires sur sa gestion de la crise. Attaqué sur le manque de transparence, il a assuré qu'il rendait publiques toutes les informations en sa possession. Un député de l'opposition, Yosuke Isozaki, a aussi reproché à Naoto Kan de ne pas avoir ordonné l'évacuation des populations dans la zone comprise entre 20 et 30 km autour de la centrale. «Peut-il y avoir quelque chose de plus irresponsable que cela ?», a-t-il lancé. Pour l'heure, la zone d'évacuation est limitée à un rayon de 20 km, seul le confinement étant recommandé pour les 10 km suivants. Sur ce sujet, les autorités japonaises ont été fragilisées mardi par les déclarations de Greenpeace, affirmant que ses experts avaient détecté une radioactivité dangereuse à 40 km de la centrale. L'organisation écologiste a appelé à une extension de la zone d'évacuation, exhortant Tokyo à «cesser de privilégier la politique aux dépens de la science». L'Agence japonaise de sûreté nucléaire a balayé ces critiques.", diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h index 6da464aa28..bfde1b31f3 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h @@ -21,8 +21,6 @@ # ifndef __RLC_UM_TEST_H__ # define __RLC_UM_TEST_H__ -rlc_um_entity_t um_tx; -rlc_um_entity_t um_rx; void rlc_um_v9_3_0_test_windows_5(void); void rlc_um_v9_3_0_test_windows_10(void); diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 98c8c3e252..b9dcf0414b 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -36,6 +36,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "targets/COMMON/openairinterface5g_limits.h" #include "assertions.h" +#include #include "common/ran_context.h" extern RAN_CONTEXT_t RC; @@ -51,7 +52,27 @@ extern boolean_t pdcp_data_ind( #define DEBUG_RLC_PDCP_INTERFACE 1 //#define TRACE_RLC_PAYLOAD 1 #define DEBUG_RLC_DATA_REQ 1 +void (*rlc_rrc_data_conf)( + const protocol_ctxt_t *const ctxtP, + const rb_id_t rb_idP, + const mui_t muiP, + const rlc_tx_status_t statusP) __attribute__ ((aligned(32))); +void (*rlc_rrc_data_ind)( + const protocol_ctxt_t *const ctxtP, + const rb_id_t rb_idP, + const sdu_size_t sdu_sizeP, + const uint8_t *const sduP) __attribute__ ((aligned(32))); + +logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +hash_table_t *rlc_coll_p __attribute__ ((aligned(32))); + + +logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ //----------------------------------------------------------------------------- void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP) //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 7e4920a579..ef5f824ba0 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -133,13 +133,13 @@ typedef struct { #define RLC_MAX_MBMS_LC (LTE_maxSessionPerPMCH * LTE_maxServiceCount) #define RLC_MAX_LC ((max_val_LTE_DRB_Identity+1)* MAX_MOBILES_PER_ENB) -void (*rlc_rrc_data_ind)( +extern void (*rlc_rrc_data_ind)( const protocol_ctxt_t *const ctxtP, const rb_id_t rb_idP, const sdu_size_t sdu_sizeP, const uint8_t *const sduP) __attribute__ ((aligned(32))); -void (*rlc_rrc_data_conf)( +extern void (*rlc_rrc_data_conf)( const protocol_ctxt_t *const ctxtP, const rb_id_t rb_idP, const mui_t muiP, @@ -184,8 +184,8 @@ typedef struct rlc_mbms_id_s { //rlc_mbms_t rlc_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h //rlc_mbms_t rlc_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +extern rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +extern rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h #define rlc_mbms_enb_get_lcid_by_rb_id(Enb_mOD,rB_iD) rlc_mbms_rbid2lcid_eNB[Enb_mOD][rB_iD] ; @@ -201,8 +201,8 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_ rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \ } while (0); -logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ -logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +extern logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +extern logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ #define RLC_COLL_KEY_VALUE(eNB_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \ @@ -250,7 +250,7 @@ logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; (((hash_key_t)(sESSION_ID)) << 37) | \ (((hash_key_t)(0x0000000000000001)) << 63)) -hash_table_t *rlc_coll_p __attribute__ ((aligned(32))); +extern hash_table_t *rlc_coll_p __attribute__ ((aligned(32))); /*! \fn tbs_size_t mac_rlc_serialize_tb (char* bufferP, list_t transport_blocksP) * \brief Serialize a list of transport blocks coming from RLC in order to be processed by MAC. diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ec48b0adae..39b770508e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -34,6 +34,7 @@ /* from OAI */ #include "pdcp.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include #define TODO do { \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ @@ -450,7 +451,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); //printf("\n"); - itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); } } @@ -804,7 +805,9 @@ void nr_DRB_preconfiguration(uint16_t crnti) rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); + } NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); nr_rlc_bearer_init(RLC_BearerConfig); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 2eb2bae968..88333272cb 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -320,7 +320,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( return ret; } -int oai_emulation; rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c index 919d577a18..18285f6563 100644 --- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c +++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c @@ -265,7 +265,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( return ret; } -int oai_emulation; rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, diff --git a/openair2/NETWORK_DRIVER/UE_IP/netlink.c b/openair2/NETWORK_DRIVER/UE_IP/netlink.c index 658ae19aba..b3829c51d1 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/netlink.c +++ b/openair2/NETWORK_DRIVER/UE_IP/netlink.c @@ -39,6 +39,7 @@ #include "local.h" #include "proto_extern.h" +MODULE_LICENSE("OAI"); #define OAI_IP_DRIVER_NETLINK_ID 31 #define NL_DEST_PID 1 diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 5b5f3e6b3c..e42d19167d 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -41,8 +41,8 @@ #define MAX_IF_MODULES 100 //#define UL_HARQ_PRINT -NR_IF_Module_t *if_inst[MAX_IF_MODULES]; -NR_Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; +static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES]; +static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); @@ -55,7 +55,7 @@ extern uint16_t sl_ahead; void handle_nr_rach(NR_UL_IND_t *UL_info) { if (UL_info->rach_ind.number_of_pdus>0) { - LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); + LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); int npdus = UL_info->rach_ind.number_of_pdus; for(int i = 0; i < npdus; i++) { UL_info->rach_ind.number_of_pdus--; @@ -178,8 +178,8 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { #endif module_id_t module_id = UL_info->module_id; int CC_id = UL_info->CC_id; - NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; - NR_IF_Module_t *ifi = if_inst[module_id]; + NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id]; + NR_IF_Module_t *ifi = nr_if_inst[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id]; LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n", UL_info->frame,UL_info->slot, @@ -253,17 +253,17 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { AssertFatal(Mod_id %d\n",Mod_id,MAX_IF_MODULES); LOG_I(PHY,"Installing callbacks for IF_Module - UL_indication\n"); - if (if_inst[Mod_id]==NULL) { - if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t)); - memset((void*)if_inst[Mod_id],0,sizeof(NR_IF_Module_t)); + if (nr_if_inst[Mod_id]==NULL) { + nr_if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t)); + memset((void*)nr_if_inst[Mod_id],0,sizeof(NR_IF_Module_t)); - LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,if_inst[Mod_id]); + LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,nr_if_inst[Mod_id]); - if_inst[Mod_id]->CC_mask=0; - if_inst[Mod_id]->NR_UL_indication = NR_UL_indication; - AssertFatal(pthread_mutex_init(&if_inst[Mod_id]->if_mutex,NULL)==0, - "allocation of if_inst[%d]->if_mutex fails\n",Mod_id); + nr_if_inst[Mod_id]->CC_mask=0; + nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication; + AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0, + "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id); } - return if_inst[Mod_id]; + return nr_if_inst[Mod_id]; } diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index d98c603d78..38a742bf74 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -7,8 +7,8 @@ #include "nfapi/oai_integration/vendor_ext.h" #define MAX_IF_MODULES 100 -IF_Module_t *if_inst[MAX_IF_MODULES]; -Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; +static IF_Module_t *if_inst[MAX_IF_MODULES]; +static Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 21740016b1..c212075934 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -54,6 +54,7 @@ extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; extern uint16_t sf_ahead; +static eth_params_t stub_eth_params; void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h index 547fc2dfc4..bdf8872371 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -26,16 +26,7 @@ extern nfapi_tx_request_pdu_t* tx_request_pdu_list; extern nfapi_dl_config_request_t* dl_config_req; extern nfapi_ul_config_request_t* ul_config_req; extern nfapi_hi_dci0_request_t* hi_dci0_req; - -int tx_req_num_elems; - -//below 2 difinitions move to lte-ue.c to add initialization when difinition. -//int next_ra_frame; -//module_id_t next_Mod_id; -eth_params_t stub_eth_params; - - - +extern int tx_req_num_elems; // This function should return all the sched_response config messages which concern a specific UE. Inside this // function we should somehow make the translation of config message's rnti to Mod_ID. diff --git a/openair2/RRC/LTE/plmn_data.h b/openair2/RRC/LTE/plmn_data.h index 97dc94343b..701bcaf764 100644 --- a/openair2/RRC/LTE/plmn_data.h +++ b/openair2/RRC/LTE/plmn_data.h @@ -2231,7 +2231,8 @@ static const plmn_data_t plmn_data[] = { /* 310 900 Mid-Rivers Communications Mid-Rivers Wireless Operational */ - {310, 910, "Verizon Wireless", "Verizon USA"} + {310, 910, "Verizon Wireless", "Verizon USA"}, + {0,0,"",""} /* 310 920 Get Mobile Inactive 310 930 Copper Valley Wireless Inactive diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index c57cec6ba5..e3d28d8a0f 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -330,7 +330,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) { preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; // 40 ms SL Period preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; - preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(5,1); preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; // last 36 subframes for PSCCH @@ -338,7 +338,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) { preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1] = 0xFF; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2] = 0xFF; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3] = 0xFF; - preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[5] = 0xFF; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[4] = 0xFF; preconfigpool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; preconfigpool->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; preconfigpool->dataHoppingConfig_r12.rb_Offset_r12 = 0; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 9f0e40806a..9a565be560 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -87,6 +87,7 @@ #include "pdcp.h" #include "gtpv1u_eNB_task.h" +#include #include "intertask_interface.h" @@ -4968,7 +4969,7 @@ void rrc_eNB_handover_ue_context_release( ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; } - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + itti_send_msg_to_task(TASK_VARIABLE, ctxt_pP->module_id, msg_delete_tunnels_p); struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); @@ -6557,10 +6558,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (int)DRB_configList->list.array[i]->drb_Identity, (int)*DRB_configList->list.array[i]->logicalChannelIdentity); /* For pre-ci tests */ - LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", + LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, - oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid], (int)DRB_configList->list.array[i]->drb_Identity, (int)*DRB_configList->list.array[i]->logicalChannelIdentity); @@ -6585,7 +6585,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ctxt_pP->module_id, ctxt_pP->module_id, (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity)); - ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; + ue_module_id = 0; // Was oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; rb_conf_ipv4(0, //add ue_module_id, //cx ctxt_pP->module_id, //inst diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index e974a28f68..6683d91556 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -40,6 +40,7 @@ # include "common/ran_context.h" +#include extern RAN_CONTEXT_t RC; @@ -92,7 +93,6 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( } } - //------------------------------------------------------------------------------ boolean_t gtpv_data_req( @@ -113,64 +113,152 @@ gtpv_data_req( return FALSE; } LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP); - { - MessageDef *message_p; - // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). - uint8_t *message_buffer; - - if(task_id == TASK_DATA_FORWARDING){ - - LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n"); - - message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP); - - memcpy (message_buffer, buffer_pP, sdu_sizeP); - - message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND); - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti; - GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index; - - itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. - }else if(task_id == TASK_END_MARKER){ - - LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n"); - - message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP); - - memcpy (message_buffer, buffer_pP, sdu_sizeP); - - message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND); - GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame; - GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag; - GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP; - GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP; - GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP; - GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP; - GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer; - GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP; - GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id; - GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti; - GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index; - - itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. - } + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + + if(task_id == TASK_DATA_FORWARDING){ + + LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n"); + + message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP); + + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND); + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + } else if (task_id == TASK_END_MARKER){ + + LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n"); + + message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP); + + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND); + GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame; + GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag; + GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP; + GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP; + GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP; + GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP; + GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer; + GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP; + GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id; + GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti; + GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } - return TRUE; - + LOG_E(RRC, "Impossible state\n"); + return FALSE; } -//#endif +boolean_t gtpv_data_req_new ( + protocol_ctxt_t *ctxt, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { + int task; + + if (sdu_buffer_sizeP==0) + task=TASK_END_MARKER; + else + task=TASK_DATA_FORWARDING; + + struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt->module_id], ctxt->rnti); + if(ue_context_p == NULL || ue_context_p->ue_context.handover_info == NULL || + ue_context_p->ue_context.Status != RRC_HO_EXECUTION) { + LOG_E(RRC,"incoming GTP-U for X2 in non HO context\n"); + return false; + } + + /* in the source enb, UE in RRC_HO_EXECUTION mode */ + // We have 2*2=4 cases (data or end marker) * (from slave, from EPC) + if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) { + LOG_I(GTPU, "source receive END MARKER\n"); + /* set handover state */ + //ue_context_p->ue_context.handover_info->state = HO_END_MARKER; + MessageDef *msg; + // Configure end marker + msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_REQ); + GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + sdu_buffer_sizeP); + memcpy(>PV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], sdu_buffer_pP, sdu_buffer_sizeP); + GTPV1U_ENB_END_MARKER_REQ(msg).length = sdu_buffer_sizeP; + GTPV1U_ENB_END_MARKER_REQ(msg).rnti = ctxt->rnti; + GTPV1U_ENB_END_MARKER_REQ(msg).rab_id = rb_idP; + GTPV1U_ENB_END_MARKER_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX; + LOG_I(GTPU, "Send End Marker to GTPV1-U at frame %d and subframe %d \n", ctxt->frame,ctxt->subframe); + itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt->module_id), msg); + return NW_GTPV1U_OK; + } + + /* target enb */ + // We have 2*2=4 cases (data or end marker) * (from source, from EPC) + if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { + // It should come from remote eNB + // case end marker by EPC is not possible ? + if (task==TASK_END_MARKER) { + LOG_I(GTPU, "target end receive END MARKER\n"); + // We close the HO, nothing to send to remote ? + ue_context_p->ue_context.handover_info->state = HO_END_MARKER; + gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req; + memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req)); + delete_tunnel_req.rnti = ctxt->rnti; + gtpv1u_delete_x2u_tunnel(ctxt->module_id, &delete_tunnel_req, GTPV1U_TARGET_ENB); + return true; + } else { + /* data packet */ + LOG_I(GTPU, "Received a message data forwarding length %d\n", sdu_buffer_sizeP); + // Is it from remote ENB + // We have to push it to the UE ? + if(ue_context_p->ue_context.handover_info->state != HO_COMPLETE) { + int result = pdcp_data_req( + ctxt, + srb_flagP, + rb_idP, + muiP, // mui + confirmP, // confirm + sdu_buffer_sizeP, + sdu_buffer_pP, + modeP, + sourceL2Id, + destinationL2Id + ); + ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_NO_EMPTY; + return result; + } else { /* It is from from epc message */ + /* in the source enb, UE in RRC_HO_EXECUTION mode */ + MessageDef *msg; + // ????? + return true; + } + } + } + LOG_E(RRC,"This function should return before the end\n"); + return false; +} + void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( module_id_t enb_mod_idP, @@ -181,21 +269,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__); return; } + gtpv1u_enb_delete_tunnel_req_t tmp={0}; - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL, 0, - "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", - ue_context_pP->ue_context.eNB_ue_s1ap_id); - - MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg))); - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti; - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).from_gnb = 0; - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs; + tmp.rnti = ue_context_pP->ue_context.rnti; + tmp.from_gnb = 0; + tmp.num_erab = ue_context_pP->ue_context.nb_of_e_rabs; for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) { const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab]; - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi; + tmp.eps_bearer_id[e_rab] = gtp_ebi; } - itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg); + gtpv1u_delete_s1u_tunnel(enb_mod_idP,&tmp); } diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 0e6d5b580f..f64a109f75 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -48,11 +48,12 @@ #include "pdcp_primitives.h" #include "UTIL/OSA/osa_defs.h" -#include "msc.h" +#include #include "LTE_UERadioAccessCapabilityInformation.h" #include "gtpv1u_eNB_task.h" +#include #include "RRC/LTE/rrc_eNB_GTPV1U.h" #include "TLVDecoder.h" @@ -1787,7 +1788,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms } } - itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p); + itti_send_msg_to_task(TASK_VARIABLE, instance, msg_delete_tunnels_p); //S1AP_E_RAB_RELEASE_RESPONSE rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); } diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 58c595a3d0..c9ab3a3a97 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -42,6 +42,7 @@ #include "NR_MIB.h" #include "NR_BCCH-BCH-Message.h" +#include "rrc_gNB_UE_context.h" extern RAN_CONTEXT_t RC; @@ -217,29 +218,22 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, const int CC_id, const frame_t frameP, const rb_id_t Srb_id, + const rnti_t rnti, const uint8_t Nb_tb, uint8_t *const buffer_pP ){ - asn_enc_rval_t enc_rval; - uint8_t Sdu_size = 0; - uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f); - #ifdef DEBUG_RRC LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); #endif - rrc_gNB_carrier_data_t *carrier; - NR_BCCH_BCH_Message_t *mib; - NR_SRB_INFO *srb_info; - char payload_size, *payload_pP; - - carrier = &RC.nrrrc[Mod_idP]->carrier; - mib = &carrier->mib; - srb_info = &carrier->Srb0; - - /* MIBCH */ + // MIBCH if ((Srb_id & RAB_OFFSET) == MIBCH) { + asn_enc_rval_t enc_rval; + uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f); + rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier; + NR_BCCH_BCH_Message_t *mib = &carrier->mib; + // Currently we are getting the pdcch_ConfigSIB1 from the configuration file. // Uncomment this function for a dynamic pdcch_ConfigSIB1. //channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1 @@ -269,7 +263,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, return (3); } - /* TODO BCCH SIB1 SIBs */ + // TODO BCCH SIB1 SIBs if ((Srb_id & RAB_OFFSET ) == BCCH) { memcpy(&buffer_pP[0], RC.nrrrc[Mod_idP]->carrier.SIB1, @@ -278,29 +272,54 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, return RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1; } - /* CCCH */ + // CCCH if( (Srb_id & RAB_OFFSET ) == CCCH) { - //struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti); - //if (ue_context_p == NULL) return(0); - //eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; - LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id); - // srb_info=&ue_p->Srb0; + char *payload_pP; + uint8_t Sdu_size = 0; + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_idP], rnti); - payload_size = srb_info->Tx_buffer.payload_size; + LOG_D(NR_RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id); + + char payload_size = ue_context_p->ue_context.Srb0.Tx_buffer.payload_size; // check if data is there for MAC if (payload_size > 0) { - payload_pP = srb_info->Tx_buffer.Payload; - LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP); + payload_pP = ue_context_p->ue_context.Srb0.Tx_buffer.Payload; + LOG_D(NR_RRC,"[gNB %d] CCCH has %d bytes (dest: %p, src %p)\n", Mod_idP, payload_size, buffer_pP, payload_pP); // Fill buffer memcpy((void *)buffer_pP, (void*)payload_pP, payload_size); Sdu_size = payload_size; - srb_info->Tx_buffer.payload_size = 0; + ue_context_p->ue_context.Srb0.Tx_buffer.payload_size = 0; } return Sdu_size; } return(0); +} + +int8_t nr_mac_rrc_data_ind(const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const int UE_id, + const rnti_t rntiP, + const rb_id_t srb_idP, + const uint8_t *sduP, + const sdu_size_t sdu_lenP, + const boolean_t brOption) { + + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP,0); + + if((srb_idP & RAB_OFFSET) == CCCH) { + LOG_D(NR_RRC, "[gNB %d] Received SDU for CCCH on SRB %ld\n", module_idP, srb_idP); + ctxt.brOption = brOption; + if (sdu_lenP > 0) { + nr_rrc_gNB_decode_ccch(&ctxt, sduP, sdu_lenP, CC_id); + } + } + + return 0; } \ No newline at end of file diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 6c28beec34..a26a4ac5b1 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -326,7 +326,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, // cellSelectionInfo sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo)); - sib1->cellSelectionInfo->q_RxLevMin = -50; + sib1->cellSelectionInfo->q_RxLevMin = -65; // cellAccessRelatedInfo struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo)); @@ -418,7 +418,8 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, nrMultiBandInfo->freqBandIndicatorNR = configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[i]; ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list,nrMultiBandInfo); } - sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + //sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = 86; for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) { ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list,configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[i]); } diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 5aafbaee4c..ea7b853c03 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -51,6 +51,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, const int CC_id, const frame_t frameP, const rb_id_t Srb_id, + const rnti_t rnti, const uint8_t Nb_tb, uint8_t *const buffer_pP ); @@ -158,6 +159,24 @@ int nr_rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP); +int8_t nr_mac_rrc_data_ind( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const int UE_id, + const rnti_t rntiP, + const rb_id_t srb_idP, + const uint8_t *sduP, + const sdu_size_t sdu_lenP, + const boolean_t brOption +); + +int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, + const uint8_t *buffer, + int buffer_length, + const int CC_id); + void rrc_gNB_generate_dedicatedRRCReconfiguration_release( const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 9bea266ffd..dca6587d45 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1388,7 +1388,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, break; case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: - LOG_I(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti); + LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti); ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti); if (ue_context_p != NULL) { rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p); @@ -1495,15 +1495,16 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, CC_id); break; } - } - if (ue_context_p != NULL) { ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause; - } - rrc_gNB_generate_RRCSetup(ctxt_pP, - rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), - CC_id); + rrc_gNB_generate_RRCSetup(ctxt_pP, + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), + CC_id); + + // FIXME: Check the best place to perform this DRB configuration + nr_DRB_preconfiguration(ctxt_pP->rnti); + } break; case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index c1efc9550c..2336c758fc 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -39,6 +39,7 @@ #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" #include "executables/softmodem-common.h" #include +#include #include "UTIL/OSA/osa_defs.h" extern boolean_t nr_rrc_pdcp_config_asn1_req( @@ -425,7 +426,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0; } - itti_send_msg_to_task(TASK_GTPV1_U, rrc->module_id, msg_delete_tunnels_p); + itti_send_msg_to_task(TASK_VARIABLE, rrc->module_id, msg_delete_tunnels_p); /* remove context */ rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 8e60dafb27..455acb770c 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -228,33 +228,38 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->reconfigurationWithSync->t304=NR_ReconfigurationWithSync__t304_ms2000; secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = NULL; secondaryCellGroup->spCellConfig->reconfigurationWithSync->ext1 = NULL; - /* contention free ra */ - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated)); - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink; - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated)); - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA)); - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL; - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions)); - memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric, - &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t)); - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long)); - *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one; - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb; - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb)); - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0; - int n_ssb = 0; - struct NR_CFRA_SSB_Resource *ssbElem[64]; - for (int i=0;i<64;i++) { - if ((bitmap>>(63-i))&0x01){ - ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); - ssbElem[n_ssb]->ssb = i; - ssbElem[n_ssb]->ra_PreambleIndex = 63; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]); - n_ssb++; + // For 2-step contention-free random access procedure + if(get_softmodem_params()->sa == 0) { + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions)); + memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric, + &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long)); + *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0; + + int n_ssb = 0; + struct NR_CFRA_SSB_Resource *ssbElem[64]; + for (int i=0;i<64;i++) { + if ((bitmap>>(63-i))&0x01){ + ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[n_ssb]->ssb = i; + ssbElem[n_ssb]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]); + n_ssb++; + } } + + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL; } - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL; + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup)); @@ -294,7 +299,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList)); - n_ssb = 0; + int n_ssb = 0; NR_TCI_State_t *tcic[64]; for (int i=0;i<64;i++) { if ((bitmap>>(63-i))&0x01){ @@ -537,7 +542,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss); - + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1)); *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=0; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index e21859ded8..c78a1caf37 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -42,17 +42,71 @@ nr_mac_rrc_data_ind_ue( const module_id_t module_id, const int CC_id, const uint8_t gNB_index, + const frame_t frame, + const sub_frame_t sub_frame, + const rnti_t rnti, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len){ + sdu_size_t sdu_size = 0; switch(channel){ case NR_BCCH_BCH: AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); break; + case NR_BCCH_DL_SCH: - AssertFatal( nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len, 0, 0) == 0, "UE decode BCCH-DL-SCH error!\n"); + if (pdu_len>0) { + LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET, + gNB_index); + + MessageDef *message_p; + int msg_sdu_size = BCCH_SDU_SIZE; + + if (pdu_len > msg_sdu_size) { + LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = pdu_len; + } + + message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND); + memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size); + NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP + NR_RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP + NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; + NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; + itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); + } break; + + case CCCH: + if (pdu_len>0) { + LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index); + + MessageDef *message_p; + int msg_sdu_size = CCCH_SDU_SIZE; + + if (pdu_len > msg_sdu_size) { + LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = pdu_len; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND); + memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size); + NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = frame; //frameP + NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP + NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; + NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index; + NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; //rntiP + itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p); + } + break; + default: break; } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index f373d74230..def7ca6404 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -72,6 +72,7 @@ #include "nr_nas_msg_sim.h" #endif +NR_UE_RRC_INST_t *NR_UE_rrc_inst; /* NAS Attach request with IMSI */ static const char nr_nas_attach_req_imsi[] = { 0x07, 0x41, @@ -1365,10 +1366,10 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB (void **)&dl_ccch_msg, (uint8_t *)Srb_info->Rx_buffer.Payload, 100,0,0); - - // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); - // } + } if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); @@ -2472,7 +2473,6 @@ void *rrc_nrue_task( void *args_p ) { case NR_RRC_MAC_BCCH_DATA_IND: LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); - // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index, @@ -2480,6 +2480,7 @@ void *rrc_nrue_task( void *args_p ) { NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq, NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); + break; case NR_RRC_MAC_CCCH_DATA_IND: LOG_D(NR_RRC, "[UE %d] RNTI %x Received %s: frameP %d, gNB %d\n", @@ -2568,7 +2569,7 @@ void *rrc_nrue_task( void *args_p ) { LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; } - LOG_I(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id)); + LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id)); result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); msg_p = NULL; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 0acf6db634..534da0112b 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -109,7 +109,15 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui \param channel indicator for channel of the pdu \param pduP pointer to pdu \param pdu_len data length of pdu*/ -int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len); +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, + const int CC_id, + const uint8_t gNB_index, + const frame_t frame, + const sub_frame_t sub_frame, + const rnti_t rnti, + const channel_t channel, + const uint8_t* pduP, + const sdu_size_t pdu_len); /**\brief \param module_id module id diff --git a/openair2/RRC/NR_UE/rrc_vars.h b/openair2/RRC/NR_UE/rrc_vars.h index 5c74e5b5a8..30c74debdd 100644 --- a/openair2/RRC/NR_UE/rrc_vars.h +++ b/openair2/RRC/NR_UE/rrc_vars.h @@ -36,6 +36,6 @@ #include "rrc_defs.h" -NR_UE_RRC_INST_t *NR_UE_rrc_inst; +extern NR_UE_RRC_INST_t *NR_UE_rrc_inst; #endif diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c index 9b35ea6721..d583346a89 100644 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -87,8 +87,6 @@ pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex uint8_t nfapi_mode = 0; // Default to monolithic mode -uint32_t target_dl_mcs = 28; -uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; uint64_t num_missed_slots=0; @@ -120,7 +118,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; //Temp fix for inexistent NR upper layer unsigned char NB_gNB_INST = 1; -static char *itti_dump_file = NULL; int UE_scan = 1; int UE_scan_carrier = 0; @@ -148,7 +145,6 @@ extern void *udp_eNB_task(void *args_p); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; double cpuf; diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index 34190f7d15..58cc7184e7 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -667,7 +667,6 @@ typedef struct { unsigned char omv_enabled; // openair mobility visulizer unsigned char opp_enabled; // openair performance profiler unsigned char oeh_enabled; // openair event handler, with CLI this could provide a remote event management - char *itti_dump_file; unsigned char vcd_enabled; char *vcd_file; unsigned char eMBMS_active_state; @@ -717,12 +716,6 @@ typedef struct { */ unsigned char slot_isr; int slot_sfd; - rnti_t eNB_ue_module_id_to_rnti[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];/*!< \brief used by eNB, this array can be filled: - by local virtualization: set directly by UE, or by remote UEs: TODO add signalisation on ethernet emulation link from UE to eNB*/ - - module_id_t eNB_ue_local_uid_to_ue_module_id[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];/*!< \brief used by eNB, this array can be filled: - by local virtualization: set directly by UE, or by remote UEs: TODO add signalisation on ethernet emulation link from UE to eNB*/ - } Info; /* @}*/ diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 847002ab44..e1ea5cb08e 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -51,6 +51,7 @@ #include "gtpv1u_eNB_defs.h" #include "gtpv1u_eNB_task.h" #include "rrc_eNB_GTPV1U.h" +#include #undef GTP_DUMP_SOCKET @@ -308,7 +309,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( msgsrc != GTPV1U_MSG_FROM_SOURCE_ENB? "UDP DATA" : msgType == NW_GTP_END_MARKER?"END MARKER":"DATA FORWARDING"); - /* target enb */ + /* target enb */ if(msgType == NW_GTP_END_MARKER) { LOG_I(GTPU, "target end receive END MARKER\n"); ue_context_p->ue_context.handover_info->state = HO_END_MARKER; @@ -1497,15 +1498,15 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { stack_req.apiInfo.sendtoInfo.teid = tenb_x2u_teid; stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip rc = nwGtpv1uGpduMsgNew( - RC.gtpv1u_data_g->gtpv1u_stack, - tenb_x2u_teid, - NW_FALSE, - RC.gtpv1u_data_g->seq_num++, - data_req_p->buffer, - data_req_p->length, - data_req_p->offset, - &(stack_req.apiInfo.sendtoInfo.hMsg)); - + RC.gtpv1u_data_g->gtpv1u_stack, + tenb_x2u_teid, + NW_FALSE, + RC.gtpv1u_data_g->seq_num++, + data_req_p->buffer, + data_req_p->length, + data_req_p->offset, + &(stack_req.apiInfo.sendtoInfo.hMsg)); + if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", @@ -1515,7 +1516,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { pMsg = (NwGtpv1uMsgT *) stack_req.apiInfo.sendtoInfo.hMsg; pMsg->msgType = NW_GTP_END_MARKER; rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); - + if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", @@ -1535,11 +1536,11 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, stack_req.apiInfo.sendtoInfo.hMsg); - + if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); } - + gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req; memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req)); delete_tunnel_req.rnti = data_req_p->rnti; @@ -1547,7 +1548,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { } } } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT); } break; diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 178f21a44a..be887623bb 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -33,6 +33,7 @@ # include "memory.h" #include "nas_user.h" +#include // FIXME make command line option for NAS_UE_AUTOSTART # define NAS_UE_AUTOSTART 1 diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp new file mode 100644 index 0000000000..29633ba6ae --- /dev/null +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -0,0 +1,783 @@ +#include +using namespace std; + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#include +#include + +#include +#include +#include "common/utils/LOG/log.h" +#include +#include +#include +#include +//#include + +#pragma pack(1) + +typedef struct Gtpv1uMsgHeader { + uint8_t PN:1; + uint8_t S:1; + uint8_t E:1; + uint8_t spare:1; + uint8_t PT:1; + uint8_t version:3; + uint8_t msgType; + uint16_t msgLength; + teid_t teid; +} __attribute__((packed)) Gtpv1uMsgHeaderT; + +#pragma pack() + +// TS 29.060, table 7.1 defines the possible message types +// here are all the possible messages (3GPP R16) +#define GTP_ECHO_REQ (1) +#define GTP_ECHO_RSP (2) +#define GTP_ERROR_INDICATION (26) +#define GTP_SUPPORTED_EXTENSION_HEADER_INDICATION (31) +#define GTP_END_MARKER (254) +#define GTP_GPDU (255) + + +typedef struct ocp_gtpv1u_bearer_s { + /* TEID used in dl and ul */ + teid_t teid_incoming; ///< eNB TEID + teid_t teid_outgoing; ///< Remote TEID + in_addr_t outgoing_ip_addr; + struct in6_addr outgoing_ip6_addr; + tcp_udp_port_t outgoing_port; + uint16_t seqNum; + uint8_t npduNum; +} ocp_gtpv1u_bearer_t; + +typedef struct { + map bearers; +} teidData_t; + +typedef struct { + rnti_t rnti; + ebi_t rb_id; + gtpCallback callBack; +} rntiData_t; + +class gtpEndPoint { + public: + openAddr_t addr; + uint8_t foundAddr[20]; + int foundAddrLen; + int ipVersion; + map ue2te_mapping; + map te2ue_mapping; +}; + +class gtpEndPoints { + public: + pthread_mutex_t gtp_lock=PTHREAD_MUTEX_INITIALIZER; + // the instance id will be the Linux socket handler, as this is uniq + map instances; +}; + +gtpEndPoints globGtp; + + // note TEid 0 is reserved for specific usage: echo req/resp, error and supported extensions +static uint32_t gtpv1uNewTeid(void) { +#ifdef GTPV1U_LINEAR_TEID_ALLOCATION + g_gtpv1u_teid = g_gtpv1u_teid + 1; + return g_gtpv1u_teid; +#else + return random() + random() % (RAND_MAX - 1) + 1; +#endif +} + +int legacyInstanceMapping=0; +#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a) + +#define GTPV1U_HEADER_SIZE (8) +static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen, + bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { + AssertFatal(extHdrFlag==false,"Not developped"); + int headerAdditional=0; + + if ( seqNumFlag || npduNumFlag || extHdrFlag) + headerAdditional=4; + + uint8_t *buffer; + int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen; + AssertFatal((buffer=(uint8_t *) malloc(fullSize)) != NULL, ""); + Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *)buffer ; + // N should be 0 for us (it was used only in 2G and 3G) + msgHdr->PN=npduNumFlag; + msgHdr->S=seqNumFlag; + msgHdr->E=extHdrFlag; + msgHdr->spare=0; + //PT=0 is for GTP' TS 32.295 (charging) + msgHdr->PT=1; + msgHdr->version=1; + msgHdr->msgType=GTP_GPDU; + msgHdr->msgLength=htons(msgLen); + if ( seqNumFlag || extHdrFlag || npduNumFlag) + msgHdr->msgLength+=4; + msgHdr->teid=htonl(teid); + + if(seqNumFlag || extHdrFlag || npduNumFlag) { + *((uint16_t *) (buffer+8)) = seqNumFlag ? htons(seqNum) : 0x0000; + *((uint8_t *) (buffer+10)) = npduNumFlag ? htons(npduNum) : 0x00; + *((uint8_t *) (buffer+11)) = extHdrFlag ? htons(extHdrType) : 0x00; + } + + memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, Msg, msgLen); + // Fix me: add IPv6 support, using flag ipVersion + static struct sockaddr_in to= {0}; + to.sin_family = AF_INET; + to.sin_port = htons(peerPort); + to.sin_addr.s_addr = peerIp ; + LOG_D(GTPU,"sending packet size: %d to %s\n",fullSize, inet_ntoa(to.sin_addr) ); + + if (sendto(h, (void *)buffer, (size_t)fullSize, 0,(struct sockaddr *)&to, sizeof(to) ) != fullSize ) { + LOG_E(GTPU, + "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %u\n", + h, IPV4_ADDR_FORMAT(peerIp), peerPort, fullSize); + free(buffer); + return GTPNOK; + } + + free(buffer); + return !GTPNOK; +} + +static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) { + uint8_t *buffer=req->buffer+req->offset; + size_t length=req->length; + uint64_t rnti=req->rnti; + int rab_id=req->rab_id; + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + auto ptrRnti=inst->ue2te_mapping.find(rnti); + + if ( ptrRnti==inst->ue2te_mapping.end() ) { + LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + auto ptr=ptrRnti->second.bearers; + + if ( ptr.find(rab_id) == ptr.end() ) { + LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %lx/%x\n", rnti, rab_id); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } else + LOG_D(GTPU,"sending a packet to RNTI:RAB:teid %lx/%x/%x, len %lu, oldseq %d, oldnum %d\n", + rnti, rab_id,ptr[rab_id].teid_outgoing,length, ptr[rab_id].seqNum,ptr[rab_id].npduNum ); + + if(seqNumFlag) + ptr[rab_id].seqNum++; + + if(npduNumFlag) + ptr[rab_id].npduNum++; + + // We will release the lock, let's copy data before + ocp_gtpv1u_bearer_t tmp=ptr[rab_id]; + pthread_mutex_unlock(&globGtp.gtp_lock); + gtpv1uCreateAndSendMsg(compatInst(instance), + tmp.outgoing_ip_addr, + tmp.outgoing_port, + tmp.teid_outgoing, + buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; +} + +static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) { + uint64_t rnti=req->rnti; + int rab_id=req->rab_id; + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + auto ptrRnti=inst->ue2te_mapping.find(rnti); + + if ( ptrRnti==inst->ue2te_mapping.end() ) { + LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + auto ptr=ptrRnti->second.bearers; + + if ( ptr.find(rab_id) == ptr.end() ) { + LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %lx/%x\n", rnti, rab_id); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } else + LOG_D(GTPU,"sending a end packet packet to RNTI:RAB:teid %lx/%x/%x\n", + rnti, rab_id,ptr[rab_id].teid_outgoing); + ocp_gtpv1u_bearer_t tmp=ptr[rab_id]; + pthread_mutex_unlock(&globGtp.gtp_lock); + + Gtpv1uMsgHeaderT msgHdr; + // N should be 0 for us (it was used only in 2G and 3G) + msgHdr.PN=0; + msgHdr.S=0; + msgHdr.E=0; + msgHdr.spare=0; + //PT=0 is for GTP' TS 32.295 (charging) + msgHdr.PT=1; + msgHdr.version=1; + msgHdr.msgType=GTP_END_MARKER; + msgHdr.msgLength=htons(0); + msgHdr.teid=htonl(tmp.teid_outgoing); + + // Fix me: add IPv6 support, using flag ipVersion + static struct sockaddr_in to= {0}; + to.sin_family = AF_INET; + to.sin_port = htons(tmp.outgoing_port); + to.sin_addr.s_addr = tmp.outgoing_ip_addr; + LOG_D(GTPU,"sending end packet to %s\n", inet_ntoa(to.sin_addr) ); + + if (sendto(compatInst(instance), (void *)&msgHdr, sizeof(msgHdr), 0,(struct sockaddr *)&to, sizeof(to) ) != sizeof(msgHdr)) { + LOG_E(GTPU, + "[SD %ld] Failed to send data to " IPV4_ADDR " on port %d, buffer size %lu\n", + compatInst(instance), IPV4_ADDR_FORMAT(tmp.outgoing_ip_addr), tmp.outgoing_port, sizeof(msgHdr)); + } +} + +static int udpServerSocket(openAddr_s addr) { + LOG_I(GTPU, "Initializing UDP for local address %s with port %s\n", addr.originHost, addr.originService); + int status; + struct addrinfo hints= {0}, *servinfo, *p; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + if ((status = getaddrinfo(addr.originHost, addr.originService, &hints, &servinfo)) != 0) { + LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); + return -1; + } + + int sockfd=-1; + + // loop through all the results and bind to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + LOG_W(GTPU,"socket: %s\n", strerror(errno)); + continue; + } + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + LOG_W(GTPU,"bind: %s\n", strerror(errno)); + continue; + } else { + // We create the gtp instance on the socket + globGtp.instances[sockfd].addr=addr; + + if (p->ai_family == AF_INET) { + struct sockaddr_in *ipv4=(struct sockaddr_in *)p->ai_addr; + memcpy(globGtp.instances[sockfd].foundAddr, + &ipv4->sin_addr.s_addr, sizeof(ipv4->sin_addr.s_addr)); + globGtp.instances[sockfd].foundAddrLen=sizeof(ipv4->sin_addr.s_addr); + globGtp.instances[sockfd].ipVersion=4; + break; + } else if (p->ai_family == AF_INET6) { + LOG_W(GTPU,"Local address is IP v6\n"); + struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)p->ai_addr; + memcpy(globGtp.instances[sockfd].foundAddr, + &ipv6->sin6_addr.s6_addr, sizeof(ipv6->sin6_addr.s6_addr)); + globGtp.instances[sockfd].foundAddrLen=sizeof(ipv6->sin6_addr.s6_addr); + globGtp.instances[sockfd].ipVersion=6; + } else + AssertFatal(false,"Local address is not IPv4 or IPv6"); + } + + 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", addr.originHost, addr.originService); + return -1; + } + + freeaddrinfo(servinfo); // all done with this structure + + if (strlen(addr.destinationHost)>1) { + struct addrinfo hints; + memset(&hints,0,sizeof(hints)); + hints.ai_family=AF_UNSPEC; + hints.ai_socktype=SOCK_DGRAM; + hints.ai_protocol=0; + hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG; + struct addrinfo *res=0; + int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res); + + if (err==0) { + for(p = res; p != NULL; p = p->ai_next) { + if ((err=connect(sockfd, p->ai_addr, p->ai_addrlen))==0) + break; + } + } + + if (err) + LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService); + } + + int sendbuff = 1000*1000*10; + AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); + LOG_D(GTPU,"Created listener for paquets to: %s:%s, send buffer size: %d\n", addr.originHost, addr.originService,sendbuff); + return sockfd; +} + +instance_t ocp_gtpv1Init(openAddr_t context) { + pthread_mutex_lock(&globGtp.gtp_lock); + int id=udpServerSocket(context); + + if (id>=0) { + itti_subscribe_event_fd(OCP_GTPV1_U, id); + } else + LOG_E(GTPU,"can't create GTP-U instance\n"); + + pthread_mutex_unlock(&globGtp.gtp_lock); + return id; +} + +teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[instance]; + auto it=inst->ue2te_mapping.find(rnti); + + if ( it != inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", rnti); + inst->ue2te_mapping.erase(it); + } + + uint32_t s1u_teid=gtpv1uNewTeid(); + + while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) { + LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid); + s1u_teid=gtpv1uNewTeid(); + }; + + inst->te2ue_mapping[s1u_teid].rnti=rnti; + + inst->te2ue_mapping[s1u_teid].rb_id= teid; + + inst->te2ue_mapping[s1u_teid].callBack=callBack; + + auto tmp=&inst->ue2te_mapping[rnti].bearers[bearer_id]; + + int addrs_length_in_bytes = remoteAddr.length / 8; + + switch (addrs_length_in_bytes) { + case 4: + memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4); + break; + + case 16: + memcpy(tmp->outgoing_ip6_addr.s6_addr,remoteAddr.buffer, + 16); + break; + + case 20: + memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4); + memcpy(&tmp->outgoing_ip6_addr.s6_addr, + remoteAddr.buffer+4, + 16); + + default: + AssertFatal(false, "SGW Address size impossible"); + } + + tmp->teid_incoming = s1u_teid; + tmp->outgoing_port=port; + tmp->teid_outgoing= teid; + pthread_mutex_unlock(&globGtp.gtp_lock); + return s1u_teid; +} + +int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, + const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, + gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) { + LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %d\n", + create_tunnel_req->rnti, + create_tunnel_req->num_tunnels, + create_tunnel_req->sgw_S1u_teid[0]); + + for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { + teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, + create_tunnel_req->eps_bearer_id[i], + create_tunnel_req->sgw_S1u_teid[i], + create_tunnel_req->sgw_addr[i], 2152, + pdcp_data_req); + create_tunnel_resp->status=0; + create_tunnel_resp->rnti=create_tunnel_req->rnti; + create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; + create_tunnel_resp->enb_S1u_teid[i]=teid; + create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i]; + memcpy(create_tunnel_resp->enb_addr.buffer,globGtp.instances[compatInst(instance)].foundAddr, + globGtp.instances[compatInst(instance)].foundAddrLen); + create_tunnel_resp->enb_addr.length= globGtp.instances[compatInst(instance)].foundAddrLen; + } + + return !GTPNOK; +} + +int ocp_gtpv1u_update_s1u_tunnel( + const instance_t instance, + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req, + const rnti_t prior_rnti +) { + LOG_D(GTPU, "Start update tunnels for old RNTI %x, new RNTI %x, num_tunnels %d, sgw_S1u_teid %d, eps_bearer_id %d\n", + prior_rnti, + create_tunnel_req->rnti, + create_tunnel_req->num_tunnels, + create_tunnel_req->sgw_S1u_teid[0], + create_tunnel_req->eps_bearer_id[0]); + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + + if ( inst->ue2te_mapping.find(create_tunnel_req->rnti) == inst->ue2te_mapping.end() ) { + LOG_E(GTPU,"Update not already existing tunnel (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); + } + + auto it=inst->ue2te_mapping.find(prior_rnti); + + if ( it != inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Update a not existing tunnel, start create the new one (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + gtpv1u_enb_create_tunnel_resp_t tmp; + (void)ocp_gtpv1u_create_s1u_tunnel(instance, create_tunnel_req, &tmp); + return 0; + } + + inst->ue2te_mapping[create_tunnel_req->rnti]=it->second; + inst->ue2te_mapping.erase(it); + pthread_mutex_unlock(&globGtp.gtp_lock); + return 0; +} + +int ocp_gtpv1u_create_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP) { + AssertFatal( false, "to be developped\n"); +} + +int newGtpuDeleteTunnel(instance_t instance, rnti_t rnti) { + LOG_D(GTPU, "Start delete tunnels for RNTI %x\n", + rnti); + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + auto it=inst->ue2te_mapping.find(rnti); + + if ( it == inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Delete a non existing GTP tunnel\n"); + pthread_mutex_unlock(&globGtp.gtp_lock); + return -1; + } + + for (auto j=it->second.bearers.begin(); + j!=it->second.bearers.end(); + ++j) + inst->te2ue_mapping.erase(j->second.teid_incoming); + + inst->ue2te_mapping.erase(it); + pthread_mutex_unlock(&globGtp.gtp_lock); + return !GTPNOK; +} + +// Legacy delete tunnel finish by deleting all the rnti +// so the list of bearer provided is only a design bug +int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, + const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { + return newGtpuDeleteTunnel(instance, req_pP->rnti); +} + +static int Gtpv1uHandleEchoReq(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} + +static int Gtpv1uHandleError(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} + +static int Gtpv1uHandleSupportedExt(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} + + // When end marker arrives, we notify the client with buffer size = 0 + // The client will likely call "delete tunnel" + // nevertheless we don't take the initiative +static int Gtpv1uHandleEndMarker(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *) msgBuf; + if ( msgHdr->version != 1 || msgHdr->PT != 1 ) { + LOG_E(GTPU, "Received a packet that is not GTP header\n"); + return GTPNOK; + } + + pthread_mutex_lock(&globGtp.gtp_lock); + // the socket Linux file handler is the instance id + auto inst=&globGtp.instances[h]; + auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); + + if ( tunnel == inst->te2ue_mapping.end() ) { + LOG_E(GTPU,"Received a incoming packet on unknown teid (%d) Dropping!\n", msgHdr->teid); + pthread_mutex_unlock(&globGtp.gtp_lock); + return GTPNOK; + } + // This context is not good for gtp + // frame, ... has no meaning + // manyother attributes may come from create tunnel + protocol_ctxt_t ctxt; + ctxt.module_id = 0; + ctxt.enb_flag = 1; + ctxt.instance = inst->addr.originInstance; + ctxt.rnti = tunnel->second.rnti; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 0; + ctxt.brOption = 0; + const srb_flag_t srb_flag=SRB_FLAG_NO; + const rb_id_t rb_id=tunnel->second.rb_id; + const mui_t mui=RLC_MUI_UNDEFINED; + const confirm_t confirm=RLC_SDU_CONFIRM_NO; + const pdcp_transmission_mode_t mode=PDCP_TRANSMISSION_MODE_DATA; + const uint32_t sourceL2Id=0; + const uint32_t destinationL2Id=0; + pthread_mutex_unlock(&globGtp.gtp_lock); + + if ( !tunnel->second.callBack(&ctxt, + srb_flag, + rb_id, + mui, + confirm, + 0, + NULL, + mode, + &sourceL2Id, + &destinationL2Id) ) + LOG_E(GTPU,"down layer refused incoming packet\n"); + + LOG_D(GTPU,"Received END marker packet for: teid:%x\n", ntohl(msgHdr->teid)); + return !GTPNOK; +} + +static int Gtpv1uHandleGpdu(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *) msgBuf; + + if ( msgHdr->version != 1 || msgHdr->PT != 1 ) { + LOG_E(GTPU, "Received a packet that is not GTP header\n"); + return GTPNOK; + } + + pthread_mutex_lock(&globGtp.gtp_lock); + // the socket Linux file handler is the instance id + auto inst=&globGtp.instances[h]; + auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); + + if ( tunnel == inst->te2ue_mapping.end() ) { + LOG_E(GTPU,"Received a incoming packet on unknown teid (%d) Dropping!\n", msgHdr->teid); + pthread_mutex_unlock(&globGtp.gtp_lock); + return GTPNOK; + } + + int offset=8; + + if( msgHdr->E || msgHdr->S ||msgHdr->PN) + offset+=4; + + // This context is not good for gtp + // frame, ... has no meaning + // manyother attributes may come from create tunnel + protocol_ctxt_t ctxt; + ctxt.module_id = 0; + ctxt.enb_flag = 1; + ctxt.instance = inst->addr.originInstance; + ctxt.rnti = tunnel->second.rnti; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 0; + ctxt.brOption = 0; + const srb_flag_t srb_flag=SRB_FLAG_NO; + const rb_id_t rb_id=tunnel->second.rb_id; + const mui_t mui=RLC_MUI_UNDEFINED; + const confirm_t confirm=RLC_SDU_CONFIRM_NO; + const sdu_size_t sdu_buffer_size=msgBufLen-offset; + unsigned char *const sdu_buffer=msgBuf+offset; + const pdcp_transmission_mode_t mode=PDCP_TRANSMISSION_MODE_DATA; + const uint32_t sourceL2Id=0; + const uint32_t destinationL2Id=0; + pthread_mutex_unlock(&globGtp.gtp_lock); + + if ( !tunnel->second.callBack(&ctxt, + srb_flag, + rb_id, + mui, + confirm, + sdu_buffer_size, + sdu_buffer, + mode, + &sourceL2Id, + &destinationL2Id) ) + LOG_E(GTPU,"down layer refused incoming packet\n"); + + LOG_D(GTPU,"Received a %d bytes packet for: teid:%x\n", + msgBufLen-offset, + ntohl(msgHdr->teid)); + return !GTPNOK; +} + +void gtpv1uReceiver(int h) { + uint8_t udpData[65536]; + int udpDataLen; + socklen_t from_len; + struct sockaddr_in addr; + from_len = (socklen_t)sizeof(struct sockaddr_in); + + if ((udpDataLen = recvfrom(h, udpData, sizeof(udpData), 0, + (struct sockaddr *)&addr, &from_len)) < 0) { + LOG_E(GTPU, "Recvfrom failed on %d (%s)\n", h, strerror(errno)); + return; + } else if (udpDataLen == 0) { + LOG_W(GTPU, "Recvfrom returned 0\n"); + return; + } else { + uint8_t msgType = *((uint8_t *)(udpData + 1)); + LOG_D(GTPU, "Received GTP data, msg type: %x\n", msgType); + + switch(msgType) { + case GTP_ECHO_RSP: + break; + + case GTP_ECHO_REQ: + Gtpv1uHandleEchoReq( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_ERROR_INDICATION: + Gtpv1uHandleError( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION: + Gtpv1uHandleSupportedExt( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_END_MARKER: + Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_GPDU: + Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + default: + LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType); + break; + } + } +} + +#include + +void *ocp_gtpv1uTask(void *args) { + while(1) { + /* Trying to fetch a message from the message queue. + If the queue is empty, this function will block till a + message is sent to the task. + */ + MessageDef *message_p = NULL; + itti_receive_msg(OCP_GTPV1_U, &message_p); + + if (message_p != NULL ) { + openAddr_t addr= {0}; + + switch (ITTI_MSG_ID(message_p)) { + // DATA TO BE SENT TO UDP + case GTPV1U_ENB_TUNNEL_DATA_REQ: { + gtpv1uSend(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), + >PV1U_ENB_TUNNEL_DATA_REQ(message_p), false, false); + itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer); + } + break; + + case TERMINATE_MESSAGE: + break; + + case TIMER_HAS_EXPIRED: + LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p)); + break; + + case GTPV1U_ENB_END_MARKER_REQ: + gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), + >PV1U_ENB_TUNNEL_DATA_REQ(message_p)); + itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer); + break; + + case GTPV1U_ENB_DATA_FORWARDING_REQ: + case GTPV1U_ENB_DATA_FORWARDING_IND: + case GTPV1U_ENB_END_MARKER_IND: + LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p)); + abort(); + break; + + case GTPV1U_ENB_S1_REQ: + // to be dev: should be removed, to use API + strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr); + strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr); + AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n"); + break; + + default: + LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + abort(); + break; + } + + AssertFatal(EXIT_SUCCESS==itti_free(OCP_GTPV1_U, message_p), "Failed to free memory!\n"); + } + + struct epoll_event *events; + + int nb_events = itti_get_events(OCP_GTPV1_U, &events); + + for (int i = 0; i < nb_events; i++) + if ((events[i].events&EPOLLIN)) + gtpv1uReceiver(events[i].data.fd); + } + + return NULL; +} + +#ifdef __cplusplus +} +#endif diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h new file mode 100644 index 0000000000..507aa1338e --- /dev/null +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -0,0 +1,71 @@ +#ifndef __GTPUNEW_ITF_H__ +#define __GTPUNEW_ITF_H__ +#define GTPNOK -1 + +# define GTPU_HEADER_OVERHEAD_MAX 64 +#ifdef __cplusplus +extern "C" { +#endif + +#include +#if defined(NEW_GTPU) +#define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel +#define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel +#define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel +#define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel +#define gtpv1u_eNB_task ocp_gtpv1uTask +#define gtpv1u_gNB_task ocp_gtpv1uTask +#define TASK_VARIABLE OCP_GTPV1_U +#else +#define TASK_VARIABLE TASK_GTPV1_U +#endif + +typedef boolean_t (*gtpCallback)( + protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id); + +typedef struct openAddr_s { + char originHost[HOST_NAME_MAX]; + char originService[HOST_NAME_MAX]; + char destinationHost[HOST_NAME_MAX]; + char destinationService[HOST_NAME_MAX]; + instance_t originInstance; +} openAddr_t; + +// the init function create a gtp instance and return the gtp instance id +// the parameter originInstance will be sent back in each message from gtp to the creator +void ocp_gtpv1uReceiver(int h); +void ocp_gtpv1uProcessTimeout(int handle,void *arg); +int ocp_gtpv1u_create_s1u_tunnel(const instance_t instance, const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, + gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp); +int ocp_gtpv1u_update_s1u_tunnel(const instance_t instanceP, + const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req_pP, + const rnti_t prior_rnti + ); +int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); +int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); + +int ocp_gtpv1u_create_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP); + + +// New API +teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, + transport_layer_addr_t remoteAddr, int port, gtpCallback callBack); +instance_t ocp_gtpv1Init(openAddr_t context); +void *ocp_gtpv1uTask(void *args); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 93e9ffb52f..2ab6d29d30 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -33,6 +33,7 @@ #ifndef COMMON_LIB_H #define COMMON_LIB_H #include +#include #include #include #include "record_player.h" diff --git a/targets/ARCH/COMMON/record_player.c b/targets/ARCH/COMMON/record_player.c index 2dcd61e479..522f6b6d16 100644 --- a/targets/ARCH/COMMON/record_player.c +++ b/targets/ARCH/COMMON/record_player.c @@ -68,8 +68,10 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_ *recplay_conf=NULL; } - if (u_sf_replay == 1) return RECPLAY_REPLAYMODE; - else if (u_sf_record == 1) return RECPLAY_RECORDMODE; + if (u_sf_replay == 1) + return RECPLAY_REPLAYMODE; + else if (u_sf_record == 1) + return RECPLAY_RECORDMODE; return 0; } @@ -80,7 +82,7 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_ */ void iqrecorder_end(openair0_device *device) { if (device->recplay_state != NULL) { // subframes store - iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,OAIIQFILE_ID}; + iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID}; recplay_state_t *rs = device->recplay_state; recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf; rs->pFile = fopen (rc->u_sf_filename,"wb+"); @@ -91,16 +93,20 @@ void iqrecorder_end(openair0_device *device) { unsigned int i = 0; unsigned int modu = 0; - if ((modu = rs->nb_samples % 10) != 0) { - rs->nb_samples -= modu; // store entire number of frames + if ((modu = rs->nbSamplesBlocks % 10) != 0) { + rs->nbSamplesBlocks -= modu; // store entire number of frames } + fh.nbSamplesBlocks=rs->nbSamplesBlocks; LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename ); fwrite(&fh, sizeof(fh), 1, rs->pFile); - LOG_UI(HW,"Writing %u subframes to %s \n",rs->nb_samples, rc->u_sf_filename ); + LOG_UI(HW,"Writing %u subframes to %s \n",rs->nbSamplesBlocks, rc->u_sf_filename ); + uint8_t *ptr=(uint8_t *)rs->ms_sample; - for (i = 0; i < rs->nb_samples; i++) { - fwrite(rs->ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), rs->pFile); + for (i = 0; i < rs->nbSamplesBlocks; i++) { + int blockBytes=sizeof(iqrec_t)+((iqrec_t *)ptr)->nbBytes; + fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile); + ptr+=blockBytes; } fclose (rs->pFile); @@ -112,4 +118,4 @@ void iqrecorder_end(openair0_device *device) { rs->ms_sample = NULL; } } -} \ No newline at end of file +} diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h index 500acdd709..d91da68323 100644 --- a/targets/ARCH/COMMON/record_player.h +++ b/targets/ARCH/COMMON/record_player.h @@ -46,21 +46,22 @@ extern "C" #define BELL_LABS_IQ_HEADER 0xabababababababab #define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now #define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4) +#define MAX_BELL_LABS_IQ_BYTES_PER_SF BELL_LABS_IQ_BYTES_PER_SF*10 -#define OAIIQFILE_ID "OIQF" +#define OAIIQFILE_ID {'O', 'I','Q','F'} typedef struct { uint64_t devtype; uint64_t tx_sample_advance; double bw; + unsigned int nbSamplesBlocks; char oaiid[4]; } iqfile_header_t; typedef struct { int64_t header; int64_t ts; - int64_t rfu1; + int64_t nbBytes; int64_t rfu2; // pad for 256 bits alignement required by AVX2 - unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe } iqrec_t; #define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz) #define DEF_SF_FILE "/tmp/iqfile" // default subframes file name @@ -114,14 +115,16 @@ typedef struct { int use_mmap; // default is to use mmap size_t mapsize; FILE *pFile; - int mmapfd; - int iqfd; + int fd; iqrec_t *ms_sample; // memory for all subframes - unsigned int nb_samples; + unsigned int nbSamplesBlocks; + uint8_t *currentPtr; + uint64_t currentTs; + unsigned int curSamplesBlock; + int64_t wrap_count; + size_t maxSizeBytes; } recplay_state_t; - - #ifdef __cplusplus } #endif diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index dce410de47..f35a18eb0e 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -42,7 +42,6 @@ #include #include #include -#include #include "common_lib.h" #include "ethernet_lib.h" diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 61a742af65..bed7faf161 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -153,7 +153,7 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) { } static int sync_to_gps(openair0_device *device) { - uhd::set_thread_priority_safe(); + //uhd::set_thread_priority_safe(); //std::string args; //Set up program options //po::options_description desc("Allowed options"); @@ -276,7 +276,7 @@ static int trx_usrp_start(openair0_device *device) { // setup GPIO for TDD, GPIO(4) = ATR_RX //set data direction register (DDR) to output s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff); - //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually) + //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually) s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff); //set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX) s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f); @@ -301,7 +301,7 @@ static int trx_usrp_start(openair0_device *device) { } uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - cmd.time_spec = uhd::time_spec_t(1.0); + cmd.time_spec = uhd::time_spec_t(1.0); cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); @@ -315,7 +315,7 @@ static void trx_usrp_end(openair0_device *device) { return; usrp_state_t *s = (usrp_state_t *)device->priv; - + if (s == NULL) return; iqrecorder_end(device); @@ -436,7 +436,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0])); ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); - } + } else { ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); } @@ -480,7 +480,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI @param antenna_id index of the antenna if the device has multiple antennas @param flags flags must be set to TRUE if timestamp parameter needs to be applied */ -void *trx_usrp_write_thread(void * arg){ +void *trx_usrp_write_thread(void * arg){ int ret=0; openair0_device *device=(openair0_device *)arg; openair0_thread_t *write_thread = &device->write_thread; @@ -549,7 +549,7 @@ void *trx_usrp_write_thread(void * arg){ } } - + s->tx_md.has_time_spec = true; s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet; s->tx_md.end_of_burst = last_packet; @@ -572,7 +572,7 @@ void *trx_usrp_write_thread(void * arg){ buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0])); ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); - } + } else { ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); } @@ -589,7 +589,7 @@ void *trx_usrp_write_thread(void * arg){ int trx_usrp_write_init(openair0_device *device){ - uhd::set_thread_priority_safe(1.0); + //uhd::set_thread_priority_safe(1.0); openair0_thread_t *write_thread = &device->write_thread; printf("initializing tx write thread\n"); @@ -697,15 +697,23 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->usrp->set_gpio_attr("FP0", "OUT", gpio789<<7, 0x380); s->usrp->clear_command_time(); gpio789 = (gpio789+1)&7;*/ + recplay_state_t *recPlay=device->recplay_state; - if (device->recplay_state != NULL) { // record mode + if ( recPlay != NULL) { // record mode // Copy subframes to memory (later dump on a file) - if (device->recplay_state->nb_samples < device->openair0_cfg->recplay_conf->u_sf_max) { - (device->recplay_state->ms_sample+device->recplay_state->nb_samples)->header = BELL_LABS_IQ_HEADER; - (device->recplay_state->ms_sample+device->recplay_state->nb_samples)->ts = *ptimestamp; - memcpy((device->recplay_state->ms_sample+device->recplay_state->nb_samples)->samples, buff[0], nsamps*4); - device->recplay_state->nb_samples++; - } else exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n"); + if (recPlay->nbSamplesBlocks < device->openair0_cfg->recplay_conf->u_sf_max && + recPlay->maxSizeBytes > (recPlay->currentPtr-(uint8_t *)recPlay->ms_sample) + + sizeof(iqrec_t) + nsamps*4 ) { + iqrec_t *hdr=(iqrec_t *)recPlay->currentPtr; + hdr->header = BELL_LABS_IQ_HEADER; + hdr->ts = *ptimestamp; + hdr->nbBytes=nsamps*4; + memcpy(hdr+1, buff[0], nsamps*4); + recPlay->currentPtr+=sizeof(iqrec_t)+nsamps*4; + recPlay->nbSamplesBlocks++; + LOG_D(HW,"recorded %d samples, for TS %lu, shift in buffer %ld\n", nsamps, hdr->ts, recPlay->currentPtr-(uint8_t *)recPlay->ms_sample); + } else + exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n"); } return samples_received; @@ -940,29 +948,29 @@ extern "C" { // hotfix! to be checked later - uhd::set_thread_priority_safe(1.0); + //uhd::set_thread_priority_safe(1.0); // Initialize USRP device int vers=0,subvers=0,subsubvers=0; int bw_gain_adjust=0; - + if (device->openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) { std::cerr << "USRP device initialized in subframes record mode" << std::endl; } - + sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); LOG_I(HW,"UHD version %s (%d.%d.%d)\n", uhd::get_version_string().c_str(),vers,subvers,subsubvers); std::string args; - + if (openair0_cfg[0].sdr_addrs == NULL) { args = "type=b200"; } else { args = openair0_cfg[0].sdr_addrs; LOG_I(HW,"Checking for USRP with args %s\n",openair0_cfg[0].sdr_addrs); } - + uhd::device_addrs_t device_adds = uhd::device::find(args); - + if (device_adds.size() == 0) { LOG_E(HW,"No USRP Device Found.\n "); free(s); @@ -972,38 +980,38 @@ extern "C" { free(s); return -1; } - + LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str()); double usrp_master_clock; - + if (device_adds[0].get("type") == "b200") { device->type = USRP_B200_DEV; usrp_master_clock = 30.72e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ; } - + if (device_adds[0].get("type") == "n3xx") { printf("Found USRP n300\n"); - device->type=USRP_N300_DEV; + device->type=USRP_N300_DEV; usrp_master_clock = 122.88e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); //args += ", send_buff_size=33554432"; } - + if (device_adds[0].get("type") == "x300") { printf("Found USRP x300\n"); device->type=USRP_X300_DEV; usrp_master_clock = 184.32e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - + // USRP recommended: https://files.ettus.com/manual/page_usrp_x3x0_config.html if ( 0 != system("sysctl -w net.core.rmem_max=33554432 net.core.wmem_max=33554432") ) LOG_W(HW,"Can't set kernel parameters for X3xx\n"); } - + s->usrp = uhd::usrp::multi_usrp::make(args); - + if (args.find("clock_source")==std::string::npos) { if (openair0_cfg[0].clock_source == internal) { s->usrp->set_clock_source("internal"); @@ -1017,7 +1025,7 @@ extern "C" { s->usrp->set_clock_source("gpsdo"); LOG_D(HW,"Setting clock source to gpsdo\n"); } - else { + else { LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n"); } } @@ -1040,7 +1048,7 @@ extern "C" { s->usrp->set_time_source("gpsdo"); LOG_D(HW,"Setting time source to gpsdo\n"); } - else { + else { LOG_W(HW,"Time source set neither in usrp_args nor on command line, using default!\n"); } } @@ -1050,10 +1058,10 @@ extern "C" { } } - + if (s->usrp->get_clock_source(0) == "gpsdo") { s->use_gps = 1; - + if (sync_to_gps(device)==EXIT_SUCCESS) { LOG_I(HW,"USRP synced with GPS!\n"); } else { @@ -1068,15 +1076,15 @@ extern "C" { exit(EXIT_FAILURE); } } - + if (device->type==USRP_X300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; + std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; } if (device->type==USRP_N300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_n310; - std::cerr << "-- Using calibration table: calib_table_n310" << std::endl; + std::cerr << "-- Using calibration table: calib_table_n310" << std::endl; } @@ -1091,7 +1099,7 @@ extern "C" { openair0_cfg[0].tx_bw = 80e6; openair0_cfg[0].rx_bw = 80e6; break; - + case 92160000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; @@ -1099,7 +1107,7 @@ extern "C" { openair0_cfg[0].tx_bw = 80e6; openair0_cfg[0].rx_bw = 80e6; break; - + case 61440000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; @@ -1107,14 +1115,14 @@ extern "C" { openair0_cfg[0].tx_bw = 40e6; openair0_cfg[0].rx_bw = 40e6; break; - + case 46080000: //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 65; + openair0_cfg[0].tx_sample_advance = 15; openair0_cfg[0].tx_bw = 40e6; openair0_cfg[0].rx_bw = 40e6; break; - + case 30720000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; @@ -1122,35 +1130,35 @@ extern "C" { openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6; break; - + case 15360000: //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_sample_advance = 45; openair0_cfg[0].tx_bw = 10e6; openair0_cfg[0].rx_bw = 10e6; break; - + case 7680000: //openair0_cfg[0].samples_per_packet = 2048; openair0_cfg[0].tx_sample_advance = 50; openair0_cfg[0].tx_bw = 5e6; openair0_cfg[0].rx_bw = 5e6; break; - + case 1920000: //openair0_cfg[0].samples_per_packet = 2048; openair0_cfg[0].tx_sample_advance = 50; openair0_cfg[0].tx_bw = 1.25e6; openair0_cfg[0].rx_bw = 1.25e6; break; - + default: LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); exit(-1); break; } } - + if (device->type == USRP_B200_DEV) { if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { openair0_cfg[0].rx_gain_calib_table = calib_table_b210; @@ -1161,7 +1169,7 @@ extern "C" { bw_gain_adjust=1; std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info } - + switch ((int)openair0_cfg[0].sample_rate) { case 46080000: s->usrp->set_master_clock_rate(46.08e6); @@ -1170,7 +1178,7 @@ extern "C" { openair0_cfg[0].tx_bw = 40e6; openair0_cfg[0].rx_bw = 40e6; break; - + case 30720000: s->usrp->set_master_clock_rate(30.72e6); //openair0_cfg[0].samples_per_packet = 1024; @@ -1178,7 +1186,7 @@ extern "C" { openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6; break; - + case 23040000: s->usrp->set_master_clock_rate(23.04e6); //to be checked //openair0_cfg[0].samples_per_packet = 1024; @@ -1186,7 +1194,7 @@ extern "C" { openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6; break; - + case 15360000: s->usrp->set_master_clock_rate(30.72e06); //openair0_cfg[0].samples_per_packet = 1024; @@ -1194,7 +1202,7 @@ extern "C" { openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6; break; - + case 7680000: s->usrp->set_master_clock_rate(30.72e6); //openair0_cfg[0].samples_per_packet = 1024; @@ -1202,7 +1210,7 @@ extern "C" { openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6; break; - + case 1920000: s->usrp->set_master_clock_rate(30.72e6); //openair0_cfg[0].samples_per_packet = 1024; @@ -1210,20 +1218,20 @@ extern "C" { openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6; break; - + default: LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); exit(-1); break; } } - + /* device specific */ //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - + for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) { if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); @@ -1240,13 +1248,13 @@ extern "C" { openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); } } - + LOG_D(HW, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels()); LOG_D(HW, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels); - + for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) { ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); - + if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); @@ -1254,7 +1262,7 @@ extern "C" { LOG_I(HW,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); } } - + //s->usrp->set_clock_source("external"); //s->usrp->set_time_source("external"); // display USRP settings @@ -1268,32 +1276,32 @@ extern "C" { int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); samples/=10000; LOG_I(HW,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); - + if ( samples < max ) { stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); } - + LOG_I(HW,"rx_max_num_samps %zu\n", s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); - + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); uhd::stream_args_t stream_args_tx("sc16", "sc16"); - + for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - + /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - + for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - + for (int i=0; iusrp->get_rx_rate(i)/1e6); @@ -1302,7 +1310,7 @@ extern "C" { LOG_I(HW," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); LOG_I(HW," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); } - + for (int i=0; iusrp->get_tx_rate(i)/1e6); @@ -1312,33 +1320,35 @@ extern "C" { LOG_I(HW," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); LOG_I(HW," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps()); } - + LOG_I(HW,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; s->sample_rate = openair0_cfg[0].sample_rate; - + // TODO: // init tx_forward_nsamps based usrp_time_offset ex if(is_equal(s->sample_rate, (double)30.72e6)) s->tx_forward_nsamps = 176; - + if(is_equal(s->sample_rate, (double)15.36e6)) s->tx_forward_nsamps = 90; - + if(is_equal(s->sample_rate, (double)7.68e6)) s->tx_forward_nsamps = 50; - - - if (device->recplay_state != NULL) { // record mode - device->recplay_state->ms_sample = (iqrec_t *) malloc(openair0_cfg[0].recplay_conf->u_sf_max * sizeof(iqrec_t)); - - if (device->recplay_state->ms_sample == NULL) { + + recplay_state_t *recPlay=device->recplay_state; + + if (recPlay != NULL) { // record mode + recPlay->maxSizeBytes=openair0_cfg[0].recplay_conf->u_sf_max * + (sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF); + recPlay->ms_sample = (iqrec_t *) malloc(recPlay->maxSizeBytes); + recPlay->currentPtr= (uint8_t *)recPlay->ms_sample; + + if (recPlay->ms_sample == NULL) { std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; exit(-1); } - - memset(device->recplay_state->ms_sample, 0, openair0_cfg[0].recplay_conf->u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); } return 0; } diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index 66308d4b1c..8b6844f9d3 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -39,18 +39,15 @@ #include "assertions.h" #include "common/utils/LOG/log.h" - - - - - static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) { - AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0), - "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n", - iq_fh->oaiid); + char tmp[4]=OAIIQFILE_ID; + AssertFatal((memcmp(iq_fh->oaiid,tmp,sizeof(iq_fh->oaiid)) == 0), + "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n", + iq_fh->oaiid); device->type = iq_fh->devtype; device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance; device->openair0_cfg[0].tx_bw = device->openair0_cfg[0].rx_bw = iq_fh->bw; + device->recplay_state->nbSamplesBlocks=iq_fh->nbSamplesBlocks; LOG_UI(HW,"Replay iqs from %s device, bandwidth %e\n",get_devname(iq_fh->devtype),iq_fh->bw); } @@ -62,89 +59,73 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair recplay_state_t *s = device->recplay_state; recplay_conf_t *c = openair0_cfg->recplay_conf; + struct stat sb; + s->fd = open(c->u_sf_filename, O_RDONLY ); + if (s->fd >= 0 ) { + fstat(s->fd, &sb); + } else { + LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename ); + exit(-1); + } + if (s->use_mmap) { // use mmap - s->mmapfd = open(c->u_sf_filename, O_RDONLY ); - - if (s->mmapfd != 0) { - struct stat sb; - fstat(s->mmapfd, &sb); s->mapsize=sb.st_size; LOG_I(HW,"Loading subframes using mmap() from %s size=%lu bytes ...\n",c->u_sf_filename, (uint64_t)sb.st_size ); - void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) ; - s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) + sizeof(iqfile_header_t)); + void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) ; + s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) + sizeof(iqfile_header_t)); if (mptr != MAP_FAILED) { parse_iqfile_header(device, (iqfile_header_t *)mptr); s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t)); - s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t)) / sizeof(iqrec_t)); - int aligned = (((unsigned long)s->ms_sample & 31) == 0)? 1:0; - LOG_I(HW,"Loaded %u subframes.\n",s->nb_samples ); - - if (aligned == 0) { - LOG_E(HW, "mmap address is not 32 bytes aligned, exiting.\n" ); - close(s->mmapfd); - exit(-1); - } + LOG_I(HW,"Loaded %u subframes.\n",s->nbSamplesBlocks ); } else { LOG_E(HW,"Cannot mmap file, exiting.\n"); - close(s->mmapfd); + close(s->fd); exit(-1); } - } else { - LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename ); - exit(-1); - } } else { - s->iqfd = open(c->u_sf_filename, O_RDONLY); + iqfile_header_t fh; + size_t hs = read(s->fd,&fh,sizeof(fh)); - if (s->iqfd != 0) { - struct stat sb; - iqfile_header_t fh; - size_t hs = read(s->iqfd,&fh,sizeof(fh)); - - if (hs == sizeof(fh)) { - parse_iqfile_header(device, &fh); - fstat(s->iqfd, &sb); + if (hs == sizeof(fh)) { + parse_iqfile_header(device, &fh); + fstat(s->fd, &sb); s->mapsize=sb.st_size; - s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t))/ sizeof(iqrec_t)); - LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nb_samples, c->u_sf_filename,(uint64_t)sb.st_size); + LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nbSamplesBlocks, c->u_sf_filename,(uint64_t)sb.st_size); // allocate buffer for 1 sample at a time - s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); + s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)+MAX_BELL_LABS_IQ_BYTES_PER_SF*4); if (s->ms_sample == NULL) { LOG_E(HW,"Memory allocation failed for individual subframe replay mode.\n" ); - close(s->iqfd); + close(s->fd); exit(-1); } memset(s->ms_sample, 0, sizeof(iqrec_t)); // point at beginning of iqs in file - if (lseek(s->iqfd,sizeof(iqfile_header_t), SEEK_SET) == 0) { + if (lseek(s->fd,sizeof(iqfile_header_t), SEEK_SET) == 0) { LOG_I(HW,"Initial seek at beginning of the file\n" ); } else { LOG_I(HW,"Problem initial seek at beginning of the file\n"); } } else { LOG_E(HW,"Cannot read header in %s exiting.\n",c->u_sf_filename ); - close(s->iqfd); + close(s->fd); exit(-1); } - } else { - LOG_E(HW,"Cannot open %s exiting.\n",c->u_sf_filename ); - exit(-1); - } } + s->currentPtr=(uint8_t *)s->ms_sample; return 0; } /*! \brief start the oai iq player * \param device, the hardware used */ -static int trx_iqplayer_start(openair0_device *device){ - return 0; +static int trx_iqplayer_start(openair0_device *device) { + return 0; } /*! \brief Terminate operation of the oai iq player @@ -156,28 +137,22 @@ static void trx_iqplayer_end(openair0_device *device) { if (device->recplay_state == NULL) return; - + if (device->recplay_state->use_mmap) { if (device->recplay_state->ms_sample != MAP_FAILED) { munmap(device->recplay_state->ms_sample, device->recplay_state->mapsize); - device->recplay_state->ms_sample = NULL; - } - - if (device->recplay_state->mmapfd != 0) { - close(device->recplay_state->mmapfd); - device->recplay_state->mmapfd = 0; - } + } } else { if (device->recplay_state->ms_sample != NULL) { free(device->recplay_state->ms_sample); - device->recplay_state->ms_sample = NULL; - } - - if (device->recplay_state->iqfd != 0) { - close(device->recplay_state->iqfd); - device->recplay_state->iqfd = 0; - } + } } + device->recplay_state->ms_sample = NULL; + if (device->recplay_state->fd >= 0) { + close(device->recplay_state->fd); + device->recplay_state->fd = -1; + } + } /*! \brief Write iqs function when in replay mode, just introduce a delay, as configured at init time, @param device pointer to the device structure specific to the RF hardware target @@ -207,93 +182,68 @@ static int trx_iqplayer_write(openair0_device *device, openair0_timestamp timest * \returns the number of sample read */ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - int samples_received=0; - static unsigned int cur_samples; - static int64_t wrap_count; - static int64_t wrap_ts; recplay_state_t *s = device->recplay_state; - if (cur_samples == s->nb_samples) { - cur_samples = 0; - wrap_count++; + if (s->curSamplesBlock==0 && s->wrap_count==0 ) + s->currentTs=s->ms_sample->ts; + + if (s->curSamplesBlock == s->nbSamplesBlocks) { + LOG_I(HW, "wrapping on iq file (%ld)\n", s->wrap_count); + s->curSamplesBlock = 0; + s->wrap_count++; - if (wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) { - LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n",device->openair0_cfg->recplay_conf->u_sf_loops); + if (s->wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) { + LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n", + device->openair0_cfg->recplay_conf->u_sf_loops); exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n"); } - wrap_ts = wrap_count * (s->nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); + LOG_I(HW,"go back at the beginning of IQ file"); + device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample; - if (!device->recplay_state->use_mmap) { - if (lseek(device->recplay_state->iqfd, 0, SEEK_SET) == 0) { - LOG_I(HW,"Seeking at the beginning of IQ file"); - } else { - LOG_I(HW, "Problem seeking at the beginning of IQ file"); + if (!s->use_mmap) { + if (lseek(device->recplay_state->fd, 0, SEEK_SET) != 0) { + LOG_E(HW, "Problem seeking at the beginning of IQ file"); } } } - if (s->use_mmap) { - if (cur_samples < s->nb_samples) { - *ptimestamp = (s->ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; - - if (cur_samples == 0) { - LOG_I(HW,"starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu\n", wrap_count,wrap_ts,*ptimestamp); - } - - memcpy(buff[0], &s->ms_sample[cur_samples].samples[0], nsamps*4); - cur_samples++; - } - } else { + if (!s->use_mmap) { // read sample from file - if (read(s->iqfd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { - LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*cur_samples ); - close(s->iqfd); - free(s->ms_sample); - s->ms_sample = NULL; - s->iqfd = 0; + if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { + LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock ); exit(-1); - } - - if (cur_samples < s->nb_samples) { - static int64_t ts0 = 0; - - if ((cur_samples == 0) && (wrap_count == 0)) { - ts0 = s->ms_sample->ts; - } - - *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; - - if (cur_samples == 0) { - LOG_I(HW, "starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu ",wrap_count,wrap_ts, *ptimestamp); - } - - memcpy(buff[0], &s->ms_sample->samples[0], nsamps*4); - cur_samples++; - // Prepare for next read - off_t where = lseek(s->iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); - - if (where < 0) { - LOG_E(HW,"Cannot lseek in iqfile: %s\n",strerror(errno)); + } else { + if (read(s->fd, s->ms_sample+1, s->ms_sample->nbBytes) != s->ms_sample->nbBytes) { + LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock ); exit(-1); } } } + iqrec_t *curHeader=(iqrec_t *)s->currentPtr; + AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" ); + // the current timestamp is the stored timestamp until we wrap on input + // USRP shifts 1 sample time to time + AssertFatal(s->wrap_count !=0 || abs(curHeader->ts-s->currentTs) < 5 ,""); + AssertFatal(nsamps*4==curHeader->nbBytes,""); + *ptimestamp = s->currentTs; + memcpy(buff[0], curHeader+1, nsamps*4); + s->curSamplesBlock++; + // Prepare for next read + s->currentTs+=nsamps; + + if (s->use_mmap) + s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes; + struct timespec req; - req.tv_sec = 0; - req.tv_nsec = (device->openair0_cfg[0].recplay_conf->u_sf_read_delay) * 1000; - nanosleep(&req, NULL); - + LOG_D(HW, "returning %d samples at ts %lu\n", nsamps, *ptimestamp); return nsamps; - - return samples_received; } - int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->openair0_cfg = openair0_cfg; device->trx_start_func = trx_iqplayer_start; @@ -312,5 +262,4 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { LOG_UI(HW,"iqplayer device initialized, replay %s for %i iterations",openair0_cfg->recplay_conf->u_sf_filename,openair0_cfg->recplay_conf->u_sf_loops); return 0; } - /*@}*/ diff --git a/targets/ARCH/rfsimulator/apply_channelmod.c b/targets/ARCH/rfsimulator/apply_channelmod.c index 3f4c0e1517..ab8ae77edd 100644 --- a/targets/ARCH/rfsimulator/apply_channelmod.c +++ b/targets/ARCH/rfsimulator/apply_channelmod.c @@ -65,17 +65,8 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si // Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...) const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0); // Energy in one sample to calibrate input noise - //Fixme: modified the N0W computation, not understand the origin value - const double KT=1.38e-23*290; //Boltzman*temperature - // sampling rate is linked to acquisition band (the input pass band filter) - const double noise_figure_watt = KT*channelDesc->sampling_rate; - // Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ? - // the parameter "-s" is declared as SNR, but the input power is not well defined - // −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise) - const double rxGain= 132.24 - channelmod_get_snr_dB(); - // sqrt(4*noise_figure_watt) is the thermal noise factor (volts) - // fixme: the last constant is pure trial results to make decent noise - const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10; + // the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1) + const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256; // Fixme: we don't fill the offset length samples at begining ? // anyway, in today code, channel_offset=0 const int dd = abs(channelDesc->channel_offset); diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 96d9541db9..f80f77f39c 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -69,7 +69,9 @@ extern RAN_CONTEXT_t RC; #define RFSIMU_SECTION "rfsimulator" #define RFSIMU_OPTIONS_PARAMNAME "options" -# define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\ + + +#define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\ " chanmod: enable channel modelisation\n"\ " saviq: enable saving written iqs to a file\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -78,21 +80,21 @@ extern RAN_CONTEXT_t RC; /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED #define RFSIMULATOR_PARAMS_DESC { \ - {"serveraddr", "\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ - {"serverport", "\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ - {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ - {"IQfile", "\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ - {"modelname", "\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ - {"ploss", "\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ - {"forgetfact", "\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ - {"offset", "\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ + {"serveraddr", "\n", simOpt, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ + {"serverport", "\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ + {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ + {"IQfile", "\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ + {"modelname", "\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ + {"ploss", "\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ + {"forgetfact", "\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ + {"offset", "\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ }; static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); static telnetshell_cmddef_t rfsimu_cmdarray[] = { - {"setmodel","",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, + {"setmodel"," ",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, {"","",NULL}, }; @@ -133,6 +135,7 @@ typedef struct { double chan_pathloss; double chan_forgetfact; int chan_offset; + float noise_power_dB; void *telnetcmd_qid; poll_telnetcmdq_func_t poll_telnetcmdq; } rfsimulator_state_t; @@ -182,15 +185,9 @@ static void allocCirBuf(rfsimulator_state_t *bridge, int sock) { tableNor(rand); init_done=true; } - - ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, - bridge->channelmod, - bridge->sample_rate, - bridge->tx_bw, - 30e-9, // TDL delay-spread parameter - bridge->chan_forgetfact, // forgetting_factor - bridge->chan_offset, // maybe used for TA - bridge->chan_pathloss); // path_loss in dB + char *modelname = (bridge->typeStamp == ENB_MAGICDL) ? "rfsimu_channel_ue0":"rfsimu_channel_enB0"; + ptr->channel_model=find_channel_desc_fromname(modelname); // path_loss in dB + AssertFatal((ptr->channel_model!= NULL),"Channel model %s not found, check config file\n",modelname); set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID); random_channel(ptr->channel_model,false); } @@ -299,7 +296,8 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { break; } else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) { init_channelmod(); - rfsimulator->channelmod=modelid_fromname(modelname); + load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->tx_bw); + rfsimulator->channelmod=true; } else { fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]); exit(-1); @@ -320,20 +318,27 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { char *modelname=NULL; - int s = sscanf(buff,"%ms\n",&modelname); + char *modeltype=NULL; + if (debug) + prnt("rfsimu_setchanmod_cmd buffer \"%s\"\n",buff); + int s = sscanf(buff,"%m[^ ] %ms\n",&modelname, &modeltype); - if (s == 1) { - int channelmod=modelid_fromname(modelname); + if (s == 2) { + int channelmod=modelid_fromstrtype(modeltype); if (channelmod<0) - prnt("ERROR: model %s unknown\n",modelname); + prnt("ERROR: model type %s unknown\n",modeltype); else { rfsimulator_state_t *t = (rfsimulator_state_t *)arg; - + int found=0; for (int i=0; ibuf[i]; + if ( b->channel_model==NULL) + continue; + if (b->channel_model->model_name==NULL) + continue; + if (b->conn_sock >= 0 && (strcmp(b->channel_model->model_name,modelname)==0)) { - if (b->conn_sock >= 0 ) { channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels, channelmod, t->sample_rate, @@ -341,21 +346,29 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, 30e-9, // TDL delay-spread parameter t->chan_forgetfact, // forgetting_factor t->chan_offset, // maybe used for TA - t->chan_pathloss); // path_loss in dB + t->chan_pathloss, + t->noise_power_dB + ); // path_loss in dB set_channeldesc_owner(newmodel, RFSIMU_MODULEID); + set_channeldesc_name(newmodel,modelname); random_channel(newmodel,false); channel_desc_t *oldmodel=b->channel_model; b->channel_model=newmodel; free_channel_desc_scm(oldmodel); - prnt("New model %s applied to channel connected to sock %d\n",modelname,i); + prnt("New model type %s applied to channel %s connected to sock %d\n",modeltype,modelname,i); + found=1; + break; } - } + } /* for */ + if (found==0) + prnt("Channel %s not found or not currently used\n",modelname); } } else { - prnt("ERROR: no model specified\n"); + prnt("ERROR: 2 parameters required: model name and model type (%i found)\n",s); } free(modelname); + free(modeltype); return CMDSTATUS_FOUND; } @@ -774,6 +787,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { // to change the log level, use this on command line // --log_config.hw_log_level debug rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); + // initialize channel simulation + rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels; + rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels; + rfsimulator->sample_rate=openair0_cfg->sample_rate; + rfsimulator->tx_bw=openair0_cfg->tx_bw; rfsimulator_readconfig(rfsimulator); pthread_mutex_init(&Sockmutex, NULL); LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side"); @@ -798,11 +816,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator->buf[i].conn_sock=-1; AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,""); - // initialize channel simulation - rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels; - rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels; - rfsimulator->sample_rate=openair0_cfg->sample_rate; - rfsimulator->tx_bw=openair0_cfg->tx_bw; + //randominit(0); set_taus_seed(0); /* look for telnet server, if it is loaded, add the channel modeling commands to it */ diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index dcea69b9dd..cf025680cd 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -186,14 +186,14 @@ int main(int argc, char *argv[]) { serviceSock=client_start(argv[2],atoi(argv[3])); } - uint64_t typeStamp=ENB_MAGICDL_FDD; + uint64_t typeStamp=ENB_MAGICDL; boolean_t raw=false; if ( argc == 5 ) { raw=true; if (strcmp(argv[4],"UL") == 0 ) - typeStamp=UE_MAGICDL_FDD; + typeStamp=UE_MAGICDL; } samplesBlockHeader_t header; @@ -201,7 +201,6 @@ int main(int argc, char *argv[]) { void *buff=malloc(bufSize); uint64_t timestamp=0; const int blockSize=1920; - // If fileSize is not multiple of blockSize*4 then discard remaining samples fileSize = (fileSize/(blockSize<<2))*(blockSize<<2); diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 4d57ab4e16..3e0d97f60a 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -42,6 +42,7 @@ # include "enb_app.h" # include "openair2/LAYER2/MAC/mac_proto.h" #include +#include extern RAN_CONTEXT_t RC; diff --git a/targets/COMMON/create_tasks_mbms.c b/targets/COMMON/create_tasks_mbms.c index 5f81592b96..579e851ea7 100644 --- a/targets/COMMON/create_tasks_mbms.c +++ b/targets/COMMON/create_tasks_mbms.c @@ -47,6 +47,7 @@ # include "mce_app.h" # include "mme_app.h" +#include //extern RAN_CONTEXT_t RC; int create_tasks_mbms(uint32_t enb_nb) { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 42b87d5672..20423b50b9 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -13,7 +13,7 @@ gNBs = // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; - plmn_list = ({mcc = 222; mnc = 93; mnc_length = 2;}); + plmn_list = ({mcc = 208; mnc = 92; mnc_length = 2;}); tr_s_preference = "local_mac" @@ -21,6 +21,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; pdcch_ConfigSIB1 = ( { @@ -51,7 +52,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6368; + initialDLBWPlocationAndBandwidth = 12952; # 6366 12925 12956 28875 # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -64,28 +65,23 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_0 = 53; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; initialDLBWPmappingType_1 = 0; - #this is SS=2,L=10 - initialDLBWPstartSymbolAndLength_1 = 81; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; initialDLBWPk0_2 = 0; initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 95; + initialDLBWPstartSymbolAndLength_2 = 54; initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=2,L=7 - initialDLBWPstartSymbolAndLength_3 = 86; - - initialDLBWPk0_4 = 0; - initialDLBWPmappingType_4 = 0; - #this is SS=2,L=5 - initialDLBWPstartSymbolAndLength_4 = 58; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon #frequencyInfoUL @@ -99,7 +95,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6368; + initialULBWPlocationAndBandwidth = 12952; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -111,7 +107,7 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 0; zeroCorrelationZoneConfig = 13; - preambleReceivedTargetPower = -100; + preambleReceivedTargetPower = -96; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -196,7 +192,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -255,10 +251,11 @@ MACRLCs = ( ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 96df4a971f..c4d9de3347 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -13,7 +13,7 @@ gNBs = // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; - plmn_list = ({mcc = 222; mnc = 93; mnc_length = 2;}); + plmn_list = ({mcc = 208; mnc = 92; mnc_length = 2;}); tr_s_preference = "local_mac" @@ -21,6 +21,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; pdcch_ConfigSIB1 = ( { @@ -50,8 +51,8 @@ gNBs = dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6368; + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 12952; # 6366 12925 12956 28875 12952 # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -64,13 +65,13 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_0 = 53; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; initialDLBWPmappingType_1 = 0; - #this is SS=2,L=10 - initialDLBWPstartSymbolAndLength_1 = 81; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; initialDLBWPk0_2 = 0; initialDLBWPmappingType_2 = 0; @@ -94,7 +95,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6368; + initialULBWPlocationAndBandwidth = 12952; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -106,7 +107,7 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 0; zeroCorrelationZoneConfig = 13; - preambleReceivedTargetPower = -100; + preambleReceivedTargetPower = -96; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -191,7 +192,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -250,10 +251,11 @@ MACRLCs = ( ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 368fd78f9e..4682c5989e 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -869,7 +869,6 @@ static void *ru_thread_asynch_rxtx( void *param ) { LOG_I(PHY, "devices ok (ru_thread_asynch_rxtx)\n"); while (!oai_exit) { - if (oai_exit) break; if (ru->state != RU_RUN) { subframe=0; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 2e6f148e00..b558c14380 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -35,6 +35,7 @@ #include #include "rt_wrapper.h" +#include #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all @@ -56,6 +57,8 @@ //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all +#include + #include "PHY/phy_vars.h" #include "SCHED/sched_common_vars.h" #include "LAYER2/MAC/mac_vars.h" @@ -100,6 +103,8 @@ pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex +msc_interface_t msc_interface; + uint16_t sf_ahead=4; @@ -170,7 +175,6 @@ extern void init_eNB_afterRU(void); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; THREAD_STRUCT thread_struct; /* struct for ethernet specific parameters given in eNB conf file */ @@ -727,7 +731,7 @@ int main ( int argc, char **argv ) fflush(stderr); // end of CI modifications //getchar(); - if(IS_SOFTMODEM_DOFORMS) + if(IS_SOFTMODEM_DOSCOPE) load_softscope("enb",NULL); itti_wait_tasks_end(); oai_exit=1; @@ -735,7 +739,7 @@ int main ( int argc, char **argv ) // stop threads if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) { - if(IS_SOFTMODEM_DOFORMS) + if(IS_SOFTMODEM_DOSCOPE) end_forms(); LOG_I(ENB_APP,"stopping MODEM threads\n"); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 407756e20f..82140ea5aa 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -95,6 +95,7 @@ extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); +int tx_req_num_elems; extern uint16_t sf_ahead; //extern int tx_req_UE_MAC1(); @@ -181,9 +182,8 @@ PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t abstraction_flag) { - PHY_VARS_UE *ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE)); - memset(ue,0,sizeof(PHY_VARS_UE)); - + PHY_VARS_UE *ue = (PHY_VARS_UE *)calloc(1,sizeof(PHY_VARS_UE)); + AssertFatal(ue,""); if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS)); } diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 9bf179efb9..3714b0dc6f 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -86,6 +86,7 @@ #include "lte-softmodem.h" +msc_interface_t msc_interface; /* temporary compilation wokaround (UE/eNB split */ uint16_t sf_ahead; @@ -168,7 +169,6 @@ extern void get_uethreads_params(void); int transmission_mode=1; -int usrp_tx_thread = 0; char *usrp_args=NULL; @@ -758,7 +758,7 @@ int main( int argc, char **argv ) { PHY_vars_UE_g[0][0]->no_timing_correction = 1; } - if(IS_SOFTMODEM_DOFORMS) + if(IS_SOFTMODEM_DOSCOPE) load_softscope("ue",NULL); config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); @@ -783,7 +783,7 @@ int main( int argc, char **argv ) { printf("oai_exit=%d\n",oai_exit); // stop threads - if(IS_SOFTMODEM_DOFORMS) + if(IS_SOFTMODEM_DOSCOPE) end_forms(); printf("stopping MODEM threads\n"); diff --git a/targets/RT/USER/rfsim.c b/targets/RT/USER/rfsim.c index eb380b9518..2bd95507c3 100644 --- a/targets/RT/USER/rfsim.c +++ b/targets/RT/USER/rfsim.c @@ -361,6 +361,7 @@ void init_ocm(void) { DS_TDL, 0.0, 0, + 0, 0); random_channel(sim.RU2UE[ru_id][UE_id][CC_id],0); LOG_D(OCM,"[SIM] Initializing channel (%s) from UE %d to ru %d\n", "AWGN", UE_id, ru_id); @@ -374,6 +375,7 @@ void init_ocm(void) { DS_TDL, 0.0, 0, + 0, 0); random_channel(sim.UE2RU[UE_id][ru_id][CC_id],0); // to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed. diff --git a/targets/RT/USER/rt_wrapper.c b/targets/RT/USER/rt_wrapper.c index 5bdbbb36e3..b051868825 100644 --- a/targets/RT/USER/rt_wrapper.c +++ b/targets/RT/USER/rt_wrapper.c @@ -44,6 +44,7 @@ #include #include "rt_wrapper.h" #include +#include #include "openair1/PHY/defs_common.h"