diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 9570610cd8..b8dc8b32fb 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -579,9 +579,17 @@ class Containerize(): lUserName = self.eNB2UserName lPassWord = self.eNB2Password lSsh.open(lIpAddr, lUserName, lPassWord) - lSsh.command('docker save ' + self.imageToCopy + ':' + imageTag + ' | gzip > ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60) - lSsh.copyin(lIpAddr, lUserName, lPassWord, '~/' + self.imageToCopy + '-' + imageTag + '.tar.gz', '.') + lSsh.command('docker save ' + self.imageToCopy + ':' + imageTag + ' | gzip --fast > ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60) + ret = lSsh.copyin(lIpAddr, lUserName, lPassWord, '~/' + self.imageToCopy + '-' + imageTag + '.tar.gz', '.') + if ret != 0: + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) + self.exitStatus = 1 + return False lSsh.command('rm ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60) + if lSsh.getBefore().count('cannot remove'): + HTML.CreateHtmlTestRow('file not created by docker save', 'KO', CONST.ALL_PROCESSES_OK) + self.exitStatus = 1 + return False lSsh.close() # Going to the Test Server @@ -599,15 +607,26 @@ class Containerize(): lPassWord = self.eNB2Password lSsh.open(lIpAddr, lUserName, lPassWord) lSsh.copyout(lIpAddr, lUserName, lPassWord, './' + self.imageToCopy + '-' + imageTag + '.tar.gz', '~') + # copyout has no return code and will quit if something fails lSsh.command('docker rmi ' + self.imageToCopy + ':' + imageTag, '\$', 10) lSsh.command('docker load < ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60) + if lSsh.getBefore().count('o such file') or lSsh.getBefore().count('invalid tar header'): + logging.debug(lSsh.getBefore()) + HTML.CreateHtmlTestRow('problem during docker load', 'KO', CONST.ALL_PROCESSES_OK) + self.exitStatus = 1 + return False lSsh.command('rm ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60) + if lSsh.getBefore().count('cannot remove'): + HTML.CreateHtmlTestRow('file not copied during scp?', 'KO', CONST.ALL_PROCESSES_OK) + self.exitStatus = 1 + return False lSsh.close() if os.path.isfile('./' + self.imageToCopy + '-' + imageTag + '.tar.gz'): os.remove('./' + self.imageToCopy + '-' + imageTag + '.tar.gz') HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + return True def DeployObject(self, HTML, EPC): if self.eNB_serverId[self.eNB_instance] == '0': @@ -683,6 +702,9 @@ class Containerize(): logging.debug(' -- ' + str(unhealthyNb) + ' unhealthy container(s)') logging.debug(' -- ' + str(startingNb) + ' still starting container(s)') + self.testCase_id = HTML.testCase_id + self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log' + status = False if healthyNb == 1: cnt = 0 @@ -697,11 +719,12 @@ class Containerize(): status = True logging.info('\u001B[1m Deploying OAI object Pass\u001B[0m') time.sleep(10) + else: + # containers are unhealthy, so we won't start. However, logs are stored at the end + # in UndeployObject so we here store the logs of the unhealthy container to report it + mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30) mySSH.close() - self.testCase_id = HTML.testCase_id - self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log' - if status: HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) else: diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 9113d29ac9..a636bf9433 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -253,7 +253,7 @@ class EPCManagement(): logging.debug('Starting OAI CN5G') mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5) mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5) - mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5) + mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5) mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60) if re.search('start-mini-as-ue', self.cfgDeploy): dFile = 'docker-compose-mini-nrf-asue.yaml' @@ -537,7 +537,7 @@ class EPCManagement(): mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5) logging.debug('Terminating OAI CN5G') - mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5) + mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5) mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60) mySSH.command('docker volume prune --force || true', '\$', 60) time.sleep(2) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index baed6a6011..8a4b59ede6 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -921,7 +921,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re elif action == 'Build_Proxy': CONTAINERS.BuildProxy(HTML) elif action == 'Copy_Image_to_Test': - CONTAINERS.Copy_Image_to_Test_Server(HTML) + success = CONTAINERS.Copy_Image_to_Test_Server(HTML) + if not success: + RAN.prematureExit = True elif action == 'Deploy_Object': CONTAINERS.DeployObject(HTML, EPC) if CONTAINERS.exitStatus==1: diff --git a/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml b/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml index a28b640e1a..7edcad25a4 100644 --- a/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml @@ -2,7 +2,7 @@ version: '3.8' services: oai-nrf: container_name: "l2sim-oai-nrf" - image: oai-nrf:latest + image: oai-nrf:august-dev environment: - NRF_INTERFACE_NAME_FOR_SBI=eth0 - NRF_INTERFACE_PORT_FOR_SBI=80 @@ -42,7 +42,7 @@ services: ipv4_address: 192.168.71.131 oai-amf: container_name: "l2sim-oai-amf" - image: oai-amf:latest + image: oai-amf:august-dev environment: - TZ=Europe/paris - INSTANCE=0 @@ -110,7 +110,7 @@ services: ipv4_address: 192.168.71.132 oai-smf: container_name: "l2sim-oai-smf" - image: oai-smf:latest + image: oai-smf:august-dev environment: - TZ=Europe/Paris - INSTANCE=0 @@ -156,7 +156,7 @@ services: ipv4_address: 192.168.71.133 oai-spgwu: container_name: "l2sim-oai-spgwu" - image: oai-spgwu-tiny:latest + image: oai-spgwu-tiny:august-dev environment: - TZ=Europe/Paris - PID_DIRECTORY=/var/run diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml index 696d8c6698..88188da53e 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml @@ -2,7 +2,7 @@ version: '3.8' services: oai-nrf: container_name: "rfsim5g-oai-nrf" - image: oai-nrf:latest + image: oai-nrf:august-dev environment: - NRF_INTERFACE_NAME_FOR_SBI=eth0 - NRF_INTERFACE_PORT_FOR_SBI=80 @@ -42,7 +42,7 @@ services: ipv4_address: 192.168.71.131 oai-amf: container_name: "rfsim5g-oai-amf" - image: oai-amf:latest + image: oai-amf:august-dev environment: - TZ=Europe/paris - INSTANCE=0 @@ -110,7 +110,7 @@ services: ipv4_address: 192.168.71.132 oai-smf: container_name: "rfsim5g-oai-smf" - image: oai-smf:latest + image: oai-smf:august-dev environment: - TZ=Europe/Paris - INSTANCE=0 @@ -156,7 +156,7 @@ services: ipv4_address: 192.168.71.133 oai-spgwu: container_name: "rfsim5g-oai-spgwu" - image: oai-spgwu-tiny:latest + image: oai-spgwu-tiny:august-dev environment: - TZ=Europe/Paris - PID_DIRECTORY=/var/run diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index d35f90fcce..608ace0486 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -237,8 +237,9 @@ compilations() { echo_error "$2 compilation failed" exit 1 fi - if [ -s $3 ] ; then - cp $3 $4 + if [ -s "$3" ] ; then + rm -f "$4" + ln -s "$PWD/$3" "$4" echo_success "$2 compiled" check_warnings "$dlog/$2.$REL.txt" else diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 index 5296ac2172..23afb5f38d 100644 --- a/docker/Dockerfile.eNB.rhel8.2 +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -43,6 +43,7 @@ RUN yum update -y && \ tzdata \ procps-ng \ atlas \ + gdb \ python3 \ python3-pip \ net-tools \ diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 index f95a03398a..2b50dcadfb 100644 --- a/docker/Dockerfile.eNB.ubuntu18 +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -53,6 +53,7 @@ RUN apt-get update && \ iputils-ping \ iproute2 \ iperf \ + gdb \ python \ python3 \ python3-six \ diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 index 9ec7ee7556..f782384f58 100644 --- a/docker/Dockerfile.gNB.rhel8.2 +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -46,6 +46,7 @@ RUN yum repolist --disablerepo=* && \ lksctp-tools \ nettle \ tzdata \ + gdb \ python3 \ python3-pip \ net-tools \ diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 index 6a98c8d3ce..11669c2af4 100644 --- a/docker/Dockerfile.gNB.ubuntu18 +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -52,6 +52,7 @@ RUN apt-get update && \ net-tools \ iproute2 \ iputils-ping \ + gdb \ python \ python3 \ python3-six \ diff --git a/docker/Dockerfile.lteRU.rhel8.2 b/docker/Dockerfile.lteRU.rhel8.2 index b41aee36dc..f20910ff51 100644 --- a/docker/Dockerfile.lteRU.rhel8.2 +++ b/docker/Dockerfile.lteRU.rhel8.2 @@ -41,6 +41,7 @@ RUN yum update -y && \ tzdata \ procps-ng \ atlas \ + gdb \ python3 \ python3-pip \ net-tools \ diff --git a/docker/Dockerfile.lteRU.ubuntu18 b/docker/Dockerfile.lteRU.ubuntu18 index 1810afb621..157a5a615a 100644 --- a/docker/Dockerfile.lteRU.ubuntu18 +++ b/docker/Dockerfile.lteRU.ubuntu18 @@ -47,6 +47,7 @@ RUN apt-get update && \ libatlas3-base \ libconfig9 \ net-tools \ + gdb \ python \ python3 \ python3-six \ diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index ab7d224939..303394ea27 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -44,6 +44,7 @@ RUN yum update -y && \ nettle \ tzdata \ atlas \ + gdb \ python3 \ python3-pip \ iproute \ diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 index dfb28cfd1d..3ee93ed5d2 100644 --- a/docker/Dockerfile.nrUE.rhel8.2 +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -46,6 +46,7 @@ RUN yum update -y && \ iputils \ iproute \ atlas \ + gdb \ python3 \ python3-pip \ libXpm \ diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 index 9f68b947cd..0997783b8b 100644 --- a/docker/Dockerfile.nrUE.ubuntu18 +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -50,6 +50,7 @@ RUN apt-get update && \ libconfig9 \ openssl \ net-tools \ + gdb \ python \ python3 \ python3-six \ diff --git a/docker/scripts/enb_entrypoint.sh b/docker/scripts/enb_entrypoint.sh index 825dfd73c1..2d49a0ed20 100755 --- a/docker/scripts/enb_entrypoint.sh +++ b/docker/scripts/enb_entrypoint.sh @@ -51,9 +51,15 @@ for c in ${CONFIG_FILES}; do # render template and inline replace config file sed -i "${EXPRESSIONS}" ${c} + + echo "==================================" + echo "== Configuration file: ${c}" + cat ${c} done # Load the USRP binaries +echo "==================================" +echo "== Load USRP binaries" if [[ -v USE_B2XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then @@ -62,6 +68,9 @@ elif [[ -v USE_N3XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t n3xx fi +# enable printing of stack traces on assert +export gdbStacks=1 + echo "==================================" echo "== Starting eNB soft modem" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index 6deff8da10..4e8983599e 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -51,9 +51,15 @@ for c in ${CONFIG_FILES}; do # render template and inline replace config file sed -i "${EXPRESSIONS}" ${c} + + echo "==================================" + echo "== Configuration file: ${c}" + cat ${c} done # Load the USRP binaries +echo "==================================" +echo "== Load USRP binaries" if [[ -v USE_B2XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then @@ -62,6 +68,9 @@ elif [[ -v USE_N3XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t n3xx fi +# enable printing of stack traces on assert +export gdbStacks=1 + echo "==================================" echo "== Starting gNB soft modem" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then diff --git a/docker/scripts/lte_ru_entrypoint.sh b/docker/scripts/lte_ru_entrypoint.sh index 297e437ac0..746efb30b3 100755 --- a/docker/scripts/lte_ru_entrypoint.sh +++ b/docker/scripts/lte_ru_entrypoint.sh @@ -31,9 +31,15 @@ for c in ${CONFIG_FILES}; do # render template and inline replace config file sed -i "${EXPRESSIONS}" ${c} + + echo "==================================" + echo "== Configuration file: ${c}" + cat ${c} done # Load the USRP binaries +echo "==================================" +echo "== Load USRP binaries" if [[ -v USE_B2XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then @@ -42,6 +48,9 @@ elif [[ -v USE_N3XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t n3xx fi +# enable printing of stack traces on assert +export gdbStacks=1 + echo "==================================" echo "== Starting eNB soft modem" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then diff --git a/docker/scripts/lte_ue_entrypoint.sh b/docker/scripts/lte_ue_entrypoint.sh index 82e96dd07f..2bdcb873c9 100755 --- a/docker/scripts/lte_ue_entrypoint.sh +++ b/docker/scripts/lte_ue_entrypoint.sh @@ -30,6 +30,10 @@ for c in ${CONFIG_FILES}; do # render template and inline replace config file sed -i "${EXPRESSIONS}" ${c} + + echo "==================================" + echo "== Configuration file: ${c}" + cat ${c} done #now generate USIM files @@ -38,6 +42,8 @@ cd $PREFIX $PREFIX/bin/conf2uedata -c $PREFIX/etc/ue_usim.conf -o $PREFIX # Load the USRP binaries +echo "==================================" +echo "== Load USRP binaries" if [[ -v USE_B2XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then @@ -57,6 +63,9 @@ if [[ -v USE_NFAPI ]]; then new_args+=("$PREFIX/etc/ue.conf") fi +# enable printing of stack traces on assert +export gdbStacks=1 + echo "==================================" echo "== Starting LTE UE soft modem" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then diff --git a/docker/scripts/nr_ue_entrypoint.sh b/docker/scripts/nr_ue_entrypoint.sh index 38b080a41b..616d71b555 100755 --- a/docker/scripts/nr_ue_entrypoint.sh +++ b/docker/scripts/nr_ue_entrypoint.sh @@ -40,9 +40,15 @@ for c in ${CONFIG_FILES}; do # render template and inline replace config file sed -i "${EXPRESSIONS}" ${c} + + echo "==================================" + echo "== Configuration file: ${c}" + cat ${c} done # Load the USRP binaries +echo "==================================" +echo "== Load USRP binaries" if [[ -v USE_B2XX ]]; then $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then @@ -58,6 +64,9 @@ while [[ $# -gt 0 ]]; do shift done +# enable printing of stack traces on assert +export gdbStacks=1 + echo "==================================" echo "== Starting NR UE soft modem" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 5f64d0f006..75a7ac67b1 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1290,42 +1290,33 @@ typedef struct } nfapi_nr_pucch_pdu_t; -//for srs_pdu: - -typedef struct -{ - uint16_t rnti;//UE RNTI - uint32_t handle;//An opaque handling returned in the SRS.indication - //BWP - uint16_t bwp_size; - uint16_t bwp_start; - uint8_t subcarrier_spacing; - uint8_t cyclic_prefix; - - uint8_t num_ant_ports; - uint8_t num_symbols; - uint8_t num_repetitions; - uint8_t time_start_position;//Starting position in the time domain l0; Note: the MAC undertakes the translation from startPosition to 𝑙0 - uint8_t config_index; - uint16_t sequence_id; - uint8_t bandwidth_index; - uint8_t comb_size; - uint8_t comb_offset;//Transmission comb offset 𝑘 ̄ TC [TS38.211, Sec 6.4.1.4.3] Value: 0 → 1 (combSize = 0) Value: 0 → 3 (combSize = 1) - uint8_t cyclic_shift; - uint8_t frequency_position; - uint16_t frequency_shift; - uint8_t frequency_hopping; - uint8_t group_or_sequence_hopping;//Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRS-Resource - uint8_t resource_type;//Type of SRS resource allocation - uint16_t t_srs;//SRS-Periodicity in slots [TS38.211 Sec 6.4.1.4.4] Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 - uint16_t t_offset;//Slot offset value [TS38.211, Sec 6.4.1.4.3] Value:0->2559 - +typedef struct { + uint16_t rnti; // UE RNTI, Value: 1->65535 + uint32_t handle; // An opaque handling returned in the SRS.indication + uint16_t bwp_size; // Bandwidth part size [3GPP TS 38.213, sec 12]. Number of contiguous PRBs allocated to the BWP, Value: 1->275 + uint16_t bwp_start; // Bandwidth part start RB index from reference CRB [3GPP TS 38.213, sec 12], Value: 0->274 + uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4 + uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended + uint8_t num_ant_ports; // Number of antenna ports N_SRS_ap [3GPP TS 38.211, Sec 6.4.1.4.1], Value: 0 = 1 port, 1 = 2 ports, 2 = 4 ports + uint8_t num_symbols; // Number of symbols N_SRS_symb [3GPP TS 38.211, Sec 6.4.1.4.1], Value: 0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols + uint8_t num_repetitions; // Repetition factor R [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 = 1, 1 = 2, 2 = 4 + uint8_t time_start_position; // Starting position in the time domain l_0 [3GPP TS 38.211, Sec 6.4.1.4.1], Note: the MAC undertakes the translation from startPosition to l_0, Value: 0 --> 13 + uint8_t config_index; // SRS bandwidth config index C_SRS [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 63 + uint16_t sequence_id; // SRS sequence ID n_SRS_ID [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 --> 1023 + uint8_t bandwidth_index; // SRS bandwidth index B_SRS [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 3 + uint8_t comb_size; // Transmission comb size K_TC [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 = comb size 2, 1 = comb size 4, 2 = comb size 8 (Rel16) + uint8_t comb_offset; // Transmission comb offset K'_TC[3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 1 (combSize = 0), Value: 0 --> 3 (combSize = 1), Value: 0 --> 7 (combSize = 2) + uint8_t cyclic_shift; // Cyclic shift n_CS_SRS [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 --> 7 (combSize = 0), Value: 0 --> 11 (combSize = 1), Value: 0 --> 5 (combSize = 2) + uint8_t frequency_position; // Frequency domain position n_RRC [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 67 + uint16_t frequency_shift; // Frequency domain shift n_shift [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 268 + uint8_t frequency_hopping; // Frequency hopping b_hop [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 3 + uint8_t group_or_sequence_hopping; // Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRSResource IE), Value: 0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping + uint8_t resource_type; // Type of SRS resource allocation [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0: aperiodic, 1: semi-persistent, 2: periodic + uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 + uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559 nfapi_nr_ul_beamforming_t beamforming; - } nfapi_nr_srs_pdu_t; -// - typedef enum { NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE = 0, NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE = 1, diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 6b984f53db..7d385d6ce7 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -613,6 +613,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, for (int id=0; idnr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); + gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*)); + for(int ap=0; apnr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + } } generate_ul_reference_signal_sequences(SHRT_MAX); @@ -767,6 +771,10 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(gNB->nr_csi_info); for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) { + for(int i=0; inr_srs_info[id]->srs_generated_signal[i]); + } + free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal); free_and_zero(gNB->nr_srs_info[id]); } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 2dc368fdb0..6093116ec9 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -28,6 +28,7 @@ #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" @@ -964,153 +965,238 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, const int slot, const nfapi_nr_srs_pdu_t *srs_pdu, const nr_srs_info_t *nr_srs_info, - const int32_t *srs_generated_signal, + const int32_t **srs_generated_signal, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size], - int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_ls_estimated_channel[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], uint32_t *signal_power, uint32_t *noise_power_per_rb, uint32_t *noise_power, int8_t *snr_per_rb, int8_t *snr) { - if(nr_srs_info->sc_list_length == 0) { - LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); - return -1; - } +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); +#endif const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; - int16_t ch_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; - int16_t ch_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; - int16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; - int16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + const uint8_t N_ap = 1<num_ant_ports; + const uint8_t K_TC = 2<comb_size; + const uint16_t m_SRS_b = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; + uint8_t fd_cdm = N_ap; + if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) { + fd_cdm = 2; + } + + int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + int16_t noise_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t ls_estimated[2]; - uint8_t mem_offset = 0; - while(((long)&srs_estimated_channel_freq[0][nr_srs_info->sc_list[0] + mem_offset] & 0xF) != 0) { - mem_offset++; - } - int32_t srs_est[frame_parms->ofdm_symbol_size*(1<num_symbols) + mem_offset] __attribute__ ((aligned(32))); + uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) >> 2; // >> 2 <=> /sizeof(int32_t) + + // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} + // The End of OFDM symbol corresponds to the position of last 16384 in the filter + // The multadd_real_vector_complex_scalar applies the remaining 8 zeros of filter, therefore, to avoid a buffer overflow, + // we added 8 in the array size + int32_t srs_est[frame_parms->ofdm_symbol_size*(1<num_symbols) + mem_offset + 8] __attribute__ ((aligned(32))); for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - memset(srs_ls_estimated_channel[ant], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); - memset(srs_est, 0, (frame_parms->ofdm_symbol_size*(1<num_symbols) + mem_offset)*sizeof(int32_t)); + for (int p_index = 0; p_index < N_ap; p_index++) { - int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[nr_srs_info->sc_list[0] + mem_offset]; + memset(srs_ls_estimated_channel[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); + memset(srs_est, 0, (frame_parms->ofdm_symbol_size*(1<num_symbols) + mem_offset)*sizeof(int32_t)); - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant); +#endif - int16_t generated_real = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].r; - int16_t generated_imag = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].i; + uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } - int16_t received_real = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].r; - int16_t received_imag = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].i; + int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier + mem_offset]; - // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. - // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. - ls_estimated[0] = (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits); - ls_estimated[1] = (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits); - srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000); + for (int k = 0; k < M_sc_b_SRS; k++) { - const uint16_t sc_idx_offset = nr_srs_info->sc_list[sc_idx] + mem_offset; + if (k%fd_cdm==0) { - // Channel interpolation - if(srs_pdu->comb_size == 0) { - if(sc_idx == 0) { // First subcarrier case - // filt8_start is {12288,8192,4096,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8); - } else if(nr_srs_info->sc_list[sc_idx] < nr_srs_info->sc_list[sc_idx - 1]) { // Start of OFDM symbol case - // filt8_start is {12288,8192,4096,0,0,0,0,0} - srs_estimated_channel16 = (int16_t *)&srs_est[nr_srs_info->sc_list[sc_idx]]; - short *filter = mem_offset==0 ? filt8_start:filt8_start_shift2; - multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8); - } else if((sc_idx < (nr_srs_info->sc_list_length - 1) && nr_srs_info->sc_list[sc_idx + 1] < nr_srs_info->sc_list[sc_idx]) - || (sc_idx == (nr_srs_info->sc_list_length - 1))) { // End of OFDM symbol or last subcarrier cases - // filt8_end is {4096,8192,12288,16384,0,0,0,0} - short *filter = mem_offset==0 || sc_idx == (nr_srs_info->sc_list_length - 1) ? filt8_end:filt8_end_shift2; - multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8); - } else if(sc_idx%2 == 1) { // 1st middle case - // filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0} - multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8); - } else if(sc_idx%2 == 0) { // 2nd middle case - // filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0} - multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8); - srs_estimated_channel16 = (int16_t *)&srs_est[sc_idx_offset]; + ls_estimated[0] = 0; + ls_estimated[1] = 0; + uint16_t subcarrier_cdm = subcarrier; + + for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) { + + int16_t generated_real = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].r; + int16_t generated_imag = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].i; + + int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r; + int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i; + + // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. + // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. + ls_estimated[0] += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits); + ls_estimated[1] += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits); + + // Subcarrier increment + subcarrier_cdm += K_TC; + if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) { + subcarrier_cdm=subcarrier_cdm-frame_parms->ofdm_symbol_size; + } + } } - } else { - if(sc_idx == 0) { // First subcarrier case - // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); - } else if(nr_srs_info->sc_list[sc_idx] < nr_srs_info->sc_list[sc_idx - 1]) { // Start of OFDM symbol case - srs_estimated_channel16 = (int16_t *)&srs_est[sc_idx_offset]; - // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); - } else if((sc_idx < (nr_srs_info->sc_list_length - 1) && nr_srs_info->sc_list[sc_idx + 1] < nr_srs_info->sc_list[sc_idx]) - || (sc_idx == (nr_srs_info->sc_list_length - 1))) { // End of OFDM symbol or last subcarrier cases - // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16); - } else { // Middle case - // filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16); - srs_estimated_channel16 = (int16_t *)&srs_est[sc_idx_offset]; + + srs_ls_estimated_channel[ant][p_index][subcarrier] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000); + +#ifdef SRS_DEBUG + int subcarrier_log = subcarrier-subcarrier_offset; + if(subcarrier_log < 0) { + subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + } + if(subcarrier_log%12 == 0) { + LOG_I(NR_PHY,"------------------------------------ %d ------------------------------------\n", subcarrier_log/12); + LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); + } + LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + subcarrier_log, + (int16_t)(srs_generated_signal[p_index][subcarrier] & 0xFFFF), (int16_t)((srs_generated_signal[p_index][subcarrier] >> 16) & 0xFFFF), + (int16_t)(srs_received_signal[ant][subcarrier] & 0xFFFF), (int16_t)((srs_received_signal[ant][subcarrier] >> 16) & 0xFFFF), + ls_estimated[0], ls_estimated[1]); +#endif + + const uint16_t sc_offset = subcarrier + mem_offset; + + // Channel interpolation + if(srs_pdu->comb_size == 0) { + if(k == 0) { // First subcarrier case + // filt8_start is {12288,8192,4096,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8); + } else if(subcarrier < K_TC) { // Start of OFDM symbol case + // filt8_start is {12288,8192,4096,0,0,0,0,0} + srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier]; + short *filter = mem_offset==0 ? filt8_start:filt8_start_shift2; + multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8); + } else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases + // filt8_end is {4096,8192,12288,16384,0,0,0,0} + short *filter = mem_offset==0 || k == (M_sc_b_SRS-1) ? filt8_end:filt8_end_shift2; + multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8); + } else if(k%2 == 1) { // 1st middle case + // filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0} + multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8); + } else if(k%2 == 0) { // 2nd middle case + // filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0} + multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8); + srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset]; + } + } else { + if(k == 0) { // First subcarrier case + // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); + } else if(subcarrier < K_TC) { // Start of OFDM symbol case + srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset]; + // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); + } else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases + // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16); + } else { // Middle case + // filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16); + srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset]; + } + } + + // Subcarrier increment + subcarrier += K_TC; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } + + } // for (int k = 0; k < M_sc_b_SRS; k++) + + memcpy(&srs_estimated_channel_freq[ant][p_index][0], + &srs_est[mem_offset], + (frame_parms->ofdm_symbol_size*(1<num_symbols))*sizeof(int32_t)); + + // Compute noise + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } + uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS; + for (int k = 0; k < M_sc_b_SRS; k++) { + ch_real[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].r; + ch_imag[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].i; + noise_real[base_idx+k] = abs(((c16_t*)srs_ls_estimated_channel[ant][p_index])[subcarrier].r - ch_real[base_idx+k]); + noise_imag[base_idx+k] = abs(((c16_t*)srs_ls_estimated_channel[ant][p_index])[subcarrier].i - ch_imag[base_idx+k]); + subcarrier += K_TC; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; } } #ifdef SRS_DEBUG - uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; - int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; } - if(sc_idx == 0) { - LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant); + + for (int k = 0; k < K_TC*M_sc_b_SRS; k++) { + + int subcarrier_log = subcarrier-subcarrier_offset; + if(subcarrier_log < 0) { + subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + } + + if(subcarrier_log%12 == 0) { + LOG_I(NR_PHY,"------------------------------------- %d -------------------------------------\n", subcarrier_log/12); + LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n"); + } + + LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + subcarrier_log, + (int16_t)(srs_ls_estimated_channel[ant][p_index][subcarrier]&0xFFFF), + (int16_t)((srs_ls_estimated_channel[ant][p_index][subcarrier]>>16)&0xFFFF), + (int16_t)(srs_estimated_channel_freq[ant][p_index][subcarrier]&0xFFFF), + (int16_t)((srs_estimated_channel_freq[ant][p_index][subcarrier]>>16)&0xFFFF), + noise_real[base_idx+(k/K_TC)], noise_imag[base_idx+(k/K_TC)]); + + // Subcarrier increment + subcarrier++; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", subcarrier_log/12); - LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); - } - LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", - subcarrier_log, - generated_real, generated_imag, - received_real, received_imag, - ls_estimated[0], ls_estimated[1]); #endif - } - memcpy(&srs_estimated_channel_freq[ant][0], - &srs_est[mem_offset], - (frame_parms->ofdm_symbol_size*(1<num_symbols))*sizeof(int32_t)); + // Convert to time domain + freq2time(gNB->frame_parms.ofdm_symbol_size, + (int16_t*) srs_estimated_channel_freq[ant][p_index], + (int16_t*) srs_estimated_channel_time[ant][p_index]); - // Compute noise - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - ch_real[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].r; - ch_imag[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].i; - noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].r - ch_real[ant*nr_srs_info->sc_list_length + sc_idx]); - noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].i - ch_imag[ant*nr_srs_info->sc_list_length + sc_idx]); - } + memcpy(&srs_estimated_channel_time_shifted[ant][p_index][0], + &srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1], + (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - // Convert to time domain - freq2time(gNB->frame_parms.ofdm_symbol_size, - (int16_t*) srs_estimated_channel_freq[ant], - (int16_t*) srs_estimated_channel_time[ant]); + memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1], + &srs_estimated_channel_time[ant][p_index][0], + (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - memcpy(&srs_estimated_channel_time_shifted[ant][0], - &srs_estimated_channel_time[ant][gNB->frame_parms.ofdm_symbol_size>>1], - (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - - memcpy(&srs_estimated_channel_time_shifted[ant][gNB->frame_parms.ofdm_symbol_size>>1], - &srs_estimated_channel_time[ant][0], - (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - } + } // for (int p_index = 0; p_index < N_ap; p_index++) + } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) // Compute signal power - *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length) - + calc_power(ch_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) + + calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); #ifdef SRS_DEBUG LOG_I(NR_PHY,"signal_power = %u\n", *signal_power); @@ -1127,84 +1213,48 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x) const int32_t factor_dB = dB_fixed(1<first_carrier_offset + srs_pdu->bwp_start*12; const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3; - const uint8_t n_noise_est = frame_parms->nb_antennas_rx * srs_symbols_per_rb; - uint8_t count_estimates = 0; + const uint8_t n_noise_est = frame_parms->nb_antennas_rx*N_ap*srs_symbols_per_rb; uint64_t sum_re = 0; uint64_t sum_re2 = 0; uint64_t sum_im = 0; uint64_t sum_im2 = 0; - for (int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { + for (int rb = 0; rb < m_SRS_b; rb++) { - int subcarrier0 = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier0 < 0) { - subcarrier0 = subcarrier0 + frame_parms->ofdm_symbol_size; - } - int rb = subcarrier0/NR_NB_SC_PER_RB; + sum_re = 0; + sum_re2 = 0; + sum_im = 0; + sum_im2 = 0; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + for (int p_index = 0; p_index < N_ap; p_index++) { + uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS + rb*srs_symbols_per_rb; + for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) { + sum_re = sum_re + noise_real[base_idx+srs_symb]; + sum_re2 = sum_re2 + noise_real[base_idx+srs_symb]*noise_real[base_idx+srs_symb]; + sum_im = sum_im + noise_imag[base_idx+srs_symb]; + sum_im2 = sum_im2 + noise_imag[base_idx+srs_symb]*noise_imag[base_idx+srs_symb]; + } // for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) + } // for (int p_index = 0; p_index < N_ap; p_index++) + } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) - sum_re = sum_re + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; - sum_re2 = sum_re2 + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]*noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; - sum_im = sum_im + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; - sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; - - count_estimates++; - if (count_estimates == n_noise_est) { - noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) + - sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1); - snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<nb_antennas_rx*nr_srs_info->sc_list_length) - + calc_power(noise_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + *noise_power = max(calc_power(noise_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) + + calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS), 1); *snr = dB_fixed((int32_t)((*signal_power<comb_size == 0 ? 2 : 4; - for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; - } - if(sc_idx == 0) { - LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant); - } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", subcarrier_log/12); - LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm_\n"); - } - for(int r = 0; rsc_list[sc_idx] + r >= frame_parms->ofdm_symbol_size) - continue; - LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", - subcarrier_log+r, - (int16_t)(srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]+r]&0xFFFF), - (int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]+r]>>16)&0xFFFF), - (int16_t)(srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]+r]&0xFFFF), - (int16_t)((srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]+r]>>16)&0xFFFF), - noise_real[ant*nr_srs_info->sc_list_length+sc_idx], - noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]); - } - - } - } LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", *noise_power, *snr); #endif diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index b0ed3662ea..f00db212f7 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -71,12 +71,12 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, const int slot, const nfapi_nr_srs_pdu_t *srs_pdu, const nr_srs_info_t *nr_srs_info, - const int32_t *srs_generated_signal, + const int32_t **srs_generated_signal, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size], - int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_ls_estimated_channel[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], uint32_t *signal_power, uint32_t *noise_power_per_rb, uint32_t *noise_power, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 5437a9bb81..e5b043c395 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -315,19 +315,19 @@ int nr_find_pucch(uint16_t rnti, NR_gNB_SRS_t *new_gNB_srs(void); void free_gNB_srs(NR_gNB_SRS_t *srs); -int nr_find_srs(uint16_t rnti, - int frame, - int slot, +int nr_find_srs(rnti_t rnti, + frame_t frame, + slot_t slot, PHY_VARS_gNB *gNB); void nr_fill_srs(PHY_VARS_gNB *gNB, - int frame, - int slot, + frame_t frame, + slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu); int nr_get_srs_signal(PHY_VARS_gNB *gNB, - int frame, - int slot, + frame_t frame, + slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)]); diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 39c3846db5..54264b70e0 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -30,10 +30,12 @@ #include #include +#include "PHY/INIT/phy_init.h" #include "PHY/impl_defs_nr.h" #include "PHY/defs_nr_common.h" #include "PHY/defs_gNB.h" -#include +#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" +#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h" #include "common/utils/LOG/log.h" #include "nfapi/oai_integration/vendor_ext.h" @@ -54,9 +56,9 @@ void free_gNB_srs(NR_gNB_SRS_t *srs) free_and_zero(srs); } -int nr_find_srs(uint16_t rnti, - int frame, - int slot, +int nr_find_srs(rnti_t rnti, + frame_t frame, + slot_t slot, PHY_VARS_gNB *gNB) { AssertFatal(gNB!=NULL,"gNB is null\n"); @@ -78,8 +80,8 @@ int nr_find_srs(uint16_t rnti, } void nr_fill_srs(PHY_VARS_gNB *gNB, - int frame, - int slot, + frame_t frame, + slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu) { int id = nr_find_srs(srs_pdu->rnti,frame,slot,gNB); @@ -94,23 +96,28 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, } int nr_get_srs_signal(PHY_VARS_gNB *gNB, - int frame, - int slot, + frame_t frame, + slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)]) { - if(nr_srs_info->sc_list_length == 0) { - LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); - return -1; - } +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); +#endif int32_t **rxdataF = gNB->common_vars.rxdataF; - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - uint16_t n_symbols = (slot&3)*frame_parms->symbols_per_slot; // number of symbols until this slot - uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot - uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size; + const uint16_t n_symbols = (slot&3)*frame_parms->symbols_per_slot; // number of symbols until this slot + const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot + const uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size; + const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; + + const uint8_t N_ap = 1<num_ant_ports; + const uint8_t N_symb_SRS = 1<num_symbols; + const uint8_t K_TC = 2<comb_size; + const uint16_t M_sc_b_SRS = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0] * NR_NB_SC_PER_RB/K_TC; int32_t *rx_signal; bool no_srs_signal = true; @@ -119,32 +126,56 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); rx_signal = &rxdataF[ant][symbol_offset]; - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] = rx_signal[nr_srs_info->sc_list[sc_idx]]; - - if (rx_signal[nr_srs_info->sc_list[sc_idx]] != 0) { - no_srs_signal = false; - } + for (int p_index = 0; p_index < N_ap; p_index++) { #ifdef SRS_DEBUG - uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; - int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; - } - if(sc_idx == 0) { - LOG_I(NR_PHY,"________ Rx antenna %i ________\n", ant); - } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,"::::::::::::: %i :::::::::::::\n", subcarrier_log/12); - } - LOG_I(NR_PHY,"(%i) \t%i\t%i\n", - subcarrier_log, - (int16_t)(srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]]&0xFFFF), - (int16_t)((srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]]>>16)&0xFFFF)); + LOG_I(NR_PHY,"===== UE port %d --> gNB Rx antenna %i =====\n", p_index, ant); #endif - } - } + + for (int l_line = 0; l_line < N_symb_SRS; l_line++) { + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,":::::::: OFDM symbol %d ::::::::\n", l0+l_line); +#endif + + uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][l_line]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } + uint16_t l_line_offset = l_line*frame_parms->ofdm_symbol_size; + + for (int k = 0; k < M_sc_b_SRS; k++) { + + srs_received_signal[ant][l_line_offset+subcarrier] = rx_signal[l_line_offset+subcarrier]; + + if (rx_signal[l_line_offset+subcarrier] != 0) { + no_srs_signal = false; + } + +#ifdef SRS_DEBUG + int subcarrier_log = subcarrier-subcarrier_offset; + if(subcarrier_log < 0) { + subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + } + if(subcarrier_log%12 == 0) { + LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12); + } + LOG_I(NR_PHY,"(%i) \t%i\t%i\n", + subcarrier_log, + (int16_t)(srs_received_signal[ant][l_line_offset+subcarrier]&0xFFFF), + (int16_t)((srs_received_signal[ant][l_line_offset+subcarrier]>>16)&0xFFFF)); +#endif + + // Subcarrier increment + subcarrier += K_TC; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } + + } // for (int k = 0; k < M_sc_b_SRS; k++) + } // for (int l_line = 0; l_line < N_symb_SRS; l_line++) + } // for (int p_index = 0; p_index < N_ap; p_index++) + } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) if (no_srs_signal) { LOG_W(NR_PHY, "No SRS signal\n"); diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index f3a953c9a8..55669ba322 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -48,9 +48,129 @@ //#define SRS_DEBUG -/******************************************************************* + +uint16_t group_number_hopping(int slot_number, + uint8_t n_ID_SRS, + uint8_t l0, + uint8_t l_line) { + + // Pseudo-random sequence c(i) defined by TS 38.211 - Section 5.2.1 + uint32_t cinit = n_ID_SRS; + uint8_t c_last_index = 8 * (slot_number * N_SYMB_SLOT + l0 + l_line) + 7; + uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t)); + pseudo_random_sequence(c_last_index+1, c_sequence, cinit); + + // TS 38.211 - 6.4.1.4.2 Sequence generation + uint32_t f_gh = 0; + for (int m = 0; m <= 7; m++) { + f_gh += c_sequence[8 * (slot_number * N_SYMB_SLOT + l0 + l_line) + m] << m; + } + f_gh = f_gh%30; + uint8_t u = (f_gh + n_ID_SRS)%U_GROUP_NUMBER; + + free(c_sequence); + return u; +} + +uint16_t sequence_number_hopping(int slot_number, + uint8_t n_ID_SRS, + uint16_t M_sc_b_SRS, + uint8_t l0, + uint8_t l_line) { + uint16_t v = 0; + if (M_sc_b_SRS > 6 * NR_NB_SC_PER_RB) { + // Pseudo-random sequence c(i) defined by TS 38.211 - Section 5.2.1 + uint32_t cinit = n_ID_SRS; + uint8_t c_last_index = (slot_number * N_SYMB_SLOT + l0 + l_line); + uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t)); + pseudo_random_sequence(c_last_index+1, c_sequence, cinit); + // TS 38.211 - 6.4.1.4.2 Sequence generation + v = c_sequence[c_last_index]; + free(c_sequence); + } + return v; +} + +uint16_t compute_F_b(frame_t frame_number, + slot_t slot_number, + uint16_t slots_per_frame, + uint8_t N_symb_SRS, + uint8_t B_SRS, + uint8_t C_SRS, + uint8_t b_hop, + uint8_t R, + uint16_t T_offset, + uint16_t T_SRS, + resourceType_t resource_type, + uint8_t l_line, + uint8_t b) { + + // Compute the number of SRS transmissions + uint16_t n_SRS = 0; + if (resource_type == aperiodic) { + n_SRS = l_line / R; + } else { + n_SRS = ((slots_per_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l_line / R); + } + + uint16_t product_N_b = 1; + for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) { + if (b_prime != b_hop) { + product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1]; + } + } + + uint16_t F_b = 0; + uint8_t N_b = srs_bandwidth_config[C_SRS][b][1]; + if (N_b & 1) { // Nb odd + F_b = (N_b/2)*(n_SRS/product_N_b); + } else { // Nb even + uint16_t product_N_b_B_SRS = product_N_b; + product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */ + F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b); + } + + return F_b; +} + +uint16_t compute_n_b(frame_t frame_number, + slot_t slot_number, + uint16_t slots_per_frame, + uint8_t N_symb_SRS, + uint8_t B_SRS, + uint8_t C_SRS, + uint8_t b_hop, + uint8_t n_RRC, + uint8_t R, + uint16_t T_offset, + uint16_t T_SRS, + resourceType_t resource_type, + uint8_t l_line, + uint8_t b) { + + uint8_t N_b = srs_bandwidth_config[C_SRS][b][1]; + uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; + + uint16_t n_b = 0; + if (b_hop >= B_SRS) { + n_b = (4 * n_RRC/m_SRS_b)%N_b; + } else { + if (b <= b_hop) { + n_b = (4 * n_RRC/m_SRS_b)%N_b; + } else { + // Compute the hopping offset Fb + uint16_t F_b = compute_F_b(frame_number, slot_number, slots_per_frame, N_symb_SRS, B_SRS, C_SRS, b_hop, R, + T_offset, T_SRS, resource_type, l_line, b); + n_b = (F_b + (4 * n_RRC/m_SRS_b))%N_b; + } + } + + return n_b; +} + +/************************************************************************* * -* NAME : generate_srs +* NAME : generate_srs_nr * * PARAMETERS : pointer to srs config pdu * pointer to transmit buffer @@ -60,68 +180,43 @@ * -1 if sequence can not be properly generated * * DESCRIPTION : generate/map srs symbol into transmit buffer -* see TS 38211 6.4.1.4 Sounding reference signal +* See TS 38.211 - Section 6.4.1.4 Sounding reference signal * -* FFS_TODO_NR -* Current supported configuration: -* - single resource per resource set -* - single port antenna -* - 1 symbol for SRS -* - no symbol offset -* - periodic mode -* - no hopping -* - no carrier switching -* - no antenna switching* -* -*********************************************************************/ +***************************************************************************/ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, - int32_t *txptr, + int32_t **txdataF, + uint16_t symbol_offset, nr_srs_info_t *nr_srs_info, int16_t amp, - int frame_number, - int slot_number) -{ - uint8_t n_SRS_cs_max; - uint8_t u; - uint8_t v_nu; - uint32_t f_gh = 0; - uint16_t n_SRS; - uint16_t n_SRS_cs_i; - double alpha_i; - uint8_t K_TC_p; - uint16_t n_b[B_SRS_NUMBER]; - uint16_t F_b; - uint16_t subcarrier; - uint8_t N_b; - uint8_t k_0_overbar_p; + frame_t frame_number, + slot_t slot_number) { - // get parameters from srs_config_pdu - uint8_t B_SRS = srs_config_pdu->bandwidth_index; - uint8_t C_SRS = srs_config_pdu->config_index; +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); +#endif + + // SRS config parameters + uint8_t B_SRS = srs_config_pdu->bandwidth_index; + uint8_t C_SRS = srs_config_pdu->config_index; uint8_t b_hop = srs_config_pdu->frequency_hopping; uint8_t K_TC = 2<comb_size; - uint8_t K_TC_overbar = srs_config_pdu->comb_offset; // FFS_TODO_NR is this parameter for K_TC_overbar ?? + uint8_t K_TC_overbar = srs_config_pdu->comb_offset; uint8_t n_SRS_cs = srs_config_pdu->cyclic_shift; uint8_t n_ID_SRS = srs_config_pdu->sequence_id; - uint8_t n_shift = srs_config_pdu->frequency_position; // it adjusts the SRS allocation to align with the common resource block grid in multiples of four + uint8_t n_shift = srs_config_pdu->frequency_position; // It adjusts the SRS allocation to align with the common resource block grid in multiples of four uint8_t n_RRC = srs_config_pdu->frequency_shift; uint8_t groupOrSequenceHopping = srs_config_pdu->group_or_sequence_hopping; uint8_t l_offset = srs_config_pdu->time_start_position; uint16_t T_SRS = srs_config_pdu->t_srs; - uint16_t T_offset = srs_config_pdu->t_offset; // FFS_TODO_NR to check interface with RRC + uint16_t T_offset = srs_config_pdu->t_offset; uint8_t R = 1<num_repetitions; - uint8_t N_ap = 1<num_ant_ports; // antenna port for transmission - uint8_t N_symb_SRS = 1<num_symbols; // consecutive OFDM symbols - uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // starting position in the time domain - uint8_t k_0_p; // frequency domain starting position - - uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_config_pdu->bwp_start*N_SC_RB; - - if(nr_srs_info) { - nr_srs_info->sc_list_length = 0; - nr_srs_info->srs_generated_signal_bits = log2_approx(amp); - } + uint8_t N_ap = 1<num_ant_ports; // Number of antenna port for transmission + uint8_t N_symb_SRS = 1<num_symbols; // Number of consecutive OFDM symbols + uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // Starting symbol position in the time domain + uint8_t n_SRS_cs_max = srs_max_number_cs[srs_config_pdu->comb_size]; + uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; // Number of resource blocks + uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; // Length of the SRS sequence #ifdef SRS_DEBUG LOG_I(NR_PHY,"Frame = %i, slot = %i\n", frame_number, slot_number); @@ -142,265 +237,185 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, LOG_I(NR_PHY,"N_ap = %i\n", N_ap); LOG_I(NR_PHY,"N_symb_SRS = %i\n", N_symb_SRS); LOG_I(NR_PHY,"l0 = %i\n", l0); + LOG_I(NR_PHY,"n_SRS_cs_max = %i\n", n_SRS_cs_max); + LOG_I(NR_PHY,"m_SRS_b = %i\n", m_SRS_b); + LOG_I(NR_PHY,"M_sc_b_SRS = %i\n", M_sc_b_SRS); #endif - if (N_ap != port1) { - LOG_E(NR_PHY, "generate_srs: this number of antenna ports %d is not yet supported!\n", N_ap); - return (-1); - } - if (N_symb_SRS != 1) { - LOG_E(NR_PHY, "generate_srs: this number of srs symbol %d is not yet supported!\n", N_symb_SRS); - return (-1); - } - if (groupOrSequenceHopping != neitherHopping) { - LOG_E(NR_PHY, "generate_srs: sequence hopping is not yet supported!\n"); - return (-1); - } + // Validation of SRS config parameters + if (R == 0) { LOG_E(NR_PHY, "generate_srs: this parameter repetition factor %d is not consistent !\n", R); - return (-1); - } - else if (R > N_symb_SRS) { + return -1; + } else if (R > N_symb_SRS) { LOG_E(NR_PHY, "generate_srs: R %d can not be greater than N_symb_SRS %d !\n", R, N_symb_SRS); - return (-1); - } - /* see 38211 6.4.1.4.2 Sequence generation */ - if (K_TC == 4) { - n_SRS_cs_max = 12; - // delta = 2; /* delta = log2(K_TC) */ - } - else if (K_TC == 2) { - n_SRS_cs_max = 8; - // delta = 1; /* delta = log2(K_TC) */ - } - else { - LOG_E(NR_PHY, "generate_srs: SRS unknown value for K_TC %d !\n", K_TC); - return (-1); + return -1; } + if (n_SRS_cs >= n_SRS_cs_max) { LOG_E(NR_PHY, "generate_srs: inconsistent parameter n_SRS_cs %d >= n_SRS_cs_max %d !\n", n_SRS_cs, n_SRS_cs_max); - return (-1); + return -1; } + if (T_SRS == 0) { LOG_E(NR_PHY, "generate_srs: inconsistent parameter T_SRS %d can not be equal to zero !\n", T_SRS); - return (-1); - } - else - { + return -1; + } else { int index = 0; while (srs_periodicity[index] != T_SRS) { index++; if (index == SRS_PERIODICITY) { LOG_E(NR_PHY, "generate_srs: inconsistent parameter T_SRS %d not specified !\n", T_SRS); - return (-1); + return -1; } } } - uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; /* m_SRS_b is given by TS 38211 clause 6.4.1.4.3 */ - uint16_t M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC; /* length of the sounding reference signal sequence */ + // Variable initialization + if(nr_srs_info) { + nr_srs_info->srs_generated_signal_bits = log2_approx(amp); + } + uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_config_pdu->bwp_start*NR_NB_SC_PER_RB; + double sqrt_N_ap = sqrt(N_ap); + uint16_t n_b[B_SRS_NUMBER]; - /* for each antenna ports for transmission */ + // Find index of table which is for this SRS length + uint16_t M_sc_b_SRS_index = 0; + while((ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) && (M_sc_b_SRS_index < SRS_SB_CONF)){ + M_sc_b_SRS_index++; + } + + // SRS sequence generation and mapping, TS 38.211 - Section 6.4.1.4 for (int p_index = 0; p_index < N_ap; p_index++) { - /* see TS 38.211 6.4.1.4.2 Sequence generation */ - - n_SRS_cs_i = (n_SRS_cs + (n_SRS_cs_max * (SRS_antenna_port[p_index] - 1000)/N_ap))%n_SRS_cs_max; - alpha_i = 2 * M_PI * ((double)n_SRS_cs_i / (double)n_SRS_cs_max); - - /* for each SRS symbol which should be managed by SRS configuration */ - /* from TS 38.214 6.2.1.1 UE SRS frequency hopping procedure */ - /* A UE may be configured to transmit an SRS resource on adjacent symbols within the last six symbols of a slot, */ - /* where all antenna ports of the SRS resource are mapped to each symbol of the resource */ - - uint8_t l = p_index; - if (l >= N_symb_SRS) { - LOG_E(NR_PHY, "generate_srs: number of antenna ports %d and number of srs symbols %d are different !\n", N_ap, N_symb_SRS); - } - - switch(groupOrSequenceHopping) { - case neitherHopping: - { - f_gh = 0; - v_nu = 0; - break; - } - case groupHopping: - { - uint8_t c_last_index = 8 * (slot_number * N_SYMB_SLOT + l0 + l) + 7; /* compute maximum value of the random sequence */ - uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t)); - uint32_t cinit = n_ID_SRS/30; - pseudo_random_sequence(c_last_index+1, c_sequence, cinit); - for (int m = 0; m < 8; m++) { - f_gh += c_sequence[8 * (slot_number * N_SYMB_SLOT + l0 + l) + m]< 6 * N_SC_RB) { - uint8_t c_last_index = (slot_number * N_SYMB_SLOT + l0 + l); /* compute maximum value of the random sequence */ - uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t)); - uint32_t cinit = n_ID_SRS; - pseudo_random_sequence(c_last_index+1, c_sequence, cinit); - v_nu = c_sequence[c_last_index]; - free(c_sequence); - } - else { - v_nu = 0; - } - break; - } - default: - { - LOG_E(NR_PHY, "generate_srs: unknown hopping setting %d !\n", groupOrSequenceHopping); - return (-1); - } - } - - /* u is the sequence-group number defined in section 6.4.1.4.1 */ - u = (f_gh + n_ID_SRS)%U_GROUP_NUMBER; /* 30 */ - - /* TS 38.211 6.4.1.4.3 Mapping to physical resources */ - - if((n_SRS_cs >= n_SRS_cs_max/2)&&(n_SRS_cs < n_SRS_cs_max)&&(N_ap == 4) && ((SRS_antenna_port[p_index] == 1001) || (SRS_antenna_port[p_index] == 1003))) { - K_TC_p = (K_TC_overbar + K_TC/2)%K_TC; - } - else { - K_TC_p = K_TC_overbar; - } - - for (int b = 0; b <= B_SRS; b++) { - N_b = srs_bandwidth_config[C_SRS][b][1]; - if (b_hop >= B_SRS) { - n_b[b] = (4 * n_RRC/m_SRS_b)%N_b; /* frequency hopping is disabled and the frequency position index n_b remains constant */ - } - else { - if (b == b_hop) { - N_b = 1; - } - /* periodicity and offset */ - if (srs_config_pdu->resource_type == aperiodic) { - n_SRS = l/R; - } - else { - int8_t N_slot_frame = frame_parms->slots_per_frame; - n_SRS = ((N_slot_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l/R); - } - - uint16_t product_N_b = 1; /* for b_hop to b-1 */ - for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) { /* product for b_hop to b-1 */ - if (b_prime != b_hop) { - product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1]; - } - } - - if (N_b & 1) { /* Nb odd */ - F_b = (N_b/2)*(n_SRS/product_N_b); - } - else { /* Nb even */ - uint16_t product_N_b_B_SRS = product_N_b; - product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */ - F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b); - } - - if (b <= b_hop) { - n_b[b] = (4 * n_RRC/m_SRS_b)%N_b; - } - else { - n_b[b] = (F_b + (4 * n_RRC/m_SRS_b))%N_b; - } - } - } - - k_0_overbar_p = n_shift * N_SC_RB + K_TC_p; - - k_0_p = k_0_overbar_p; /* it is the frequency-domain starting position */ - - for (int b = 0; b <= B_SRS; b++) { - k_0_p += K_TC * M_sc_b_SRS * n_b[b]; - } - - subcarrier = subcarrier_offset + k_0_p; - if (subcarrier>frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } - - /* find index of table which is for this srs length */ - unsigned int M_sc_b_SRS_index = 0; - while((ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) && (M_sc_b_SRS_index < SRS_SB_CONF)){ - M_sc_b_SRS_index++; - } - - if (ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) { - LOG_E(NR_PHY, "generate_srs: srs uplink allocation %d can not be found! \n", M_sc_b_SRS); - return (-1); - } - -#if 0 - - char output_file[255]; - char sequence_name[255]; - sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v_nu, ul_allocated_re[M_sc_b_SRS_index]); - sprintf(sequence_name, "rv_seq_%d_%d_%d", u, v_nu, ul_allocated_re[M_sc_b_SRS_index]); - write_output(output_file, sequence_name, rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index], ul_allocated_re[M_sc_b_SRS_index], 1, 1); - +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"============ port %d ============\n", p_index); #endif - for (int k=0; k < M_sc_b_SRS; k++) { + uint16_t n_SRS_cs_i = (n_SRS_cs + (n_SRS_cs_max * (SRS_antenna_port[p_index] - 1000)/N_ap))%n_SRS_cs_max; + double alpha_i = 2 * M_PI * ((double)n_SRS_cs_i / (double)n_SRS_cs_max); - double real_shift = cos(alpha_i*k); - double imag_shift = sin(alpha_i*k); - - /* cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */ - double real = ((real_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k]) - (imag_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]))/sqrt(N_ap); - /* sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */ - double imag = ((imag_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k]) + (real_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]))/sqrt(N_ap); - - int32_t real_amp = ((int32_t)round((double) amp * real)) >> 15; - int32_t imag_amp = ((int32_t)round((double) amp * imag)) >> 15; - -#if 0 - printf("subcarrier %5d srs[%3d] r: %4d i: %4d reference[%d][%d][%d] r: %6d i: %6d\n", subcarrier, k, real_amp, imag_amp, - u, v_nu, M_sc_b_SRS_index, - rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k], - rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]); +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"n_SRS_cs_i = %i\n", n_SRS_cs_i); + LOG_I(NR_PHY,"alpha_i = %f\n", alpha_i); #endif - txptr[subcarrier] = (real_amp & 0xFFFF) + ((imag_amp<<16)&0xFFFF0000); + for (int l_line = 0; l_line < N_symb_SRS; l_line++) { - if(nr_srs_info) { - nr_srs_info->sc_list[nr_srs_info->sc_list_length] = subcarrier; - nr_srs_info->sc_list_length++; +#ifdef SRS_DEBUG + LOG_I(NR_PHY,":::::::: OFDM symbol %d ::::::::\n", l0+l_line); +#endif + + // Set group and sequence numbers (u,v) per OFDM symbol + uint16_t u = 0; + uint16_t v = 0; + switch(groupOrSequenceHopping) { + case neitherHopping: + u = n_ID_SRS%U_GROUP_NUMBER; + v = 0; + break; + case groupHopping: + u = group_number_hopping(slot_number, n_ID_SRS, l0, l_line); + v = 0; + break; + case sequenceHopping: + u = n_ID_SRS%U_GROUP_NUMBER; + v = sequence_number_hopping(slot_number, n_ID_SRS, M_sc_b_SRS, l0, l_line); + break; + default: + LOG_E(NR_PHY, "generate_srs: unknown hopping setting %d !\n", groupOrSequenceHopping); + return -1; } #ifdef SRS_DEBUG - int subcarrier_log = subcarrier-subcarrier_offset; - if(subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; - } - if( subcarrier_log%12 == 0 ) { - LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12); - } - LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(real_amp&0xFFFF), (int16_t)(imag_amp&0xFFFF)); + LOG_I(NR_PHY,"u = %i\n", u); + LOG_I(NR_PHY,"v = %i\n", v); #endif - subcarrier += (K_TC); /* subcarrier increment */ + // Compute the frequency position index n_b + uint16_t sum_n_b = 0; + for (int b = 0; b <= B_SRS; b++) { + n_b[b] = compute_n_b(frame_number, slot_number, frame_parms->slots_per_frame, N_symb_SRS, B_SRS, + C_SRS, b_hop, n_RRC, R, T_offset, T_SRS, srs_config_pdu->resource_type, l_line, b); + + sum_n_b += n_b[b]; + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"n_b[%i] = %i\n", b, n_b[b]); +#endif - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier=subcarrier-frame_parms->ofdm_symbol_size; } - } - /* process next symbol */ - //txptr = txptr + frame_parms->ofdm_symbol_size; - } +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"sum_n_b = %i\n", sum_n_b); +#endif - return (0); + // Compute the frequency-domain starting position + uint8_t K_TC_p = 0; + if((n_SRS_cs >= n_SRS_cs_max/2)&&(n_SRS_cs < n_SRS_cs_max)&&(N_ap == 4) && ((SRS_antenna_port[p_index] == 1001) || (SRS_antenna_port[p_index] == 1003))) { + K_TC_p = (K_TC_overbar + K_TC/2)%K_TC; + } else { + K_TC_p = K_TC_overbar; + } + uint8_t k_l_offset = 0; // If the SRS is configured by the IE SRS-PosResource-r16, the quantity k_l_offset is + // given by TS 38.211 - Table 6.4.1.4.3-2, otherwise k_l_offset = 0. + uint8_t k_0_overbar_p = (n_shift*NR_NB_SC_PER_RB + (K_TC_p+k_l_offset))%K_TC; + uint8_t k_0_p = k_0_overbar_p + K_TC*M_sc_b_SRS*sum_n_b; + nr_srs_info->k_0_p[p_index][l_line] = k_0_p; + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"K_TC_p = %i\n", K_TC_p); + LOG_I(NR_PHY,"k_0_overbar_p = %i\n", k_0_overbar_p); + LOG_I(NR_PHY,"k_0_p = %i\n", k_0_p); +#endif + + uint16_t subcarrier = subcarrier_offset + k_0_p; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } + uint16_t l_line_offset = l_line*frame_parms->ofdm_symbol_size; + + // For each port, and for each OFDM symbol, here it is computed and mapped an SRS sequence with M_sc_b_SRS symbols + for (int k = 0; k < M_sc_b_SRS; k++) { + + double shift_real = cos(alpha_i * k); + double shift_imag = sin(alpha_i * k); + int16_t r_overbar_real = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k<<1]; + int16_t r_overbar_imag = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][(k<<1)+1]; + + // cos(x+y) = cos(x)cos(y) - sin(x)sin(y) + double r_real = (shift_real*r_overbar_real - shift_imag*r_overbar_imag) / sqrt_N_ap; + + // sin(x+y) = sin(x)cos(y) + cos(x)sin(y) + double r_imag = (shift_imag*r_overbar_real + shift_real*r_overbar_imag) / sqrt_N_ap; + + int32_t r_real_amp = ((int32_t) round((double) amp * r_real)) >> 15; + int32_t r_imag_amp = ((int32_t) round((double) amp * r_imag)) >> 15; + +#ifdef SRS_DEBUG + int subcarrier_log = subcarrier-subcarrier_offset; + if(subcarrier_log < 0) { + subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + } + if(subcarrier_log%12 == 0) { + LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12); + } + LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(r_real_amp&0xFFFF), (int16_t)(r_imag_amp&0xFFFF)); +#endif + + txdataF[p_index][symbol_offset+l_line_offset+subcarrier] = (r_real_amp & 0xFFFF) + ((r_imag_amp<<16)&0xFFFF0000); + + // Subcarrier increment + subcarrier += K_TC; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } + + } // for (int k = 0; k < M_sc_b_SRS; k++) + } // for (int l_line = 0; l_line < N_symb_SRS; l_line++) + } // for (int p_index = 0; p_index < N_ap; p_index++) + + return 0; } /******************************************************************* @@ -457,7 +472,7 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gN NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms); uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size; - if (generate_srs_nr(srs_config_pdu, frame_parms, &ue->common_vars.txdataF[gNB_id][symbol_offset], ue->nr_srs_info, + if (generate_srs_nr(srs_config_pdu, frame_parms, ue->common_vars.txdataF, symbol_offset, ue->nr_srs_info, AMP, proc->frame_tx, proc->nr_slot_tx) == 0) { return 0; } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index e43bbe4934..2c3d6d266c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -131,11 +131,19 @@ EXTERN const uint16_t srs_periodicity[SRS_PERIODICITY] #endif ; +// TS 38.211 - Table 6.4.1.4.2-1 +EXTERN const uint16_t srs_max_number_cs[3] +#ifdef INIT_VARIABLES_SRS_MODULATION_NR_H + = {8, 12, 6} +#endif +; + /*************** FUNCTIONS *****************************************/ /** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 38.211 6.4.1.4 Sounding reference signal @param frame_parms NR DL Frame parameters @param txdataF pointer to the frequency domain TX signal + @param symbol_offset symbol offset added in txdataF @param nr_srs_info pointer to the srs info structure @param amp amplitude of generated signal @param frame_number frame number @@ -144,11 +152,12 @@ EXTERN const uint16_t srs_periodicity[SRS_PERIODICITY] int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, - int32_t *txptr, + int32_t **txdataF, + uint16_t symbol_offset, nr_srs_info_t *nr_srs_info, int16_t amp, - int frame_number, - int slot_number); + frame_t frame_number, + slot_t slot_number); /** \brief This function checks for periodic srs if srs should be transmitted in this slot * @param p_SRS_Resource pointer to active resource diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index a9d502b9eb..fb2f4d589e 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -85,38 +85,30 @@ void multadd_real_vector_complex_scalar(int16_t *x, uint32_t i; // do 8 multiplications at a time - simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x,*y_128=(simd_q15_t*)y; - int j; + simd_q15_t alpha_r_128, alpha_i_128, yr, yi, *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y; // printf("alpha = %d,%d\n",alpha[0],alpha[1]); alpha_r_128 = set1_int16(alpha[0]); alpha_i_128 = set1_int16(alpha[1]); - - j=0; - for (i=0; i>3; i++) { yr = mulhi_s1_int16(alpha_r_128,x_128[i]); yi = mulhi_s1_int16(alpha_i_128,x_128[i]); #if defined(__x86_64__) || defined(__i386__) - y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpacklo_epi16(yr,yi)); - j++; - y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpackhi_epi16(yr,yi)); - j++; + const simd_q15_t tmp = _mm_loadu_si128(y_128); + _mm_storeu_si128(y_128++, _mm_adds_epi16(tmp, _mm_unpacklo_epi16(yr, yi))); + const simd_q15_t tmp2 = _mm_loadu_si128(y_128); + _mm_storeu_si128(y_128++, _mm_adds_epi16(tmp2, _mm_unpackhi_epi16(yr, yi))); #elif defined(__arm__) int16x8x2_t yint; yint = vzipq_s16(yr,yi); - y_128[j] = adds_int16(y_128[j],yint.val[0]); + *y_128 = adds_int16(*y_128, yint.val[0]); j++; - y_128[j] = adds_int16(y_128[j],yint.val[1]); - + *y_128 = adds_int16(*y_128, yint.val[1]); + j++; #endif } - - _mm_empty(); - _m_empty(); - } void multadd_real_four_symbols_vector_complex_scalar(int16_t *x, diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 33451944ef..c8a063fe19 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -97,6 +97,7 @@ #define MAX_NUM_NR_RE (4*14*273*12) #define MAX_NUM_NR_SRS_SYMBOLS 4 +#define MAX_NUM_NR_SRS_AP 4 #define NR_RX_NB_TH 1 #define NR_NB_TH_SLOT 2 @@ -241,10 +242,9 @@ typedef struct { } NR_PRACH_RESOURCES_t; typedef struct { - uint16_t sc_list_length; - uint16_t sc_list[6*273]; + uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS]; uint8_t srs_generated_signal_bits; - int32_t srs_generated_signal[OFDM_SYMBOL_SIZE_SAMPLES_MAX * MAX_NUM_NR_SRS_SYMBOLS]; + int32_t **srs_generated_signal; } nr_srs_info_t; typedef struct { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 7c6a2eb998..bdcebc77e6 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -807,10 +807,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; uint8_t N_symb_SRS = 1<num_symbols; int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; - int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; - int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); - int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); - int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS]; + int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size]; uint32_t noise_power_per_rb[srs_pdu->bwp_size]; int8_t snr_per_rb[srs_pdu->bwp_size]; uint32_t signal_power; @@ -818,8 +818,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { int8_t snr; // At least currently, the configuration is constant, so it is enough to generate the sequence just once. - if(gNB->nr_srs_info[i]->sc_list_length == 0) { - generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); + if(gNB->nr_srs_info[i]->srs_generated_signal_bits == 0) { + generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); } const int srs_est = nr_get_srs_signal(gNB,frame_rx,slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); @@ -830,7 +830,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { slot_rx, srs_pdu, gNB->nr_srs_info[i], - gNB->nr_srs_info[i]->srs_generated_signal, + (const int32_t **) gNB->nr_srs_info[i]->srs_generated_signal, srs_received_signal, srs_ls_estimated_channel, srs_estimated_channel_freq, @@ -844,10 +844,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(srs_estimated_channel_freq[0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(srs_estimated_channel_time_shifted[0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); const uint16_t num_srs = gNB->UL_INFO.srs_ind.number_of_pdus; gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0]; @@ -856,7 +856,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle; gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; gNB->srs_pdu_list[num_srs].timing_advance = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, - srs_estimated_channel_time) : 0xFFFF; + srs_estimated_channel_time[0]) : 0xFFFF; gNB->srs_pdu_list[num_srs].num_symbols = 1<num_symbols; gNB->srs_pdu_list[num_srs].wide_band_snr = srs_est >= 0 ? (snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<num_symbols; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 17f97ba59c..ea25fd436f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -65,6 +65,8 @@ #include "common/ran_context.h" +//#define DEBUG_DCI + extern RAN_CONTEXT_t RC; // Note the 2 scs values in the table names represent resp. scs_common and pdcch_scs @@ -1247,8 +1249,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->format_type = default_pucch_fmt[rsetindex]; pucch_pdu->initial_cyclic_shift = r_pucch%default_pucch_csset[rsetindex]; if (rsetindex==3||rsetindex==7||rsetindex==11) pucch_pdu->initial_cyclic_shift*=6; - else if (rsetindex==1||rsetindex==2) pucch_pdu->initial_cyclic_shift*=3; - else pucch_pdu->initial_cyclic_shift*=4; + else if (rsetindex==1||rsetindex==2) pucch_pdu->initial_cyclic_shift*=4; + else pucch_pdu->initial_cyclic_shift*=3; pucch_pdu->nr_of_symbols = nr_of_symb; pucch_pdu->start_symbol_index = start_symb; if (pucch_pdu->format_type == 1) pucch_pdu->time_domain_occ_idx = 0; // check this!! @@ -1827,7 +1829,37 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, // UL-SCH indicator pos += 1; *dci_pdu |= ((uint64_t)dci_pdu_rel15->ulsch_indicator & 0x1) << (dci_size - pos); - break; + +#ifdef DEBUG_DCI + LOG_I(NR_MAC,"============= NR_UL_DCI_FORMAT_0_1 =============\n"); + LOG_I(NR_MAC,"dci_size = %i\n", dci_size); + LOG_I(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator); + LOG_I(NR_MAC,"dci_pdu_rel15->carrier_indicator.val = %i\n", dci_pdu_rel15->carrier_indicator.val); + LOG_I(NR_MAC,"dci_pdu_rel15->ul_sul_indicator.val = %i\n", dci_pdu_rel15->ul_sul_indicator.val); + LOG_I(NR_MAC,"dci_pdu_rel15->bwp_indicator.val = %i\n", dci_pdu_rel15->bwp_indicator.val); + LOG_I(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_I(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_I(NR_MAC,"dci_pdu_rel15->frequency_hopping_flag.val = %i\n", dci_pdu_rel15->frequency_hopping_flag.val); + LOG_I(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_I(NR_MAC,"dci_pdu_rel15->ndi = %i\n", dci_pdu_rel15->ndi); + LOG_I(NR_MAC,"dci_pdu_rel15->rv= %i\n", dci_pdu_rel15->rv); + LOG_I(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid); + LOG_I(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val); + LOG_I(NR_MAC,"dci_pdu_rel15->dai[1].val = %i\n", dci_pdu_rel15->dai[1].val); + LOG_I(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc); + LOG_I(NR_MAC,"dci_pdu_rel15->srs_resource_indicator.val = %i\n", dci_pdu_rel15->srs_resource_indicator.val); + LOG_I(NR_MAC,"dci_pdu_rel15->precoding_information.val = %i\n", dci_pdu_rel15->precoding_information.val); + LOG_I(NR_MAC,"dci_pdu_rel15->antenna_ports.val = %i\n", dci_pdu_rel15->antenna_ports.val); + LOG_I(NR_MAC,"dci_pdu_rel15->srs_request.val = %i\n", dci_pdu_rel15->srs_request.val); + LOG_I(NR_MAC,"dci_pdu_rel15->csi_request.val = %i\n", dci_pdu_rel15->csi_request.val); + LOG_I(NR_MAC,"dci_pdu_rel15->cbgti.val = %i\n", dci_pdu_rel15->cbgti.val); + LOG_I(NR_MAC,"dci_pdu_rel15->ptrs_dmrs_association.val = %i\n", dci_pdu_rel15->ptrs_dmrs_association.val); + LOG_I(NR_MAC,"dci_pdu_rel15->beta_offset_indicator.val = %i\n", dci_pdu_rel15->beta_offset_indicator.val); + LOG_I(NR_MAC,"dci_pdu_rel15->dmrs_sequence_initialization.val = %i\n", dci_pdu_rel15->dmrs_sequence_initialization.val); + LOG_I(NR_MAC,"dci_pdu_rel15->ulsch_indicator = %i\n", dci_pdu_rel15->ulsch_indicator); +#endif + + break; } break; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 4c5d11df5a..04b0bb2d3c 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1092,7 +1092,7 @@ void fill_initial_SpCellConfig(int uid, // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); - config_srs(initialUplinkBWP->srs_Config, curr_bwp, uid, 0, 0); + config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, 0); scheduling_request_config(scc, pucch_Config); @@ -1596,6 +1596,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config)); } config_srs(SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config, + uecap, curr_bwp, uid, 0, @@ -1620,6 +1621,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_BWP_Uplink_t *ul_bwp = UL_BWP_list->list.array[i]; int bwp_size = NRRIV2BW(ul_bwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); config_srs(ul_bwp->bwp_Dedicated->srs_Config, + uecap, bwp_size, uid, i+1, diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 7e123f6872..9a1d137a8c 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -352,6 +352,7 @@ long rrc_get_max_nr_csrs(const uint8_t max_rbs, const long b_SRS) { } void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, + const NR_UE_NR_Capability_t *uecap, const int curr_bwp, const int uid, const int res_id, @@ -418,6 +419,26 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0)); srs_res0->srs_ResourceId = res_id; srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + // if (uecap && + // uecap->featureSets && + // uecap->featureSets->featureSetsUplink && + // uecap->featureSets->featureSetsUplink->list.count > 0) { + // NR_FeatureSetUplink_t *ul_feature_setup = uecap->featureSets->featureSetsUplink->list.array[0]; + // switch (ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource) { + // case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n1: + // srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + // break; + // case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n2: + // srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports2; + // break; + // case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n4: + // srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports4; + // break; + // default: + // LOG_E(NR_RRC, "Max Number of SRS Ports Per Resource %ld is invalid!\n", + // ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource); + // } + // } srs_res0->ptrs_PortIndex = NULL; srs_res0->transmissionComb.present = NR_SRS_Resource__transmissionComb_PR_n2; srs_res0->transmissionComb.choice.n2 = calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2)); @@ -1116,6 +1137,7 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp, ubwp->bwp_Dedicated->srs_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->srs_Config)); config_srs(ubwp->bwp_Dedicated->srs_Config, + NULL, curr_bwp, uid, bwp_loop+1, diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 58caa50b80..49922aed6b 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -145,6 +145,7 @@ void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, void config_csiim(int do_csirs, int dl_antenna_ports, int curr_bwp, NR_CSI_MeasConfig_t *csi_MeasConfig, int id); void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, + const NR_UE_NR_Capability_t *uecap, const int curr_bwp, const int uid, const int res_id, diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 85aa5e24a9..0f1da63510 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -489,7 +489,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); - config_srs(initialUplinkBWP->srs_Config, curr_bwp, uid, 0, configuration->do_SRS); + config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, configuration->do_SRS); // Downlink BWPs int n_dl_bwp = 1; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf new file mode 100644 index 0000000000..730198653e --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf @@ -0,0 +1,321 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = ( +{ + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( + { + mcc = 208; + mnc = 99; + mnc_length = 2; + snssaiList = ({ + sst = 1; + sd = 0x1; // 0 false, else true + }); + } + ); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pusch_AntennaPorts = 2; + do_CSIRS = 1; + do_SRS = 0; + ul_prbblacklist = "135,136,137,138" + + pdcch_ConfigSIB1 = ({ + controlResourceSetZero = 12; + searchSpaceZero = 0; + }); + + servingCellConfigCommon = ( + { + # spCellConfigCommon + + physCellId = 0; + + # downlinkConfigCommon + # frequencyInfoDL + # this is 3900.60 MHz + (134 PRBs + 4 SCs)@30kHz SCS (GSCN: 8158) + absoluteFrequencySSB = 663264; + dl_frequencyBand = 77; + # this is 3900.60 MHz + dl_absoluteFrequencyPointA = 660040; + + # scs-SpecificCarrierList + dl_offstToCarrier = 0; + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + + # initialDownlinkBWP + # genericParameters + # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) + initialDLBWPlocationAndBandwidth = 31624; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + + # pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + # uplinkConfigCommon + # frequencyInfoUL + ul_frequencyBand = 77; + # scs-SpecificCarrierList + ul_offstToCarrier = 0; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 20; + + # initialUplinkBWP + # genericParameters + initialULBWPlocationAndBandwidth = 31624; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + + # rach-ConfigCommon + # rach-ConfigGeneric + prach_ConfigurationIndex = 98; + # prach_msg1_FDM + # 0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + preambleReceivedTargetPower = -90; + # preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; + # powerRampingStep + # 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; + # ra_ReponseWindow + # 1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; + # ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR + # 1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; + # oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + # ra_ContentionResolutionTimer + # (0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; + # prach-RootSequenceIndex_PR + # 1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + msg1_SubcarrierSpacing = 1, + # restrictedSetConfig + # 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + + # pucch-ConfigCommon + # pucchGroupHopping + # 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -70; + + # dmrs_TypeA_position + # 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + # ssb_PositionsInBurs_BitmapPR + # 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + # ssb_periodicityServingCell + # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + + #tdd-UL-DL-ConfigurationCommon + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + ); + + + # Dedicated Serving Cell Configuration + servingCellConfigDedicated = ( + { + # BWP-Downlink + # BWP 1 Configuration + dl_bwp-Id_1 = 1; + dl_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp1_subcarrierSpacing = 1; + + firstActiveDownlinkBWP-Id = 1; #BWP-Id + defaultDownlinkBWP-Id = 1; #BWP-Id + + # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, + # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, + # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, + # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } + + # UplinkConfig + # BWP-Uplink + # BWP 1 Configuration + ul_bwp-Id_1 = 1; + ul_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp1_subcarrierSpacing = 1; + + firstActiveUplinkBWP-Id = 1; #BWP-Id + } + ); + + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( + { + ipv4 = "192.168.70.132"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + } + +} +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 300; + pucch_TargetSNRx10 = 200; + pusch_FailureThres = 1000; + ulsch_max_frame_inactivity = 0; + ul_max_mcs = 28; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 80; +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 2; + nb_rx = 2; + att_tx = 0; + att_rx = 0; + bands = [77]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + #clock_src = "internal"; + sdr_addrs = "mgmt_addr=192.168.10.2,addr=192.168.10.2,clock_source=internal,time_source=internal" +} +); + +THREAD_STRUCT = ( +{ + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; +} +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; 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 9d00ae20aa..16bd6d9055 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 @@ -28,7 +28,6 @@ gNBs = ////////// Physical parameters: - min_rxtxtime = 2; do_CSIRS = 1; do_SRS = 1; @@ -283,8 +282,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 6; - att_rx = 6; + att_tx = 12; + att_rx = 12; bands = [78]; max_pdschReferenceSignalPower = -27; max_rxgain = 114; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf index 5f8bf45232..ef732126bd 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf @@ -27,15 +27,14 @@ gNBs = ////////// Physical parameters: - pdsch_AntennaPorts_XP = 1; + pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; - do_CSIRS = 0; - ul_prbblacklist = "79,80,81,82" + do_CSIRS = 1; pdcch_ConfigSIB1 = ( { controlResourceSetZero = 12; - searchSpaceZero = 10; + searchSpaceZero = 0; } ); @@ -67,7 +66,7 @@ gNBs = initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon initialDLBWPcontrolResourceSetZero = 12; - initialDLBWPsearchSpaceZero = 10; + initialDLBWPsearchSpaceZero = 0; #uplinkConfigCommon #frequencyInfoUL @@ -203,9 +202,11 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 150; + pusch_TargetSNRx10 = 300; pucch_TargetSNRx10 = 200; + pusch_FailureThres = 1000; ulsch_max_frame_inactivity = 0; + ul_max_mcs = 28; } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf deleted file mode 100644 index 24090bef85..0000000000 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf +++ /dev/null @@ -1,320 +0,0 @@ -Active_gNBs = ( "gNB-OAI"); -# Asn1_verbosity, choice in: none, info, annoying -Asn1_verbosity = "none"; - -gNBs = -( - { - ////////// Identification parameters: - gNB_ID = 0xe00; - gNB_name = "gNB-OAI"; - - // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 1; - plmn_list = ({ - mcc = 208; - mnc = 99; - mnc_length = 2; - snssaiList = ( - { - sst = 1; - sd = 0x1; // 0 false, else true - } - ); - }); - - nr_cellid = 12345678L; - - ////////// Physical parameters: - - pdsch_AntennaPorts_XP = 1; - pusch_AntennaPorts = 2; - do_CSIRS = 0; - ul_prbblacklist = "135,136,137,138" - - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 10; - } - ); - - servingCellConfigCommon = ( - { - #spCellConfigCommon - - physCellId = 0; - -# downlinkConfigCommon - #frequencyInfoDL - # this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741) - absoluteFrequencySSB = 623232; - dl_frequencyBand = 78; - # this is 3300.24 MHz - dl_absoluteFrequencyPointA = 620016; - #scs-SpecificCarrierList - dl_offstToCarrier = 0; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_subcarrierSpacing = 1; - dl_carrierBandwidth = 273; - #initialDownlinkBWP - #genericParameters - # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) - initialDLBWPlocationAndBandwidth = 31624; - # -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialDLBWPsubcarrierSpacing = 1; - #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 12; - initialDLBWPsearchSpaceZero = 10; - - #uplinkConfigCommon - #frequencyInfoUL - ul_frequencyBand = 78; - #scs-SpecificCarrierList - ul_offstToCarrier = 0; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_subcarrierSpacing = 1; - ul_carrierBandwidth = 273; - pMax = 20; - #initialUplinkBWP - #genericParameters - initialULBWPlocationAndBandwidth = 31624; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialULBWPsubcarrierSpacing = 1; - #rach-ConfigCommon - #rach-ConfigGeneric - prach_ConfigurationIndex = 98; -#prach_msg1_FDM -#0 = one, 1=two, 2=four, 3=eight - prach_msg1_FDM = 0; - prach_msg1_FrequencyStart = 0; - zeroCorrelationZoneConfig = 12; - preambleReceivedTargetPower = -90; -#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) - preambleTransMax = 6; -#powerRampingStep -# 0=dB0,1=dB2,2=dB4,3=dB6 - powerRampingStep = 1; -#ra_ReponseWindow -#1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; -#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; -#oneHalf (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; -#ra_ContentionResolutionTimer -#(0..7) 8,16,24,32,40,48,56,64 - ra_ContentionResolutionTimer = 7; - rsrp_ThresholdSSB = 19; -#prach-RootSequenceIndex_PR -#1 = 839, 2 = 139 - prach_RootSequenceIndex_PR = 2; - prach_RootSequenceIndex = 1; - # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex - # - msg1_SubcarrierSpacing = 1, -# restrictedSetConfig -# 0=unrestricted, 1=restricted type A, 2=restricted type B - restrictedSetConfig = 0, - - msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; - -# pucch-ConfigCommon setup : -# pucchGroupHopping -# 0 = neither, 1= group hopping, 2=sequence hopping - pucchGroupHopping = 0; - hoppingId = 40; - p0_nominal = -70; -# ssb_PositionsInBurs_BitmapPR -# 1=short, 2=medium, 3=long - ssb_PositionsInBurst_PR = 2; - ssb_PositionsInBurst_Bitmap = 1; - -# ssb_periodicityServingCell -# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 - ssb_periodicityServingCell = 2; - -# dmrs_TypeA_position -# 0 = pos2, 1 = pos3 - dmrs_TypeA_Position = 0; - -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - subcarrierSpacing = 1; - - - #tdd-UL-DL-ConfigurationCommon -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - referenceSubcarrierSpacing = 1; - # pattern1 - # dl_UL_TransmissionPeriodicity - # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 6; - nrofDownlinkSlots = 7; - nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; - nrofUplinkSymbols = 4; - - ssPBCH_BlockPower = -25; - } - - ); - - -# Dedicated Serving Cell Configuration -servingCellConfigDedicated = ({ - # BWP-Downlink - # BWP 1 Configuration - dl_bwp-Id_1 = 1; - dl_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp1_subcarrierSpacing = 1; - - firstActiveDownlinkBWP-Id = 1; #BWP-Id - defaultDownlinkBWP-Id = 1; #BWP-Id - - # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, - # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, - # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, - # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } - - # UplinkConfig - # BWP-Uplink - # BWP 1 Configuration - ul_bwp-Id_1 = 1; - ul_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp1_subcarrierSpacing = 1; - - firstActiveUplinkBWP-Id = 1; #BWP-Id - } -); - - - - # ------- SCTP definitions - SCTP : - { - # Number of streams to use in input/output - SCTP_INSTREAMS = 2; - SCTP_OUTSTREAMS = 2; - }; - - - ////////// AMF parameters: - amf_ip_address = ( { ipv4 = "192.168.70.132"; - ipv6 = "192:168:30::17"; - active = "yes"; - preference = "ipv4"; - } - ); - - - NETWORK_INTERFACES : - { - GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; - GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; - GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; - GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; - GNB_PORT_FOR_S1U = 2152; # Spec 2152 - }; - - } -); - -MACRLCs = ( -{ - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 150; - pucch_TargetSNRx10 = 200; - pusch_FailureThres = 1000; - ulsch_max_frame_inactivity = 0; -} -); - -L1s = ( -{ - num_cc = 1; - tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; - pucch0_dtx_threshold = 80; -} -); - -RUs = ( -{ - local_rf = "yes" - nb_tx = 2; - nb_rx = 2; - att_tx = 0; - att_rx = 0; - bands = [78]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 75; - eNB_instances = [0]; - ##beamforming 1x2 matrix: 1 layer x 2 antennas - bf_weights = [0x00007fff, 0x0000]; - #clock_src = "internal"; - sdr_addrs = "mgmt_addr=192.168.10.2,addr=192.168.10.2,clock_source=internal,time_source=internal" -} -); - -THREAD_STRUCT = ( -{ - #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_SINGLE_THREAD"; - #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" - worker_config = "WORKER_ENABLE"; -} -); - -rfsimulator : -{ - serveraddr = "server"; - serverport = "4043"; - options = (); #("saviq"); or/and "chanmod" - modelname = "AWGN"; - IQfile = "/tmp/rfsimulator.iqs"; -}; - -security = { - # preferred ciphering algorithms - # the first one of the list that an UE supports in chosen - # valid values: nea0, nea1, nea2, nea3 - ciphering_algorithms = ( "nea0" ); - - # preferred integrity algorithms - # the first one of the list that an UE supports in chosen - # valid values: nia0, nia1, nia2, nia3 - integrity_algorithms = ( "nia2", "nia0" ); - - # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter - # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' - drb_ciphering = "yes"; - drb_integrity = "no"; -}; - -log_config : -{ - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="info"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - ngap_log_level ="debug"; - f1ap_log_level ="debug"; -};