Merge branch 'integration_2026_w11' into 'develop'
Integration `2026.w11` * !3864 remove xran_fh_tx_send_slot_BySymbol() and xran_fh_rx_read_slot_BySymbol() * !3967 Harmonize the use of definition for number of symbols per slot * !3971 Limit dl_DataToUL_ACK values to 15 as per standard * !3414 Added NTN-FR2 FDD bands defined in release 18 in Ka-band range * !3919 Reduce number of mutex locking in MAC->RLC direction * !3923 XNAP: Add encode/decode and unit tests for Xn Setup Request/Response/Failure * !3965 Enable BladeRF support in gNB Docker image * !3904 add multi-ue support to vrtsim * !3980 SDR reordering: correct warning, and USRP: return samples written * !3834 Use flat buffer for txdataF in gNB L1 * !3981 Bugfix: make longer telnet cmdfunc names * Reduce timing reference value for feptx_total in 40 MHz phytest See merge request oai/openairinterface5g!3976
This commit is contained in:
@@ -517,6 +517,17 @@ add_library(x2ap
|
||||
target_link_libraries(x2ap PUBLIC asn1_x2ap)
|
||||
target_link_libraries(x2ap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
#XNAP
|
||||
##############
|
||||
set(XNAP_DIR ${OPENAIR2_DIR}/XNAP)
|
||||
add_library(xnap
|
||||
${XNAP_DIR}/xnap_common.c
|
||||
)
|
||||
target_include_directories(xnap PUBLIC XNAP_DIR)
|
||||
target_link_libraries(xnap PUBLIC asn1_xnap)
|
||||
target_link_libraries(xnap PRIVATE nr_rrc xnap_lib)
|
||||
target_include_directories(xnap PRIVATE ${XNAP_DIR}/lib)
|
||||
|
||||
# F1AP
|
||||
##############
|
||||
set(F1AP_DIR ${OPENAIR2_DIR}/F1AP)
|
||||
|
||||
@@ -20,7 +20,7 @@ Ref :
|
||||
Slot Indication : 5.0
|
||||
feprx : 43.0
|
||||
feptx_ofdm (per port, half_slot) : 30
|
||||
feptx_total : 57
|
||||
feptx_total : 43
|
||||
DeviationThreshold :
|
||||
feprx : 0.25
|
||||
feptx_prec : 0.25
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>vrtsim-5gnr-multiue-gh</htmlTabRef>
|
||||
<htmlTabName>Multi-UE gNB vrtsim + CIRDB</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
|
||||
<testCase>
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<node>localhost</node>
|
||||
<images>oai-gnb oai-nr-ue</images>
|
||||
<tag_prefix>arm_</tag_prefix>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<node>localhost</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI 5G CoreNetwork</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_multiue</yaml_path>
|
||||
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI 5G gNB+UE RF sim SA</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_multiue</yaml_path>
|
||||
<services>oai-gnb oai-nr-ue0 oai-nr-ue1</services>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach OAI UE 1 (Wait for IP)</desc>
|
||||
<id>rfsim5g_ue</id>
|
||||
<node>localhost</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach OAI UE 2 (Wait for IP)</desc>
|
||||
<id>rfsim5g_ue2</id>
|
||||
<node>localhost</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<id>rfsim5g_ue</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<id>rfsim5g_ext_dn</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ue</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>Iperf UE 1 (DL/3Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 3M -t 30 -R</iperf_args>
|
||||
<id>rfsim5g_ue</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>Iperf UE 1 (UL/1Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 1M -t 30</iperf_args>
|
||||
<id>rfsim5g_ue</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from UE 2</desc>
|
||||
<id>rfsim5g_ue2</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping UE 2 from ext-dn</desc>
|
||||
<id>rfsim5g_ext_dn</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ue2</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<ping_args>-c 20 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>Iperf UE 2 (DL/3Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 3M -t 30 -R</iperf_args>
|
||||
<id>rfsim5g_ue2</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>Iperf UE 2 (UL/1Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 1M -t 30</iperf_args>
|
||||
<id>rfsim5g_ue2</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_multiue</yaml_path>
|
||||
<analysis>
|
||||
<services>oai-gnb=EndsWithBye oai-nr-ue0 oai-nr-ue1</services>
|
||||
</analysis>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<node>localhost</node>
|
||||
<images>oai-gnb oai-nr-ue</images>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -0,0 +1,212 @@
|
||||
services:
|
||||
# CIR Generator service - generates CIRDB files on every CI run
|
||||
cir-generator:
|
||||
image: oaisoftwarealliance/cir-generator:test
|
||||
environment:
|
||||
GENERATOR_ARGS: "--demo"
|
||||
OUTPUT: "--out /opt/output/cir_db.bin"
|
||||
volumes:
|
||||
- cirdb_data:/opt/output
|
||||
|
||||
mysql:
|
||||
container_name: "rfsim5g-mysql"
|
||||
image: mysql:8.0
|
||||
init: true
|
||||
volumes:
|
||||
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
||||
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- MYSQL_DATABASE=oai_db
|
||||
- MYSQL_USER=test
|
||||
- MYSQL_PASSWORD=test
|
||||
- MYSQL_ROOT_PASSWORD=linux
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
retries: 30
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.131
|
||||
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.132
|
||||
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.1.10
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-amf
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.133
|
||||
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.1.10
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-smf
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
cap_drop:
|
||||
- ALL
|
||||
privileged: true
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.134
|
||||
interface_name: eth0
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.134
|
||||
interface_name: eth1
|
||||
|
||||
oai-ext-dn:
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-ext-dn
|
||||
image: oaisoftwarealliance/trf-gen-cn5g:latest
|
||||
init: true
|
||||
entrypoint: /bin/bash -c \
|
||||
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
|
||||
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
|
||||
depends_on:
|
||||
- oai-upf
|
||||
networks:
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.135
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ping -c 2 192.168.72.134"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-gnb
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.num_ues 2 --vrtsim.cirdb 1 --vrtsim.cirdb_file /cirdb/cir_db.bin --vrtsim.cirdb_yaml /cirdb/cir_db.yaml --vrtsim.ue_config.[0].antennas 1x2 --vrtsim.ue_config.[0].model_id 0 --vrtsim.ue_config.[0].ds_ns 10.0 --vrtsim.ue_config.[0].speed_mps 1.5 --vrtsim.ue_config.[1].antennas 2x2 --vrtsim.ue_config.[1].model_id 1 --vrtsim.ue_config.[1].ds_ns 10.0 --vrtsim.ue_config.[1].speed_mps 1.5 --gNBs.[0].min_rxtxtime 8
|
||||
depends_on:
|
||||
cir-generator:
|
||||
condition: service_completed_successfully
|
||||
oai-ext-dn:
|
||||
condition: service_started
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band78.106prb.vrtsim.2x2.yaml:/opt/oai-gnb/etc/gnb.yaml
|
||||
- cirdb_data:/cirdb:ro
|
||||
- tmp_data:/tmp/
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
retries: 5
|
||||
ipc: host
|
||||
|
||||
oai-nr-ue0:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-nr-ue
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3319680000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --vrtsim.ue_id 0 --ue-nb-ant-tx 1 --ue-nb-ant-rx 2
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.150
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
volumes:
|
||||
- ../../conf_files/nrue.vrtsim.chanmod.yaml:/opt/oai-nr-ue/etc/nr-ue.yaml
|
||||
- tmp_data:/tmp/
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
ipc: host
|
||||
|
||||
oai-nr-ue1:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-nr-ue2
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3319680000 --ssb 516 --uicc0.imsi 208990100001101 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --vrtsim.ue_id 1 --ue-nb-ant-tx 2 --ue-nb-ant-rx 2
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.151
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
volumes:
|
||||
- ../../conf_files/nrue.vrtsim.chanmod.yaml:/opt/oai-nr-ue/etc/nr-ue.yaml
|
||||
- tmp_data:/tmp/
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
ipc: host
|
||||
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-public-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-public"
|
||||
traffic_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-traffic-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-traffic"
|
||||
|
||||
volumes:
|
||||
tmp_data:
|
||||
cirdb_data:
|
||||
@@ -325,7 +325,7 @@ install_bladerf_driver_from_source(){
|
||||
rm -rf /tmp/bladeRF
|
||||
git clone https://github.com/Nuand/bladeRF.git
|
||||
cd bladeRF
|
||||
git checkout tags/2016.06
|
||||
git checkout tags/2025.10
|
||||
mkdir -p build
|
||||
cd build
|
||||
$CMAKE ../
|
||||
@@ -337,14 +337,12 @@ install_bladerf_driver_from_source(){
|
||||
|
||||
check_install_bladerf_driver(){
|
||||
if [[ "$OS_BASEDISTRO" == "debian" ]]; then
|
||||
$SUDO apt-get install -y bladerf libbladerf-dev
|
||||
$SUDO apt-get install -y bladerf-firmware-fx3
|
||||
$SUDO apt-get install -y bladerf-fpga-hostedx40
|
||||
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
|
||||
install_bladerf_driver_from_source
|
||||
else
|
||||
echo_error "BladeRF Installer for OAI does not support automatic build. Install BladeRF compiling sources manually from BladeRF website"
|
||||
fi
|
||||
$SUDO apt-get update
|
||||
$SUDO apt-get install -y libcurl4-openssl-dev
|
||||
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
|
||||
$SUDO dnf -y install libcurl-devel
|
||||
fi
|
||||
install_bladerf_driver_from_source
|
||||
}
|
||||
|
||||
check_install_lmssdr_driver(){
|
||||
@@ -358,8 +356,6 @@ check_install_lmssdr_driver(){
|
||||
echo_info "https://wiki.myriadrf.org/Lime_Suite"
|
||||
echo_fatal "Cannot compile lmssdr device"
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
install_soapy_from_source(){
|
||||
|
||||
@@ -162,6 +162,7 @@ static const char *const flag_name[] = {FOREACH_FLAG(FLAG_TEXT) ""};
|
||||
COMP_DEF(USIM, log) \
|
||||
COMP_DEF(F1U, ) \
|
||||
COMP_DEF(X2AP, ) \
|
||||
COMP_DEF(XNAP, ) \
|
||||
COMP_DEF(M2AP, ) \
|
||||
COMP_DEF(M3AP, ) \
|
||||
COMP_DEF(NGAP, ) \
|
||||
|
||||
@@ -628,6 +628,27 @@ ID = LEGACY_X2AP_TRACE
|
||||
GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_TRACE:LEGACY
|
||||
FORMAT = string,log
|
||||
|
||||
ID = LEGACY_XNAP_INFO
|
||||
DESC = XNAP legacy logs - info level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_INFO:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_ERROR
|
||||
DESC = XNAP legacy logs - error level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_ERROR:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_WARNING
|
||||
DESC = XNAP legacy logs - warning level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_WARNING:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_DEBUG
|
||||
DESC = XNAP legacy logs - debug level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_DEBUG:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_TRACE
|
||||
DESC = XNAP legacy logs - trace level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_TRACE:LEGACY
|
||||
FORMAT = string,log
|
||||
|
||||
ID = LEGACY_M2AP_INFO
|
||||
DESC = M2AP legacy logs - info level
|
||||
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_INFO:LEGACY
|
||||
|
||||
+125
-127
@@ -178,92 +178,97 @@ uint8_t set_ssb_case(int scs, int nr_band)
|
||||
return ssb_case;
|
||||
}
|
||||
|
||||
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) (Rel.17)
|
||||
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) (Rel.18)
|
||||
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
|
||||
// Notes:
|
||||
// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
|
||||
// - Frequencies are expressed in KHz
|
||||
// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster
|
||||
const nr_bandentry_t nr_bandtable[] = {{1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
|
||||
{2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
|
||||
{3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100},
|
||||
{5, 824000, 849000, 869000, 894000, 20, 173800, 100},
|
||||
{7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
|
||||
{8, 880000, 915000, 925000, 960000, 20, 185000, 100},
|
||||
{12, 699000, 716000, 729000, 746000, 20, 145800, 100},
|
||||
{13, 777000, 787000, 746000, 756000, 20, 149200, 100},
|
||||
{14, 788000, 798000, 758000, 768000, 20, 151600, 100},
|
||||
{18, 815000, 830000, 860000, 875000, 20, 172000, 100},
|
||||
{20, 832000, 862000, 791000, 821000, 20, 158200, 100},
|
||||
{24, 1627500, 1656500, 1526000, 1536000, 20, 305000, 100},
|
||||
{25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
|
||||
{26, 814000, 849000, 859000, 894000, 20, 171800, 100},
|
||||
{28, 703000, 758000, 758000, 813000, 20, 151600, 100},
|
||||
{29, 000, 000, 717000, 728000, 20, 143400, 100},
|
||||
{30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
|
||||
{34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
|
||||
{38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
|
||||
{39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
|
||||
{40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
|
||||
{41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
|
||||
{41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
|
||||
{46, 5150000, 5925000, 5150000, 5925000, 1, 743334, 15},
|
||||
{47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15},
|
||||
{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15},
|
||||
{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30},
|
||||
{50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
|
||||
{51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
|
||||
{53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
|
||||
{65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
|
||||
{66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
|
||||
{67, 000, 000, 738000, 758000, 20, 147600, 100},
|
||||
{70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
|
||||
{71, 663000, 698000, 617000, 652000, 20, 123400, 100},
|
||||
{74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100},
|
||||
{75, 000, 000, 1432000, 1517000, 20, 286400, 100},
|
||||
{76, 000, 000, 1427000, 1432000, 20, 285400, 100},
|
||||
{77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15},
|
||||
{77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30},
|
||||
{78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15},
|
||||
{78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30},
|
||||
{79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15},
|
||||
{79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30},
|
||||
{80, 1710000, 1785000, 000, 000, 20, 342000, 100},
|
||||
{81, 880000, 915000, 000, 000, 20, 176000, 100},
|
||||
{82, 832000, 862000, 000, 000, 20, 166400, 100},
|
||||
{83, 703000, 748000, 000, 000, 20, 140600, 100},
|
||||
{84, 1920000, 1980000, 000, 000, 20, 384000, 100},
|
||||
{85, 698000, 716000, 728000, 746000, 20, 145600, 100},
|
||||
{86, 1710000, 1785000, 000, 000, 20, 342000, 100},
|
||||
{89, 824000, 849000, 000, 000, 20, 342000, 100},
|
||||
{90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
|
||||
{90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
|
||||
{90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
|
||||
{91, 832000, 862000, 1427000, 1432000, 20, 285400, 100},
|
||||
{92, 832000, 862000, 1432000, 1517000, 20, 286400, 100},
|
||||
{93, 880000, 915000, 1427000, 1432000, 20, 285400, 100},
|
||||
{94, 880000, 915000, 1432000, 1517000, 20, 286400, 100},
|
||||
{95, 2010000, 2025000, 000, 000, 20, 402000, 100},
|
||||
{96, 5925000, 7125000, 5925000, 7125000, 1, 795000, 15},
|
||||
{100, 874400, 880000, 919400, 925000, 20, 174880, 100},
|
||||
{101, 1900000, 1910000, 1900000, 1910000, 20, 380000, 100},
|
||||
{102, 5925000, 6425000, 5925000, 6425000, 1, 795000, 15},
|
||||
{104, 6425000, 7125000, 6425000, 7125000, 1, 828334, 15},
|
||||
{104, 6425000, 7125000, 6425000, 7125000, 2, 828334, 30},
|
||||
{254, 1610000, 1626500, 2483500, 2500000, 20, 496700, 100},
|
||||
{254, 1610000, 1626500, 2483500, 2500000, 2, 496700, 10},
|
||||
{255, 1626500, 1660500, 1525000, 1559000, 20, 305000, 100},
|
||||
{255, 1626500, 1660500, 1525000, 1559000, 2, 305000, 10},
|
||||
{256, 1980000, 2010000, 2170000, 2200000, 20, 434000, 100},
|
||||
{256, 1980000, 2010000, 2170000, 2200000, 2, 434000, 10},
|
||||
{257, 26500020, 29500000, 26500020, 29500000, 1, 2054166, 60},
|
||||
{257, 26500080, 29500000, 26500080, 29500000, 2, 2054167, 120},
|
||||
{258, 24250080, 27500000, 24250080, 27500000, 1, 2016667, 60},
|
||||
{258, 24250080, 27500000, 24250080, 27500000, 2, 2016667, 120},
|
||||
{260, 37000020, 40000000, 37000020, 40000000, 1, 2229166, 60},
|
||||
{260, 37000080, 40000000, 37000080, 40000000, 2, 2229167, 120},
|
||||
{261, 27500040, 28350000, 27500040, 28350000, 1, 2070833, 60},
|
||||
{261, 27500040, 28350000, 27500040, 28350000, 2, 2070833, 120}};
|
||||
// - col: NR_band ul_min ul_max dl_min dl_max ul_stepsize dl_stepsize N_OFFs_UL N_OFFs_DL deltaf_raster
|
||||
const nr_bandentry_t nr_bandtable[] = {{1, 1920000, 1980000, 2110000, 2170000, 20, 20, 384000, 422000, 100},
|
||||
{2, 1850000, 1910000, 1930000, 1990000, 20, 20, 370000, 386000, 100},
|
||||
{3, 1710000, 1785000, 1805000, 1880000, 20, 20, 342000, 361000, 100},
|
||||
{5, 824000, 849000, 869000, 894000, 20, 20, 164800, 173800, 100},
|
||||
{7, 2500000, 2570000, 2620000, 2690000, 20, 20, 500000, 524000, 100},
|
||||
{8, 880000, 915000, 925000, 960000, 20, 20, 176000, 185000, 100},
|
||||
{12, 699000, 716000, 729000, 746000, 20, 20, 139800, 145800, 100},
|
||||
{13, 777000, 787000, 746000, 756000, 20, 20, 155400, 149200, 100},
|
||||
{14, 788000, 798000, 758000, 768000, 20, 20, 157600, 151600, 100},
|
||||
{18, 815000, 830000, 860000, 875000, 20, 20, 163000, 172000, 100},
|
||||
{20, 832000, 862000, 791000, 821000, 20, 20, 166400, 158200, 100},
|
||||
{24, 1626500, 1660500, 1525000, 1559000, 20, 20, 325300, 305000, 100},
|
||||
{25, 1850000, 1915000, 1930000, 1995000, 20, 20, 370000, 386000, 100},
|
||||
{26, 814000, 849000, 859000, 894000, 20, 20, 162800, 171800, 100},
|
||||
{28, 703000, 748000, 758000, 803000, 20, 20, 140600, 151600, 100},
|
||||
{29, 000, 000, 717000, 728000, 0, 20, 0, 143400, 100},
|
||||
{30, 2305000, 2315000, 2350000, 2360000, 20, 20, 461000, 470000, 100},
|
||||
{34, 2010000, 2025000, 2010000, 2025000, 20, 20, 402000, 402000, 100},
|
||||
{38, 2570000, 2620000, 2570000, 2620000, 20, 20, 514000, 514000, 100},
|
||||
{39, 1880000, 1920000, 1880000, 1920000, 20, 20, 376000, 376000, 100},
|
||||
{40, 2300000, 2400000, 2300000, 2400000, 20, 20, 460000, 460000, 100},
|
||||
{41, 2496000, 2690000, 2496000, 2690000, 3, 3, 499200, 499200, 15},
|
||||
{41, 2496000, 2690000, 2496000, 2690000, 6, 6, 499200, 499200, 30},
|
||||
{46, 5150000, 5925000, 5150000, 5925000, 1, 1, 743334, 743334, 15},
|
||||
{47, 5855000, 5925000, 5855000, 5925000, 1, 1, 790334, 790334, 15},
|
||||
{48, 3550000, 3700000, 3550000, 3700000, 1, 1, 636667, 636667, 15},
|
||||
{48, 3550000, 3700000, 3550000, 3700000, 2, 2, 636668, 636668, 30},
|
||||
{50, 1432000, 1517000, 1432000, 1517000, 20, 20, 286400, 286400, 100},
|
||||
{51, 1427000, 1432000, 1427000, 1432000, 20, 20, 285400, 285400, 100},
|
||||
{53, 2483500, 2495000, 2483500, 2495000, 20, 20, 496700, 496700, 100},
|
||||
{65, 1920000, 2010000, 2110000, 2200000, 20, 20, 384000, 422000, 100},
|
||||
{66, 1710000, 1780000, 2110000, 2200000, 20, 20, 342000, 422000, 100},
|
||||
{67, 000, 000, 738000, 758000, 0, 20, 0, 147600, 100},
|
||||
{70, 1695000, 1710000, 1995000, 2020000, 20, 20, 339000, 399000, 100},
|
||||
{71, 663000, 698000, 617000, 652000, 20, 20, 132600, 123400, 100},
|
||||
{74, 1427000, 1470000, 1475000, 1518000, 20, 20, 285400, 295000, 100},
|
||||
{75, 000, 000, 1432000, 1517000, 0, 20, 0, 286400, 100},
|
||||
{76, 000, 000, 1427000, 1432000, 0, 20, 0, 285400, 100},
|
||||
{77, 3300000, 4200000, 3300000, 4200000, 1, 1, 620000, 620000, 15},
|
||||
{77, 3300000, 4200000, 3300000, 4200000, 2, 2, 620000, 620000, 30},
|
||||
{78, 3300000, 3800000, 3300000, 3800000, 1, 1, 620000, 620000, 15},
|
||||
{78, 3300000, 3800000, 3300000, 3800000, 2, 2, 620000, 620000, 30},
|
||||
{79, 4400000, 5000000, 4400000, 5000000, 1, 1, 693334, 693334, 15},
|
||||
{79, 4400000, 5000000, 4400000, 5000000, 2, 2, 693334, 693334, 30},
|
||||
{80, 1710000, 1785000, 000, 000, 20, 0, 342000, 0, 100},
|
||||
{81, 880000, 915000, 000, 000, 20, 0, 176000, 0, 100},
|
||||
{82, 832000, 862000, 000, 000, 20, 0, 166400, 0, 100},
|
||||
{83, 703000, 748000, 000, 000, 20, 0, 140600, 0, 100},
|
||||
{84, 1920000, 1980000, 000, 000, 20, 0, 384000, 0, 100},
|
||||
{85, 698000, 716000, 728000, 746000, 20, 20, 139600, 145600, 100},
|
||||
{86, 1710000, 1780000, 000, 000, 20, 0, 342000, 0, 100},
|
||||
{89, 824000, 849000, 000, 000, 20, 0, 342000, 0, 100},
|
||||
{90, 2496000, 2690000, 2496000, 2690000, 3, 3, 499200, 499200, 15},
|
||||
{90, 2496000, 2690000, 2496000, 2690000, 6, 6, 499200, 499200, 30},
|
||||
{90, 2496000, 2690000, 2496000, 2690000, 20, 20, 499200, 499200, 100},
|
||||
{91, 832000, 862000, 1427000, 1432000, 20, 20, 166400, 285400, 100},
|
||||
{92, 832000, 862000, 1432000, 1517000, 20, 20, 166400, 286400, 100},
|
||||
{93, 880000, 915000, 1427000, 1432000, 20, 20, 176000, 285400, 100},
|
||||
{94, 880000, 915000, 1432000, 1517000, 20, 20, 176000, 286400, 100},
|
||||
{95, 2010000, 2025000, 000, 000, 20, 20, 402000, 402000, 100},
|
||||
{96, 5925000, 7125000, 5925000, 7125000, 1, 1, 795000, 795000, 15},
|
||||
{100, 874400, 880000, 919400, 925000, 20, 20, 174880, 174880, 100},
|
||||
{101, 1900000, 1910000, 1900000, 1910000, 20, 20, 380000, 380000, 100},
|
||||
{102, 5925000, 6425000, 5925000, 6425000, 1, 1, 795000, 795000, 15},
|
||||
{104, 6425000, 7125000, 6425000, 7125000, 1, 1, 828334, 828334, 15},
|
||||
{104, 6425000, 7125000, 6425000, 7125000, 2, 2, 828334, 828334, 30},
|
||||
{254, 1610000, 1626500, 2483500, 2500000, 20, 20, 322000, 496700, 100},
|
||||
{254, 1610000, 1626500, 2483500, 2500000, 2, 2, 322000, 496700, 10},
|
||||
{255, 1626500, 1660500, 1525000, 1559000, 20, 20, 325300, 305000, 100},
|
||||
{255, 1626500, 1660500, 1525000, 1559000, 2, 2, 325300, 305000, 10},
|
||||
{256, 1980000, 2010000, 2170000, 2200000, 20, 20, 396000, 434000, 100},
|
||||
{256, 1980000, 2010000, 2170000, 2200000, 2, 2, 396000, 434000, 10},
|
||||
{257, 26500020, 29500000, 26500020, 29500000, 1, 1, 2054166, 2054166, 60},
|
||||
{257, 26500080, 29500000, 26500080, 29500000, 2, 2, 2054167, 2054167, 120},
|
||||
{258, 24250080, 27500000, 24250080, 27500000, 1, 1, 2016667, 2016667, 60},
|
||||
{258, 24250080, 27500000, 24250080, 27500000, 2, 2, 2016667, 2016667, 120},
|
||||
{260, 37000020, 40000000, 37000020, 40000000, 1, 1, 2229166, 2229166, 60},
|
||||
{260, 37000080, 40000000, 37000080, 40000000, 2, 2, 2229167, 2229167, 120},
|
||||
{261, 27500040, 28350000, 27500040, 28350000, 1, 1, 2070833, 2070833, 60},
|
||||
{261, 27500040, 28350000, 27500040, 28350000, 2, 2, 2070833, 2070833, 120},
|
||||
{510, 27500000, 28350000, 17300000, 20200000, 1, 4, 2070833, 1553336, 60},
|
||||
{510, 27500000, 28350000, 17300000, 20200000, 2, 8, 2070833, 1553336, 120},
|
||||
{511, 28350000, 30000000, 17300000, 20200000, 1, 4, 2084999, 1553336, 60},
|
||||
{511, 28350000, 30000000, 17300000, 20200000, 2, 8, 2084999, 1553336, 120},
|
||||
{512, 27500000, 30000000, 17300000, 20200000, 1, 4, 2070833, 1553336, 60},
|
||||
{512, 27500000, 30000000, 17300000, 20200000, 2, 8, 2070833, 1553336, 120}};
|
||||
|
||||
// synchronization raster per band tables (Rel.17)
|
||||
// (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1)
|
||||
@@ -341,6 +346,13 @@ const sync_raster_t sync_raster[] = {
|
||||
{260, 4, 22996, 2, 23164},
|
||||
{261, 3, 22446, 1, 22492},
|
||||
{261, 4, 22446, 2, 22490},
|
||||
{510, 3, 17448, 12, 19428},
|
||||
{510, 4, 17472, 24, 19416},
|
||||
{511, 3, 17448, 12, 19428},
|
||||
{511, 4, 17472, 24, 19416},
|
||||
{512, 3, 17448, 12, 19428},
|
||||
{512, 4, 17472, 24, 19416},
|
||||
/***************************/
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -542,14 +554,6 @@ int get_nb_periods_per_frame(uint8_t tdd_period)
|
||||
return nb_periods_per_frame;
|
||||
}
|
||||
|
||||
void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs)
|
||||
{
|
||||
uint32_t delta_arfcn = nrarfcn - N_OFFs;
|
||||
|
||||
if(delta_arfcn % (nr_bandtable[i].step_size) != 0)
|
||||
LOG_E(NR_MAC, "nrarfcn %u is not on the channel raster for step size %lu\n", nrarfcn, nr_bandtable[i].step_size);
|
||||
}
|
||||
|
||||
uint32_t to_nrarfcn(uint64_t CarrierFreq)
|
||||
{
|
||||
uint64_t CarrierFreq_by_1k = CarrierFreq / 1000;
|
||||
@@ -580,7 +584,6 @@ uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t nrarfcn)
|
||||
int deltaFglobal = 5;
|
||||
uint32_t N_REF_Offs = 0;
|
||||
uint64_t F_REF_Offs_khz = 0;
|
||||
uint64_t N_OFFs, frequency, freq_min;
|
||||
int i = get_nr_table_idx(nr_bandP, scs_index);
|
||||
|
||||
if (nrarfcn > 599999 && nrarfcn < 2016667) {
|
||||
@@ -594,42 +597,30 @@ uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t nrarfcn)
|
||||
F_REF_Offs_khz = 24250080;
|
||||
}
|
||||
|
||||
int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index);
|
||||
// First check if the ARFCN is on the RASTER
|
||||
uint32_t stepsize = nr_bandtable[i].dl_stepsize;
|
||||
uint32_t N_OFFs = nr_bandtable[i].N_OFFs_DL;
|
||||
|
||||
if (delta_duplex <= 0){ // DL band >= UL band
|
||||
if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL
|
||||
N_OFFs = nr_bandtable[i].N_OFFs_DL;
|
||||
freq_min = nr_bandtable[i].dl_min;
|
||||
} else {// is FDD UL
|
||||
N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal;
|
||||
freq_min = nr_bandtable[i].ul_min;
|
||||
}
|
||||
} else { // UL band > DL band
|
||||
if (nrarfcn >= nr_bandtable[i].N_OFFs_DL + delta_duplex / deltaFglobal){ // is FDD UL
|
||||
N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex / deltaFglobal;
|
||||
freq_min = nr_bandtable[i].ul_min;
|
||||
} else { // is FDD DL
|
||||
N_OFFs = nr_bandtable[i].N_OFFs_DL;
|
||||
freq_min = nr_bandtable[i].dl_min;
|
||||
if (nrarfcn >= nr_bandtable[i].N_OFFs_UL) {
|
||||
if (nr_bandtable[i].N_OFFs_UL > N_OFFs || nrarfcn < N_OFFs) {
|
||||
N_OFFs = nr_bandtable[i].N_OFFs_UL;
|
||||
stepsize = nr_bandtable[i].ul_stepsize;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "Frequency from NR-ARFCN for N_OFFs %lu, duplex spacing %d KHz, deltaFglobal %d KHz\n",
|
||||
N_OFFs,
|
||||
delta_duplex,
|
||||
deltaFglobal);
|
||||
LOG_D(NR_MAC, "N_OFFs %u, deltaFglobal %d KHz, stepsize:%d\n", N_OFFs, deltaFglobal, stepsize);
|
||||
|
||||
AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %llu\n", nrarfcn, nr_bandtable[i].band, (long long unsigned int)N_OFFs);
|
||||
get_delta_arfcn(i, nrarfcn, N_OFFs);
|
||||
AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %u\n", nrarfcn, nr_bandtable[i].band, N_OFFs);
|
||||
|
||||
frequency = 1000 * (F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal);
|
||||
if ((nrarfcn - N_OFFs) % stepsize != 0)
|
||||
LOG_E(NR_MAC, "nrarfcn %u is not on the channel raster for step size %u. N_OFFS:%d\n",
|
||||
nrarfcn, stepsize, N_OFFs);
|
||||
|
||||
LOG_D(NR_MAC, "Computing frequency (nrarfcn %llu => %llu KHz (freq_min %llu KHz, NR band %d N_OFFs %llu))\n",
|
||||
uint64_t frequency = 1000 * (F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal);
|
||||
LOG_I(NR_MAC, "Computing frequency (nrarfcn %llu => %llu KHz, NR band %d\n",
|
||||
(unsigned long long)nrarfcn,
|
||||
(unsigned long long)frequency/1000,
|
||||
(unsigned long long)freq_min,
|
||||
nr_bandP,
|
||||
(unsigned long long)N_OFFs);
|
||||
nr_bandP);
|
||||
|
||||
return frequency;
|
||||
}
|
||||
@@ -1049,12 +1040,13 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
|
||||
// only difference wrt NR-ARFCN is delta frequency 5kHz if f < 3 GHz for ARFCN
|
||||
uint32_t absolute_diff = (absoluteFrequencySSB - absoluteFrequencyPointA);
|
||||
const int scaling_5khz = absoluteFrequencyPointA < 600000 ? 3 : 1;
|
||||
const int scaling = frequency_range == FR2 ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing;
|
||||
const int scaling = (absoluteFrequencyPointA >= 2016667) ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing;
|
||||
const int scaled_abs_diff = absolute_diff / (scaling_5khz * scaling);
|
||||
// absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total
|
||||
const int ssb_offset_point_a = ((scaled_abs_diff / 12) - 10) * scaling;
|
||||
const int ssb_offset_scaling = (frequency_range == FR2) ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing;
|
||||
const int ssb_offset_point_a = ((scaled_abs_diff / 12) - 10) * ssb_offset_scaling;
|
||||
// Offset to point A needs to be divisible by scaling
|
||||
AssertFatal(ssb_offset_point_a % scaling == 0, "PRB offset %d not valid for scs %d\n", ssb_offset_point_a, ssbSubcarrierSpacing);
|
||||
AssertFatal(ssb_offset_point_a % ssb_offset_scaling == 0, "PRB offset %d not valid for scs %d\n", ssb_offset_point_a, ssbSubcarrierSpacing);
|
||||
AssertFatal(ssb_offset_point_a >= 0, "ssb offset is negative %d for scs %d\n", ssb_offset_point_a, ssbSubcarrierSpacing);
|
||||
return ssb_offset_point_a;
|
||||
}
|
||||
@@ -1358,11 +1350,14 @@ long rrc_get_max_nr_csrs(const int max_rbs, const long b_SRS)
|
||||
|
||||
frequency_range_t get_freq_range_from_freq(uint64_t freq)
|
||||
{
|
||||
// 3GPP TS 38.101-1 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
// 3GPP TS 38.101-1,38.101-5 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
if (freq >= 410000000 && freq <= 7125000000)
|
||||
return FR1;
|
||||
|
||||
if (freq >= 24250000000 && freq <= 71000000000)
|
||||
// 3GPP TS 38.101-1 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
// FR2 is from 24250 MHz to 71000 MHz
|
||||
// 3GPP TS 38.101-5 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
// FR2 for NTN is from 17300 Mhz to 30000 MHz
|
||||
if (freq >= 17300000000 && freq <= 71000000000)
|
||||
return FR2;
|
||||
|
||||
AssertFatal(false, "Undefined Frequency Range for frequency %ld Hz\n", freq);
|
||||
@@ -1373,8 +1368,11 @@ frequency_range_t get_freq_range_from_arfcn(uint32_t arfcn)
|
||||
// 3GPP TS 38.101-1 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
if (arfcn >= 82000 && arfcn <= 875000)
|
||||
return FR1;
|
||||
|
||||
if (arfcn >= 2016667 && arfcn <= 2795832)
|
||||
// 3GPP TS 38.101-1 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
// FR2 is from 24250 MHz to 71000 MHz (from ARFCN 2016667)
|
||||
// 3GPP TS 38.101-5 Version 19.0.0 Table 5.1-1: Definition of frequency ranges
|
||||
// FR2 for NTN is from 17300 Mhz to 30000 MHz, from ARFCN 1553336 (Table 5.4.2.3-3)
|
||||
if (arfcn >= 1553336 && arfcn <= 2795832)
|
||||
return FR2;
|
||||
|
||||
AssertFatal(false, "Undefined Frequency Range for ARFCN %d\n", arfcn);
|
||||
|
||||
@@ -84,8 +84,8 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
|
||||
|
||||
#define MU_SCS(m) (15 << m)
|
||||
#define MAX_GSCN_BAND 620 // n78 has the highest GSCN range of 619
|
||||
#define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14
|
||||
#define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12
|
||||
#define NR_SYMBOLS_PER_SLOT 14
|
||||
#define NR_SYMBOLS_PER_SLOT_EXTENDED_CP 12
|
||||
#define NR_MAX_NB_LAYERS 4 // 8
|
||||
#define NR_MAX_CSI_PORTS 12
|
||||
|
||||
@@ -107,8 +107,10 @@ typedef struct nr_bandentry_s {
|
||||
uint64_t ul_max;
|
||||
uint64_t dl_min;
|
||||
uint64_t dl_max;
|
||||
uint64_t step_size;
|
||||
uint64_t N_OFFs_DL;
|
||||
uint8_t ul_stepsize;
|
||||
uint8_t dl_stepsize;
|
||||
uint32_t N_OFFs_UL;
|
||||
uint32_t N_OFFs_DL;
|
||||
uint8_t deltaf_raster;
|
||||
} nr_bandentry_t;
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ int process_command(char *buf, int iteration)
|
||||
}
|
||||
|
||||
rt=CMDSTATUS_NOTFOUND;
|
||||
j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb);
|
||||
j = sscanf(buf,"%19s %63s %m[^\t\n]",modulename,cmd,&cmdb);
|
||||
|
||||
if (telnetparams.telnetdbg > 0)
|
||||
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n", j, modulename, cmd, (cmdb == NULL) ? "" : cmdb);
|
||||
@@ -947,6 +947,12 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
|
||||
telnetparams.CmdParsers[i].cmd = cmd;
|
||||
telnetparams.CmdParsers[i].var = var;
|
||||
for (int j = 0; cmd[j].cmdfunc != NULL; j++) {
|
||||
size_t cmdnamelen = strnlen(cmd[j].cmdname, TELNET_CMD_MAXSIZE);
|
||||
AssertFatal(cmdnamelen < TELNET_CMD_MAXSIZE,
|
||||
"cmdname %s too long: %ld >= %d",
|
||||
cmd[j].cmdname,
|
||||
cmdnamelen,
|
||||
TELNET_CMD_MAXSIZE);
|
||||
if (cmd[j].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
if (afifo == NULL) {
|
||||
afifo = calloc_or_fail(1, sizeof(notifiedFIFO_t));
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
#define TELNET_MAX_MSGLENGTH 2048
|
||||
#define TELNET_PROMPT_PREFIX "softmodem"
|
||||
#define TELNET_MAXCMD 20
|
||||
#define TELNET_CMD_MAXSIZE 20
|
||||
#define TELNET_MAXCMD 64
|
||||
#define TELNET_CMD_MAXSIZE 64
|
||||
#define TELNET_HELPSTR_SIZE 80
|
||||
|
||||
/* status return by the command parser after it analysed user input */
|
||||
|
||||
@@ -83,6 +83,7 @@ COPY --from=gnb-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_bladerfdevif.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
|
||||
@@ -104,6 +105,9 @@ COPY --from=gnb-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-
|
||||
## Copy E2 SM models
|
||||
COPY --from=gnb-build /usr/local/lib/flexric /usr/local/lib/flexric
|
||||
|
||||
# Copy BladeRF runtime from base image
|
||||
COPY --from=gnb-base /usr/local/lib/libbladeRF* /usr/local/lib/
|
||||
|
||||
RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \
|
||||
ldconfig && \
|
||||
echo "---- ldd on nr-softmodem ----" && \
|
||||
@@ -112,6 +116,7 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai
|
||||
ldd /usr/local/lib/liboai_eth_transpro.so \
|
||||
/usr/local/lib/librfsimulator.so \
|
||||
/usr/local/lib/liboai_usrpdevif.so \
|
||||
/usr/local/lib/liboai_bladerfdevif.so \
|
||||
/usr/local/lib/libcoding.so \
|
||||
/usr/local/lib/libparams_libconfig.so \
|
||||
/usr/local/lib/libdfts.so \
|
||||
|
||||
@@ -89,6 +89,7 @@ COPY --from=nr-ue-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/liboai_bladerfdevif.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
|
||||
@@ -112,6 +113,9 @@ COPY --from=nr-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin
|
||||
COPY --from=nr-ue-base /usr/local/lib/libuhd.so.4.8.0 /usr/local/lib
|
||||
COPY --from=nr-ue-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-nr-ue/bin
|
||||
|
||||
# Copy BladeRF runtime from base image
|
||||
COPY --from=nr-ue-base /usr/local/lib/libbladeRF* /usr/local/lib/
|
||||
|
||||
RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \
|
||||
ldconfig && \
|
||||
echo "---- ldd on nr-uesoftmodem ----" && \
|
||||
@@ -120,6 +124,7 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai
|
||||
ldd /usr/local/lib/liboai_eth_transpro.so \
|
||||
/usr/local/lib/librfsimulator.so \
|
||||
/usr/local/lib/liboai_usrpdevif.so \
|
||||
/usr/local/lib/liboai_bladerfdevif.so \
|
||||
/usr/local/lib/libcoding.so \
|
||||
/usr/local/lib/libparams_libconfig.so \
|
||||
/usr/local/lib/libdfts.so \
|
||||
|
||||
@@ -101,7 +101,7 @@ int oai_exit = 0;
|
||||
int NB_UE_INST = 0;
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
int UE_scan = 1;
|
||||
int UE_scan_carrier = 0;
|
||||
|
||||
@@ -114,7 +114,7 @@ extern uint16_t ue_id_g;
|
||||
extern uint16_t node_number;
|
||||
|
||||
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
extern int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
extern int rx_input_level_dBm;
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
@@ -437,8 +437,10 @@ static void *UE_thread_synch(void *arg) {
|
||||
printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min);
|
||||
|
||||
if ((eutra_bands[ind].dl_min <= UE->frame_parms.dl_CarrierFreq) && (eutra_bands[ind].dl_max >= UE->frame_parms.dl_CarrierFreq)) {
|
||||
for (i=0; i<4; i++)
|
||||
uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
|
||||
for (i=0; i<4; i++) {
|
||||
int32_t delta = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
|
||||
uplink_frequency_offset[CC_id][i] = delta;
|
||||
}
|
||||
|
||||
found = 1;
|
||||
break;
|
||||
@@ -473,8 +475,8 @@ static void *UE_thread_synch(void *arg) {
|
||||
|
||||
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
|
||||
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
|
||||
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
|
||||
bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
|
||||
int32_t delta = bands_to_scan.band_info[CC_id].ul_min - bands_to_scan.band_info[CC_id].dl_min;
|
||||
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = delta;
|
||||
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
|
||||
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
|
||||
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
|
||||
@@ -517,7 +519,8 @@ static void *UE_thread_synch(void *arg) {
|
||||
|
||||
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
|
||||
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
|
||||
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
|
||||
int32_t delta = bands_to_scan.band_info[current_band].ul_min - bands_to_scan.band_info[0].dl_min + current_offset;
|
||||
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = delta;
|
||||
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
|
||||
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
|
||||
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
|
||||
|
||||
@@ -92,7 +92,7 @@ unsigned int mmapped_dma=0;
|
||||
UE_MAC_INST *UE_mac_inst = NULL;
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ extern void set_function_spec_param(RU_t *ru);
|
||||
extern void start_NR_RU();
|
||||
extern void init_NR_RU(configmodule_interface_t *cfg, char *);
|
||||
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
void nfapi_setmode(nfapi_mode_t nfapi_mode)
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ extern void init_RU_proc(RU_t *ru);
|
||||
extern void kill_RU_proc(RU_t *ru);
|
||||
extern void set_function_spec_param(RU_t *ru);
|
||||
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
|
||||
void nfapi_setmode(nfapi_mode_t nfapi_mode) { return; }
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
RAN_CONTEXT_t RC;
|
||||
THREAD_STRUCT thread_struct;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int oai_exit = 0;
|
||||
instance_t CUuniqInstance = 0;
|
||||
|
||||
|
||||
+1
-1
@@ -538,7 +538,7 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
if(slot_type == NR_MIXED_SLOT) {
|
||||
int txsymb = 0;
|
||||
|
||||
for(int symbol_count = 0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
for(int symbol_count = 0; symbol_count < fp->symbols_per_slot; symbol_count++) {
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value == 0)
|
||||
txsymb++;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ int oai_exit = 0;
|
||||
unsigned int mmapped_dma=0;
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
char *uecap_file;
|
||||
|
||||
runmode_t mode = normal_txrx;
|
||||
|
||||
+1
-1
@@ -281,7 +281,7 @@ static int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot)
|
||||
if (current_slot->max_num_of_symbol_per_slot_list[0].slot_config == 2)
|
||||
return NR_MIXED_SLOT;
|
||||
|
||||
for (int i = 1; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) {
|
||||
for (int i = 1; i < NR_SYMBOLS_PER_SLOT; i++) {
|
||||
// if the 1st symbol is DL and any other is not, the slot is mixed
|
||||
if (current_slot->max_num_of_symbol_per_slot_list[i].slot_config != 0) {
|
||||
return NR_MIXED_SLOT;
|
||||
|
||||
@@ -103,7 +103,7 @@ RAN_CONTEXT_t RC;
|
||||
int oai_exit = 0;
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
// UE and OAI config variables
|
||||
|
||||
@@ -138,8 +138,8 @@ extern int usrp_tx_thread;
|
||||
{"clock-source", CONFIG_HLP_CLK, 0, .uptr=&CLOCK_SOURCE, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"time-source", CONFIG_HLP_TME, 0, .uptr=&TIMING_SOURCE, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"tune-offset", CONFIG_HLP_TUNE_OFFSET, 0, .dblptr=&TUNE_OFFSET, .defintval=0, TYPE_DOUBLE, 0}, \
|
||||
{"C" , CONFIG_HLP_DLF, 0, .u64ptr=&(downlink_frequency[0][0]), .defint64val=0, TYPE_UINT64, 0}, \
|
||||
{"CO" , CONFIG_HLP_ULF, 0, .iptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT, 0}, \
|
||||
{"C" , CONFIG_HLP_DLF, 0, .u64ptr=&(downlink_frequency[0][0]), .defuintval=0, TYPE_UINT64, 0}, \
|
||||
{"CO" , CONFIG_HLP_ULF, 0, .i64ptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT64, 0}, \
|
||||
{"a" , CONFIG_HLP_CHOFF, 0, .iptr=&CHAIN_OFFSET, .defintval=0, TYPE_INT, 0}, \
|
||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
|
||||
@@ -330,7 +330,7 @@ char *get_softmodem_function(void);
|
||||
#define SOFTMODEM_RTSIGNAL (SIGRTMIN+1)
|
||||
void set_softmodem_sighandler(void);
|
||||
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
extern int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
extern int usrp_tx_thread;
|
||||
extern int sf_ahead;
|
||||
extern int oai_exit;
|
||||
|
||||
@@ -355,7 +355,7 @@ void *epoll_recv_task(void *arg)
|
||||
void create_recv_thread(int8_t affinity)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
threadCreate(&thread_id, epoll_recv_task, NULL, "vnf_nvipc_aerial", affinity, OAI_PRIORITY_RT);
|
||||
threadCreate(&thread_id, epoll_recv_task, NULL, "vnf_nvipc_aerial", affinity, OAI_PRIORITY_RT_MAX);
|
||||
}
|
||||
|
||||
int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport)
|
||||
|
||||
@@ -185,7 +185,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
for (int i = 0; i < common_vars->num_beams_period; i++) {
|
||||
common_vars->txdataF[i] = (c16_t**)malloc16_clear(Ptx * sizeof(c16_t*));
|
||||
for (int j = 0; j < Ptx; j++)
|
||||
common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(c16_t));
|
||||
common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_slot_wCP * sizeof(c16_t));
|
||||
}
|
||||
common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100);
|
||||
common_vars->debugBuff_sample_offset = 0;
|
||||
@@ -435,8 +435,8 @@ void init_nr_transport(PHY_VARS_gNB *gNB)
|
||||
fp->slots_per_frame;
|
||||
int nb_ul_slots_period = 0;
|
||||
if (cfg->cell_config.frame_duplex_type.value) {
|
||||
for(int i=0; i<nb_slots_per_period; i++) {
|
||||
for(int j=0; j<NR_NUMBER_OF_SYMBOLS_PER_SLOT; j++) {
|
||||
for(int i = 0; i < nb_slots_per_period; i++) {
|
||||
for(int j = 0; j < fp->symbols_per_slot; j++) {
|
||||
if(cfg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[j].slot_config.value == 1) { // UL symbol
|
||||
nb_ul_slots_period++;
|
||||
break;
|
||||
|
||||
@@ -97,13 +97,14 @@ void nr_phy_init_RU(RU_t *ru)
|
||||
ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
// [hna] samples_per_frame without CP
|
||||
for(int i = 0; i < ru->nb_tx; ++i)
|
||||
ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
ru->common.txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
|
||||
// allocate IFFT input buffers (TX)
|
||||
ru->common.txdataF_BF = (int32_t **)malloc16(nb_tx_streams * sizeof(int32_t*));
|
||||
LOG_D(PHY, "[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, nb_tx_streams * sizeof(int32_t *));
|
||||
for (int i = 0; i < nb_tx_streams; i++) {
|
||||
ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP * sizeof(int32_t));
|
||||
ru->common.txdataF_BF[i] =
|
||||
(int32_t *)malloc16_clear(fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
LOG_D(PHY, "txdataF_BF[%d] %p for RU %d\n", i, ru->common.txdataF_BF[i], ru->idx);
|
||||
}
|
||||
// allocate FFT output buffers (RX)
|
||||
|
||||
@@ -265,7 +265,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_CSI_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal));
|
||||
for (int i = 0; i < NR_MAX_CSI_PORTS; i++) {
|
||||
ue->nr_csi_info->csi_rs_generated_signal[i] =
|
||||
malloc16_clear(fp->samples_per_frame_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal));
|
||||
malloc16_clear(fp->samples_per_slot_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal));
|
||||
}
|
||||
|
||||
ue->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t));
|
||||
|
||||
@@ -409,7 +409,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf
|
||||
set_scs_parameters(fp, fp->numerology_index, N_RB, config->ssb_table.ssb_case);
|
||||
|
||||
fp->slots_per_frame = 10* fp->slots_per_subframe;
|
||||
fp->symbols_per_slot = ((Ncp == NR_NORMAL)? 14 : 12); // to redefine for different slot formats
|
||||
fp->symbols_per_slot = ((Ncp == NR_NORMAL)? NR_SYMBOLS_PER_SLOT : NR_SYMBOLS_PER_SLOT_EXTENDED_CP);
|
||||
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
|
||||
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
|
||||
fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size;
|
||||
@@ -469,7 +469,7 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_p
|
||||
set_Lmax(frame_parms);
|
||||
|
||||
frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe;
|
||||
frame_parms->symbols_per_slot = ((frame_parms->Ncp == NR_NORMAL)? 14 : 12); // to redefine for different slot formats
|
||||
frame_parms->symbols_per_slot = ((frame_parms->Ncp == NR_NORMAL)? NR_SYMBOLS_PER_SLOT : NR_SYMBOLS_PER_SLOT_EXTENDED_CP);
|
||||
frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe;
|
||||
frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP;
|
||||
frame_parms->samples_per_slot_wCP = frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
|
||||
@@ -570,7 +570,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
|
||||
sl_set_scs_parameters(fp, fp->numerology_index, fp->N_RB_SL);
|
||||
|
||||
fp->slots_per_frame = 10 * fp->slots_per_subframe;
|
||||
fp->symbols_per_slot = ((fp->Ncp == NR_NORMAL) ? 14 : 12); // to redefine for different slot formats
|
||||
fp->symbols_per_slot = ((fp->Ncp == NR_NORMAL) ? NR_SYMBOLS_PER_SLOT : NR_SYMBOLS_PER_SLOT_EXTENDED_CP);
|
||||
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
|
||||
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
|
||||
fp->samples_per_slot_wCP = fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
|
||||
@@ -53,7 +53,7 @@ void nr_normal_prefix_mod(c16_t *txdataF,
|
||||
uint8_t nsymb,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t slot,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT]);
|
||||
|
||||
void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ void nr_beam_precoding(c16_t **txdataF,
|
||||
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
bool is_flat_buff,
|
||||
const c16_t *symbol_rotation,
|
||||
int slot,
|
||||
int nb_rb,
|
||||
@@ -118,7 +119,7 @@ void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata,
|
||||
int slot,
|
||||
int slot_offsetF,
|
||||
enum nr_Link linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT]);
|
||||
|
||||
void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation);
|
||||
|
||||
@@ -161,4 +162,12 @@ void nr_layer_precoder_simd(const int n_layers,
|
||||
const int sc_offset,
|
||||
const int re_cnt,
|
||||
c16_t *txdataF_precoded);
|
||||
|
||||
void fft_shift(const c16_t *in,
|
||||
uint32_t in_symb_sz,
|
||||
uint16_t num_prb,
|
||||
c16_t *out,
|
||||
uint16_t fft_size_out,
|
||||
uint16_t start_symb,
|
||||
uint16_t num_symb);
|
||||
#endif
|
||||
|
||||
@@ -72,7 +72,7 @@ void nr_normal_prefix_mod(c16_t *txdataF,
|
||||
uint8_t nsymb,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t slot,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
|
||||
if (frame_parms->numerology_index != 0) { // case where numerology != 0
|
||||
@@ -288,6 +288,7 @@ void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_s
|
||||
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
bool is_flat_buff,
|
||||
const c16_t *symbol_rotation,
|
||||
int slot,
|
||||
int nb_rb,
|
||||
@@ -309,20 +310,39 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
this_rotation->r,
|
||||
this_rotation->i);
|
||||
|
||||
if (nb_rb & 1) {
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol,
|
||||
(nb_rb + 1) * 6, 15);
|
||||
rotate_cpx_vector(this_symbol + fp->first_carrier_offset - 6,
|
||||
this_rotation,
|
||||
this_symbol + fp->first_carrier_offset - 6,
|
||||
(nb_rb + 1) * 6, 15);
|
||||
} else {
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol,
|
||||
nb_rb * 6, 15);
|
||||
rotate_cpx_vector(this_symbol + fp->first_carrier_offset,
|
||||
this_rotation,
|
||||
this_symbol + fp->first_carrier_offset,
|
||||
nb_rb * 6, 15);
|
||||
if (is_flat_buff)
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * NR_NB_SC_PER_RB, 15);
|
||||
else {
|
||||
c16_t *this_symbol_neg = this_symbol + fp->first_carrier_offset;
|
||||
if (nb_rb & 1) {
|
||||
this_symbol_neg -= 6;
|
||||
nb_rb += 1;
|
||||
}
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * 6, 15);
|
||||
rotate_cpx_vector(this_symbol_neg, this_rotation, this_symbol_neg, nb_rb * 6, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do FFT-shift for symbols in the provided in buffer and writes to out buffer. */
|
||||
void fft_shift(const c16_t *in,
|
||||
uint32_t in_symb_sz,
|
||||
uint16_t num_prb,
|
||||
c16_t *out,
|
||||
uint16_t fft_size_out,
|
||||
uint16_t start_symb,
|
||||
uint16_t num_symb)
|
||||
{
|
||||
const int num_samp_half = num_prb * NR_NB_SC_PER_RB / 2;
|
||||
const int first_carrier_offset = fft_size_out - num_samp_half;
|
||||
for (int s = start_symb; s < start_symb + num_symb; s++) {
|
||||
// Copy negative freq component
|
||||
uint16_t out_offset = s * fft_size_out + first_carrier_offset;
|
||||
uint16_t in_offset = s * in_symb_sz;
|
||||
memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t));
|
||||
// Copy positive freq component
|
||||
out_offset = s * fft_size_out;
|
||||
in_offset = s * in_symb_sz + num_samp_half;
|
||||
memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata,
|
||||
int slot,
|
||||
int slot_offsetF,
|
||||
enum nr_Link linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
for (int aa = 0; aa < nb_antennas; aa++) {
|
||||
for (uint8_t symbol = 0; symbol < fp->symbols_per_slot; symbol++) {
|
||||
|
||||
@@ -53,7 +53,6 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3
|
||||
|
||||
void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
int txdataF_offset,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot)
|
||||
{
|
||||
@@ -68,7 +67,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
if (pdcch_pdu_rel15->CoreSetType == 1)
|
||||
additional_offset = (pdcch_pdu_rel15->BWPStart + 5) / 6 * 6 - pdcch_pdu_rel15->BWPStart;
|
||||
int rb_offset = cset_start + additional_offset;
|
||||
uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
uint16_t cset_start_sc = (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols;
|
||||
int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 3) + 15) & ~15;
|
||||
c16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16)));
|
||||
@@ -179,9 +178,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
/// Resource mapping
|
||||
uint16_t amp = gNB->TX_AMP;
|
||||
c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0] + txdataF_offset;
|
||||
if (cset_start_sc >= frame_parms->ofdm_symbol_size)
|
||||
cset_start_sc -= frame_parms->ofdm_symbol_size;
|
||||
c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0];
|
||||
|
||||
int num_regs = dci_pdu->AggregationLevel * NR_NB_REG_PER_CCE / pdcch_pdu_rel15->DurationSymbols;
|
||||
/*Mapping the encoded DCI along with the DMRS */
|
||||
@@ -190,8 +187,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
for (int reg_count = 0; reg_count < num_regs; reg_count++) {
|
||||
int k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB;
|
||||
LOG_D(NR_PHY_DCI, "REG %d k %d\n", reg_list[d][reg_count], k);
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
int l = cset_start_symb + symbol_idx;
|
||||
|
||||
@@ -227,9 +222,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
} // m
|
||||
} // reg_count
|
||||
} // symbol_idx
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
int txdataF_offset,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot);
|
||||
|
||||
|
||||
@@ -86,8 +86,7 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
printf("k %d \t txdataF: %d %d\n", k, txF[k].r, txF[k].i);
|
||||
#endif
|
||||
}
|
||||
if (++k >= symbol_sz)
|
||||
k -= symbol_sz;
|
||||
k++;
|
||||
}
|
||||
return in - tx_layer;
|
||||
}
|
||||
@@ -294,7 +293,7 @@ static inline int dmrs_case00(c16_t *output,
|
||||
else {
|
||||
output[k] = (c16_t){0};
|
||||
}
|
||||
k = (k + 1) % symbol_sz;
|
||||
k++;
|
||||
} // RE loop
|
||||
return in - txl;
|
||||
}
|
||||
@@ -355,12 +354,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
{
|
||||
c16_t *txl = txl_start;
|
||||
const uint sz = rel15->rbSize * NR_NB_SC_PER_RB;
|
||||
int upper_limit = sz;
|
||||
int remaining_re = 0;
|
||||
if (start_sc + upper_limit > symbol_sz) {
|
||||
upper_limit = symbol_sz - start_sc;
|
||||
remaining_re = sz - upper_limit;
|
||||
}
|
||||
|
||||
/* calculate if current symbol is PTRS symbols */
|
||||
int ptrs_symbol = 0;
|
||||
@@ -385,47 +378,39 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
if (rel15->numDmrsCdmGrpsNoData == 2) {
|
||||
switch (dmrs_port & 3) {
|
||||
case 0:
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
|
||||
txl += interleave_with_0_signal_first(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, sz);
|
||||
break;
|
||||
case 1: {
|
||||
c16_t dmrs[sz / 2];
|
||||
neg_dmrs(dmrs_start, dmrs, sz / 2);
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, upper_limit);
|
||||
txl += interleave_with_0_signal_first(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, sz);
|
||||
} break;
|
||||
case 2:
|
||||
txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
|
||||
txl += interleave_with_0_start_with_0(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, sz);
|
||||
break;
|
||||
case 3: {
|
||||
c16_t dmrs[sz / 2];
|
||||
neg_dmrs(dmrs_start, dmrs, sz / 2);
|
||||
txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, upper_limit);
|
||||
txl += interleave_with_0_start_with_0(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, sz);
|
||||
} break;
|
||||
}
|
||||
} else if (rel15->numDmrsCdmGrpsNoData == 1) {
|
||||
switch (dmrs_port & 3) {
|
||||
case 0:
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, upper_limit);
|
||||
txl += interleave_signals(output, txl, amp, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, sz);
|
||||
break;
|
||||
case 1: {
|
||||
c16_t dmrs[sz / 2];
|
||||
neg_dmrs(dmrs_start, dmrs, sz / 2);
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, upper_limit);
|
||||
txl += interleave_signals(output, txl, amp, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, sz);
|
||||
} break;
|
||||
case 2:
|
||||
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, upper_limit);
|
||||
txl += interleave_signals(output, dmrs_start + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, sz);
|
||||
break;
|
||||
case 3: {
|
||||
c16_t dmrs[sz / 2];
|
||||
neg_dmrs(dmrs_start, dmrs, sz / 2);
|
||||
txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, upper_limit);
|
||||
txl += interleave_signals(output, dmrs + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, sz);
|
||||
} break;
|
||||
}
|
||||
} else
|
||||
@@ -445,8 +430,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
rel15->numDmrsCdmGrpsNoData);
|
||||
} // generic DMRS case
|
||||
} else { // no PTRS or DMRS in this symbol
|
||||
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, upper_limit);
|
||||
txl += no_ptrs_dmrs_case(output, txl, amp, remaining_re);
|
||||
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz);
|
||||
} // no DMRS/PTRS in symbol
|
||||
return txl - txl_start;
|
||||
}
|
||||
@@ -477,30 +461,13 @@ static inline void do_txdataF(c16_t **txdataF,
|
||||
const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0;
|
||||
const int re_cnt = NR_NB_SC_PER_RB * rb_step;
|
||||
if (pmi == 0) { // unitary Precoding
|
||||
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
const int neg_length = symbol_sz - subCarrier;
|
||||
const int pos_length = re_cnt - neg_length;
|
||||
if (ant < rel15->nrOfLayers) {
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
neg_length * sizeof(**txdataF));
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant], pos_length * sizeof(**txdataF));
|
||||
} else {
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, neg_length * sizeof(**txdataF));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol], 0, pos_length * sizeof(**txdataF));
|
||||
}
|
||||
}
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
subCarrier += re_cnt;
|
||||
if (subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
} else { // non-unitary Precoding
|
||||
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
|
||||
// get the precoding matrix weights:
|
||||
@@ -514,38 +481,21 @@ static inline void do_txdataF(c16_t **txdataF,
|
||||
"Number of layers %d doesn't match to the one in precoding matrix %d\n",
|
||||
rel15->nrOfLayers,
|
||||
pmi_pdu->numLayers);
|
||||
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} else { // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
for (int i = 0; i < re_cnt; i++) {
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] =
|
||||
nr_layer_precoder_cm(rel15->nrOfLayers, symbol_sz, txdataF_precoding, ant, pmi_pdu, subCarrier);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n",
|
||||
ant,
|
||||
l_symbol,
|
||||
subCarrier,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
}
|
||||
} // else{ // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} // else { // non-unitary Precoding
|
||||
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
}
|
||||
|
||||
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot)
|
||||
{
|
||||
const int16_t amp = gNB->TX_AMP;
|
||||
@@ -554,7 +504,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats;
|
||||
time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats;
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
|
||||
const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB;
|
||||
const int layerSz = frame_parms->N_RB_DL * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB;
|
||||
const int symbol_sz=frame_parms->ofdm_symbol_size;
|
||||
const int dmrs_Type = rel15->dmrsConfigType;
|
||||
const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
|
||||
@@ -641,11 +591,8 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
start_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
/// Resource mapping
|
||||
// Non interleaved VRB to PRB mapping
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
|
||||
if (start_sc >= symbol_sz)
|
||||
start_sc -= symbol_sz;
|
||||
uint16_t start_sc = (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
|
||||
|
||||
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
|
||||
start_sc,
|
||||
@@ -756,7 +703,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz;
|
||||
do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
|
||||
}
|
||||
stop_meas(&gNB->dlsch_precoding_stats);
|
||||
@@ -765,7 +712,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
|
||||
* should remain a multiple of 8 * 64 with enough offset to fit each dlsch
|
||||
*/
|
||||
uint32_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
|
||||
uint32_t size_output_tb = rel15->rbSize * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
|
||||
return ((size_output_tb + 511) >> 9) << 6;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
|
||||
dlsch->b = NULL;
|
||||
}
|
||||
if (dlsch->f) {
|
||||
free16(dlsch->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
free16(dlsch->f, N_RB * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
dlsch->f = NULL;
|
||||
}
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
@@ -94,9 +94,9 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
bzero(dlsch.c[r], 8448);
|
||||
}
|
||||
|
||||
dlsch.f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
dlsch.f = malloc16(N_RB * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
AssertFatal(dlsch.f, "cannot allocate dlsch->f\n");
|
||||
bzero(dlsch.f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
bzero(dlsch.f, N_RB * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
|
||||
return (dlsch);
|
||||
}
|
||||
@@ -262,7 +262,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
|
||||
* => dlsch_offset should remain a multiple of 8 * 64 with enough offset to fit each dlsch
|
||||
*/
|
||||
const size_t dlsch_size = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers;
|
||||
const size_t dlsch_size = rel15->rbSize * gNB->frame_parms.symbols_per_slot * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers;
|
||||
dlsch_offset += ceil_mod(dlsch_size, 8 * 64);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
/// Resource mapping
|
||||
// PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
|
||||
///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
|
||||
k = frame_parms->ssb_start_subcarrier + nushift;
|
||||
l = ssb_start_symbol + 1;
|
||||
|
||||
for (int m = 0; m < 60; m++) {
|
||||
@@ -80,13 +80,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
k+=4;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
|
||||
k = frame_parms->ssb_start_subcarrier + nushift;
|
||||
l++;
|
||||
|
||||
for (int m = 60; m < 84; m++) {
|
||||
@@ -100,13 +97,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
|
||||
#endif
|
||||
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
|
||||
k = frame_parms->ssb_start_subcarrier + nushift;
|
||||
l++;
|
||||
|
||||
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
|
||||
@@ -115,9 +109,6 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
k+=4;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
@@ -334,7 +325,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
nushift = config->cell_config.phy_cell_id.value &3;
|
||||
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS
|
||||
///symbol 1 [0:239] -- 180 mod symbols
|
||||
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
|
||||
int k = frame_parms->ssb_start_subcarrier;
|
||||
int l = ssb_start_symbol + 1;
|
||||
int m = 0;
|
||||
int16_t amp = gNB->TX_AMP;
|
||||
@@ -351,13 +342,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
///symbol 2 [0:47 ; 192:239] -- 72 mod symbols
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
|
||||
k = frame_parms->ssb_start_subcarrier;
|
||||
l++;
|
||||
m=180;
|
||||
|
||||
@@ -373,16 +361,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
k += 144;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
|
||||
m=216;
|
||||
|
||||
for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) {
|
||||
@@ -397,13 +379,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
///symbol 3 [0:239] -- 180 mod symbols
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
|
||||
k = frame_parms->ssb_start_subcarrier;
|
||||
l++;
|
||||
m=252;
|
||||
|
||||
@@ -419,9 +398,5 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_n
|
||||
fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
Slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
gNB->frame_parms.symbols_per_slot,
|
||||
bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg
|
||||
else if (prs_cfg->CombSize == 12){
|
||||
k_prime = k_prime_table[3][symInd];
|
||||
}
|
||||
|
||||
k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_parms->first_carrier_offset;
|
||||
|
||||
|
||||
k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12;
|
||||
|
||||
// QPSK modulation
|
||||
uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l);
|
||||
for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) {
|
||||
@@ -66,10 +66,7 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_prs[m], amp, 15);
|
||||
|
||||
k = k + prs_cfg->CombSize;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_PRS_MAP
|
||||
LOG_M("nr_prs.m", "prs",(int16_t *)&txdataF[prs_cfg->SymbolStart*frame_parms->ofdm_symbol_size],prs_cfg->NumPRSSymbols*frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
@@ -49,8 +49,7 @@ int nr_generate_pss( c16_t *txdataF,
|
||||
/// Resource mapping
|
||||
|
||||
// PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from
|
||||
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and
|
||||
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
|
||||
int k = frame_parms->ssb_start_subcarrier + 56;
|
||||
|
||||
int l = ssb_start_symbol;
|
||||
|
||||
@@ -61,9 +60,6 @@ int nr_generate_pss( c16_t *txdataF,
|
||||
// printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size);
|
||||
((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_pss) >> 15;
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
#ifdef NR_PSS_DEBUG
|
||||
|
||||
@@ -59,16 +59,13 @@ int nr_generate_sss( c16_t *txdataF,
|
||||
/// Resource mapping
|
||||
|
||||
// SSS occupies a predefined position (subcarriers 56-182, symbol 2) within the SSB block starting from
|
||||
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and
|
||||
int k = frame_parms->ssb_start_subcarrier + 56;
|
||||
int l = ssb_start_symbol + 2;
|
||||
|
||||
for (int i = 0; i < NR_SSS_LENGTH; i++) {
|
||||
int16_t d_sss = (1 - 2*x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2*x1[(i + m1) % NR_SSS_LENGTH] ) * 23170;
|
||||
((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15;
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
#ifdef NR_SSS_DEBUG
|
||||
// write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
@@ -160,7 +160,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
|
||||
fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
gNB->frame_parms.symbols_per_slot,
|
||||
bitmap);
|
||||
}
|
||||
ulsch->frame = frame;
|
||||
|
||||
@@ -73,7 +73,7 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t
|
||||
fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
gNB->frame_parms.symbols_per_slot,
|
||||
bitmap);
|
||||
}
|
||||
memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t));
|
||||
@@ -1069,7 +1069,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
// first compute DMRS component
|
||||
const int scramble = pucch_pdu->dmrs_scrambling_id * 2;
|
||||
uint32_t x2 =
|
||||
((1ULL << 17) * ((NR_NUMBER_OF_SYMBOLS_PER_SLOT * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1))
|
||||
((1ULL << 17) * ((frame_parms->symbols_per_slot * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1))
|
||||
+ scramble)
|
||||
% (1U << 31); // c_init calculation according to TS38.211 subclause
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
|
||||
@@ -63,7 +63,7 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
|
||||
fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
gNB->frame_parms.symbols_per_slot,
|
||||
bitmap);
|
||||
}
|
||||
memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
|
||||
|
||||
@@ -281,7 +281,6 @@ static int nr_csi_rs_channel_estimation(
|
||||
int16_t *log2_maxh,
|
||||
uint32_t *noise_power)
|
||||
{
|
||||
const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP;
|
||||
*noise_power = 0;
|
||||
int maxh = 0;
|
||||
int count = 0;
|
||||
@@ -316,7 +315,7 @@ static int nr_csi_rs_channel_estimation(
|
||||
for (int lp = 0; lp <= csi_mapping->lprime; lp++) {
|
||||
uint16_t symb = lp + csi_mapping->loverline[cdm_id];
|
||||
uint64_t symbol_offset = symb * fp->ofdm_symbol_size;
|
||||
const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||
const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset];
|
||||
const c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
c16_t tmp = c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits);
|
||||
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions
|
||||
@@ -330,7 +329,7 @@ static int nr_csi_rs_channel_estimation(
|
||||
}
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
|
||||
for(int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
||||
if(!is_csi_rs_in_symbol(*csirs_config_pdu,symb)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -345,8 +345,7 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
|
||||
// generate pilot
|
||||
c16_t pilot[(n_rb + dmrs_ref) * 3] __attribute__((aligned(16)));
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
const uint32_t *gold =
|
||||
nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, proc->nr_slot_rx, symbol);
|
||||
const uint32_t *gold = nr_gold_pdcch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, proc->nr_slot_rx, symbol);
|
||||
nr_pdcch_dmrs_ref(gold, pilot, n_rb + dmrs_ref);
|
||||
nr_pdcch_channel_estimation(ue,
|
||||
n_rb,
|
||||
@@ -363,7 +362,7 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
|
||||
__attribute__((aligned(32))) c16_t rxdataF_ext[fp->nb_antennas_rx][rx_size];
|
||||
__attribute__((aligned(32))) c16_t pdcch_dl_ch_estimates_ext[fp->nb_antennas_rx][rx_size];
|
||||
|
||||
nr_pdcch_extract_rbs_single(ue->frame_parms.ofdm_symbol_size,
|
||||
nr_pdcch_extract_rbs_single(fp->ofdm_symbol_size,
|
||||
rxdataF,
|
||||
pdcch_est_size,
|
||||
pdcch_dl_ch_estimates,
|
||||
@@ -401,16 +400,18 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
|
||||
nr_pdcch_llr(llr_size_symbol, rxdataF_comp[0], llr);
|
||||
}
|
||||
|
||||
bool is_start_symbol_in_ss(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, const int symbol)
|
||||
static bool is_start_symbol_in_ss(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, const int symbol, const int nb_symb_slot)
|
||||
{
|
||||
return ((ss->coreset.StartSymbolBitmap >> (NR_SYMBOLS_PER_SLOT - 1 - symbol)) & 1);
|
||||
return ((ss->coreset.StartSymbolBitmap >> (nb_symb_slot - 1 - symbol)) & 1);
|
||||
}
|
||||
|
||||
int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, uint8_t start_symb[NR_SYMBOLS_PER_SLOT])
|
||||
static int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss,
|
||||
int nb_symb_slot,
|
||||
uint8_t start_symb[nb_symb_slot])
|
||||
{
|
||||
int sum = 0;
|
||||
for (int s = 0; s < NR_SYMBOLS_PER_SLOT; s++) {
|
||||
if (is_start_symbol_in_ss(ss, s)) {
|
||||
for (int s = 0; s < nb_symb_slot; s++) {
|
||||
if (is_start_symbol_in_ss(ss, s, nb_symb_slot)) {
|
||||
if (start_symb != NULL)
|
||||
start_symb[sum] = s;
|
||||
sum++;
|
||||
@@ -420,22 +421,22 @@ int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss,
|
||||
return sum;
|
||||
}
|
||||
|
||||
int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config)
|
||||
int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int nb_symb_slot)
|
||||
{
|
||||
int monOcc = 0;
|
||||
for (int ss = 0; ss < phy_pdcch_config->nb_search_space; ss++) {
|
||||
monOcc = max(monOcc, get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss], NULL));
|
||||
monOcc = max(monOcc, get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss], nb_symb_slot, NULL));
|
||||
}
|
||||
return monOcc;
|
||||
}
|
||||
|
||||
void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb)
|
||||
void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int nb_symb_slot, int *first_symb, int *last_symb)
|
||||
{
|
||||
*first_symb = NR_SYMBOLS_PER_SLOT; // max first pdcch symbol
|
||||
*first_symb = nb_symb_slot; // max first pdcch symbol
|
||||
*last_symb = 0; // min last pdcch symbol
|
||||
for (int ss = 0; ss < phy_pdcch_config->nb_search_space; ss++) {
|
||||
for (int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
|
||||
if (is_start_symbol_in_ss(&phy_pdcch_config->pdcch_config[ss], symb)) {
|
||||
for (int symb = 0; symb < nb_symb_slot; symb++) {
|
||||
if (is_start_symbol_in_ss(&phy_pdcch_config->pdcch_config[ss], symb, nb_symb_slot)) {
|
||||
const int duration = phy_pdcch_config->pdcch_config[ss].coreset.duration;
|
||||
*first_symb = min(*first_symb, symb);
|
||||
*last_symb = max(*last_symb, symb + duration - 1);
|
||||
@@ -460,7 +461,9 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue,
|
||||
// Loop over search spaces
|
||||
for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) {
|
||||
uint8_t start_symb[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
const int num_monOcc = get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss_idx], start_symb);
|
||||
const int num_monOcc = get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss_idx],
|
||||
ue->frame_parms.symbols_per_slot,
|
||||
start_symb);
|
||||
// Loop over monitoring occations within the slot in this ss
|
||||
for (int occ = 0; occ < num_monOcc; occ++) {
|
||||
const int first_symb = start_symb[occ];
|
||||
@@ -609,7 +612,7 @@ void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
|
||||
for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) {
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[ss_idx];
|
||||
uint8_t unused_start_symb[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, unused_start_symb);
|
||||
const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, ue->frame_parms.symbols_per_slot, unused_start_symb);
|
||||
const int llr_stride = llr_size / rel15->coreset.duration;
|
||||
int n_rb, cset_start;
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start);
|
||||
|
||||
@@ -701,7 +701,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
UEunlockScopeData(ue, pdschRxdataF_comp)
|
||||
}
|
||||
} else {
|
||||
UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nbRx, rx_size_symbol * NR_SYMBOLS_PER_SLOT, 0);
|
||||
UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nbRx, rx_size_symbol * fp->symbols_per_slot, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,11 +69,9 @@ typedef struct pdsch_scope_req_s {
|
||||
void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations);
|
||||
void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0);
|
||||
|
||||
void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb);
|
||||
void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int symb_slot, int *first_symb, int *last_symb);
|
||||
|
||||
int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, uint8_t start_symb[NR_SYMBOLS_PER_SLOT]);
|
||||
|
||||
int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config);
|
||||
int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int nb_symb_slot);
|
||||
|
||||
/** \brief This is the alternative top-level entry point for DLSCH decoding in UE.
|
||||
It handles all the HARQ processes in only one call. The routine first
|
||||
@@ -162,25 +160,25 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint8_t slot,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT]);
|
||||
|
||||
/** \brief This function does IFFT for PUSCH
|
||||
*/
|
||||
|
||||
uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT],
|
||||
bool no_phase_pre_comp);
|
||||
void nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT],
|
||||
bool no_phase_pre_comp);
|
||||
|
||||
bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t **txdataF,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT]);
|
||||
|
||||
void clean_UE_harq(PHY_VARS_NR_UE *UE);
|
||||
|
||||
|
||||
@@ -1027,11 +1027,11 @@ static uci_on_pusch_bit_type_t *nr_data_control_mapping(const nfapi_nr_ue_pusch_
|
||||
if (!pusch_pdu || !codeword || codeword_len == 0 || !template)
|
||||
return NULL;
|
||||
const uint8_t n_symbols = pusch_pdu->nr_of_symbols;
|
||||
if (n_symbols == 0 || n_symbols > NR_NUMBER_OF_SYMBOLS_PER_SLOT)
|
||||
if (n_symbols == 0 || n_symbols > NR_SYMBOLS_PER_SLOT)
|
||||
return NULL;
|
||||
|
||||
uint32_t m_ulsch_initial[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
uint32_t m_uci_current[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0}; // This holds RE counts, not bit counts
|
||||
uint32_t m_ulsch_initial[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
uint32_t m_uci_current[NR_SYMBOLS_PER_SLOT] = {0}; // This holds RE counts, not bit counts
|
||||
|
||||
if (initialize_mapping_resources(pusch_pdu, m_ulsch_initial, m_uci_current) != 0) {
|
||||
LOG_E(PHY, "Failed to initialize mapping resources\n");
|
||||
@@ -1048,8 +1048,8 @@ static uci_on_pusch_bit_type_t *nr_data_control_mapping(const nfapi_nr_ue_pusch_
|
||||
|
||||
memset(template, 0, codeword_len * sizeof(uci_on_pusch_bit_type_t));
|
||||
|
||||
uint32_t positions_by_sym[NR_NUMBER_OF_SYMBOLS_PER_SLOT][MAX_UCI_CODED_BITS] = {0};
|
||||
uint32_t count_by_sym[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
uint32_t positions_by_sym[NR_SYMBOLS_PER_SLOT][MAX_UCI_CODED_BITS] = {0};
|
||||
uint32_t count_by_sym[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
|
||||
struct map_uci_common_arg map_arg = {.template = template,
|
||||
.n_symbols = pusch_pdu->nr_of_symbols,
|
||||
@@ -1094,7 +1094,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint8_t slot,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
|
||||
int harq_pid = phy_data->ulsch.pusch_pdu.pusch_data.harq_process_id;
|
||||
@@ -1603,30 +1603,37 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS);
|
||||
}
|
||||
|
||||
uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT],
|
||||
bool no_phase_pre_comp)
|
||||
void nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT],
|
||||
bool no_phase_pre_comp)
|
||||
{
|
||||
int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL;
|
||||
|
||||
if (!no_phase_pre_comp) {
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) {
|
||||
for (int i = 0; i < frame_parms->symbols_per_slot; i++) {
|
||||
if (was_symbol_used[i] == false)
|
||||
continue;
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1);
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
txdataF[ap],
|
||||
false,
|
||||
frame_parms->symbol_rotation[linktype],
|
||||
slot,
|
||||
N_RB,
|
||||
i,
|
||||
1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
if (frame_parms->Ncp == 1) { // extended cyclic prefix
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP; i++) {
|
||||
for (int i = 0; i < frame_parms->symbols_per_slot; i++) {
|
||||
if (was_symbol_used[i] == false) {
|
||||
memset(&txdata[ap][(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * i],
|
||||
0,
|
||||
@@ -1641,11 +1648,7 @@ uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
|
||||
CYCLIC_PREFIX);
|
||||
}
|
||||
} else { // normal cyclic prefix
|
||||
nr_normal_prefix_mod(txdataF[ap], txdata[ap], NR_NUMBER_OF_SYMBOLS_PER_SLOT, frame_parms, slot, was_symbol_used);
|
||||
nr_normal_prefix_mod(txdataF[ap], txdata[ap], frame_parms->symbols_per_slot, frame_parms, slot, was_symbol_used);
|
||||
}
|
||||
}
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ unsigned int mmapped_dma=0;
|
||||
uint32_t timing_advance;
|
||||
int8_t threequarter_fs;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int cpu_meas_enabled;
|
||||
THREAD_STRUCT thread_struct;
|
||||
uint32_t target_ul_mcs = 9;
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#define MAX_NUM_SUBCARRIER_SPACING 5
|
||||
#define NR_MAX_OFDM_SYMBOL_SIZE 8192
|
||||
|
||||
#define NR_SYMBOLS_PER_SLOT NR_NUMBER_OF_SYMBOLS_PER_SLOT
|
||||
|
||||
#define ONE_OVER_SQRT2_Q15 23170
|
||||
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 686
|
||||
|
||||
@@ -25,8 +25,6 @@ static void csi_rs_resource_mapping(c16_t **dataF,
|
||||
int csi_rs_length,
|
||||
int16_t mod_csi[][csi_rs_length >> 1],
|
||||
int ofdm_symbol_size,
|
||||
int dataF_offset,
|
||||
int start_sc,
|
||||
const csi_mapping_parms_t *mapping_parms,
|
||||
int start_rb,
|
||||
int nb_rbs,
|
||||
@@ -44,7 +42,7 @@ static void csi_rs_resource_mapping(c16_t **dataF,
|
||||
int p = s + mapping_parms->j[ji] * gs; // port index
|
||||
for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group
|
||||
// frequency index of current resource element
|
||||
int k = (start_sc + (n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp) % (ofdm_symbol_size);
|
||||
int k = ((n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp);
|
||||
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
|
||||
int na = n * alpha;
|
||||
@@ -66,7 +64,7 @@ static void csi_rs_resource_mapping(c16_t **dataF,
|
||||
else
|
||||
wt = -1;
|
||||
}
|
||||
int index = (l * ofdm_symbol_size + k) + dataF_offset;
|
||||
int index = (l * ofdm_symbol_size + k);
|
||||
dataF[p][index].r = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15;
|
||||
dataF[p][index].i = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15;
|
||||
LOG_D(PHY,
|
||||
@@ -622,14 +620,10 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
// CDM group size from CDM type index
|
||||
const int gs = get_cdm_group_size(cdm_type);
|
||||
|
||||
const int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
|
||||
csi_rs_resource_mapping(dataF,
|
||||
frame_parms->N_RB_DL << 4,
|
||||
mod_csi,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
dataF_offset,
|
||||
frame_parms->first_carrier_offset,
|
||||
phy_csi_parms,
|
||||
start_rb,
|
||||
nr_of_rbs,
|
||||
|
||||
@@ -30,18 +30,18 @@ static const uint16_t srs_max_number_cs[3] = {8, 12, 6};
|
||||
|
||||
//#define SRS_DEBUG
|
||||
|
||||
static int group_number_hopping(int slot_number, uint8_t n_ID_SRS, uint8_t l0, uint8_t l_line)
|
||||
static int group_number_hopping(int slot_number, uint8_t n_ID_SRS, uint8_t l0, uint8_t l_line, int symb_slot)
|
||||
{
|
||||
// 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 * NR_SYMBOLS_PER_SLOT + l0 + l_line) + 7;
|
||||
uint8_t c_last_index = 8 * (slot_number * 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 * NR_SYMBOLS_PER_SLOT + l0 + l_line) + m] << m;
|
||||
f_gh += c_sequence[8 * (slot_number * symb_slot + l0 + l_line) + m] << m;
|
||||
}
|
||||
f_gh = f_gh % 30;
|
||||
int u = (f_gh + n_ID_SRS) % U_GROUP_NUMBER;
|
||||
@@ -49,13 +49,13 @@ static int group_number_hopping(int slot_number, uint8_t n_ID_SRS, uint8_t l0, u
|
||||
return u;
|
||||
}
|
||||
|
||||
static int sequence_number_hopping(int slot_number, uint8_t n_ID_SRS, uint16_t M_sc_b_SRS, uint8_t l0, uint8_t l_line)
|
||||
static int sequence_number_hopping(int slot_number, int n_ID_SRS, int M_sc_b_SRS, int l0, int l_line, int symb_slot)
|
||||
{
|
||||
int 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 * NR_SYMBOLS_PER_SLOT + l0 + l_line);
|
||||
uint8_t c_last_index = (slot_number * 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
|
||||
@@ -255,12 +255,12 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
v = 0;
|
||||
break;
|
||||
case groupHopping:
|
||||
u = group_number_hopping(slot_number, nr_srs_info->n_ID_SRS, l0, l_line);
|
||||
u = group_number_hopping(slot_number, nr_srs_info->n_ID_SRS, l0, l_line, frame_parms->symbols_per_slot);
|
||||
v = 0;
|
||||
break;
|
||||
case sequenceHopping:
|
||||
u = nr_srs_info->n_ID_SRS % U_GROUP_NUMBER;
|
||||
v = sequence_number_hopping(slot_number, nr_srs_info->n_ID_SRS, M_sc_b_SRS, l0, l_line);
|
||||
v = sequence_number_hopping(slot_number, nr_srs_info->n_ID_SRS, M_sc_b_SRS, l0, l_line, frame_parms->symbols_per_slot);
|
||||
break;
|
||||
default:
|
||||
LOG_E(NR_PHY, "generate_srs: unknown hopping setting %d !\n", nr_srs_info->groupOrSequenceHopping);
|
||||
|
||||
@@ -145,19 +145,17 @@ void nr_feptx0(RU_t *ru, int tti_tx, int first_symbol, int num_symbols, int aa)
|
||||
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx)
|
||||
{
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
|
||||
int cyclic_prefix_type = NFAPI_CP_NORMAL;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
unsigned int aa=0;
|
||||
int slot_sizeF = (fp->ofdm_symbol_size)*
|
||||
((cyclic_prefix_type == 1) ? 12 : 14);
|
||||
int slot_sizeF = fp->ofdm_symbol_size * fp->symbols_per_slot;
|
||||
int slot = tti_tx;
|
||||
int *txdata = &ru->common.txdata[aa][get_samples_slot_timestamp(fp, slot)];
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
|
||||
nr_feptx0(ru,slot,0,NR_NUMBER_OF_SYMBOLS_PER_SLOT,aa);
|
||||
nr_feptx0(ru, slot, 0, fp->symbols_per_slot, aa);
|
||||
|
||||
LOG_D(PHY,
|
||||
"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n",
|
||||
@@ -175,7 +173,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
|
||||
PHY_VARS_gNB *gNB = gNB_list[0];
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int txdataF_offset = slot_tx * fp->samples_per_slot_wCP;
|
||||
start_meas(&ru->precoding_stats);
|
||||
|
||||
if (gNB->common_vars.analog_bf) {
|
||||
@@ -195,8 +192,8 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
|
||||
for (int b = 0; b < ru->num_beams_period; b++) {
|
||||
for (int i = 0; i < Ptx; ++i) {
|
||||
int tx_idx = i + b * ru->nb_tx;
|
||||
memcpy((void*)ru->common.txdataF_BF[tx_idx],
|
||||
(void*)&gNB->common_vars.txdataF[b][i][txdataF_offset],
|
||||
memcpy((void *)ru->common.txdataF_BF[tx_idx],
|
||||
(void *)gNB->common_vars.txdataF[b][i],
|
||||
fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
@@ -218,9 +215,6 @@ void nr_feptx(void *arg)
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
int numSamples = feptx->numSymbols * fp->ofdm_symbol_size;
|
||||
int txdataF_offset = (slot * fp->samples_per_slot_wCP) + startSymbol * fp->ofdm_symbol_size;
|
||||
int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size;
|
||||
|
||||
int tx_idx = aa + bb * ru->nb_tx;
|
||||
|
||||
@@ -234,11 +228,17 @@ void nr_feptx(void *arg)
|
||||
}
|
||||
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf)
|
||||
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset],
|
||||
numSamples * sizeof(int32_t));
|
||||
else {
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
// FFT shift
|
||||
const NR_DL_FRAME_PARMS *fp = &ru->gNB_list[0]->frame_parms;
|
||||
fft_shift(ru->gNB_list[0]->common_vars.txdataF[bb][aa],
|
||||
fp->ofdm_symbol_size,
|
||||
fp->N_RB_DL,
|
||||
(c16_t *)ru->common.txdataF_BF[tx_idx],
|
||||
fp->ofdm_symbol_size,
|
||||
startSymbol,
|
||||
numSymbols);
|
||||
} else {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -74,9 +74,8 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
|
||||
cfg->tdd_table.max_tdd_periodicity_list = calloc_or_fail(nb_slots_to_set, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
for (int slot = 0; slot < nb_slots_to_set; slot++) {
|
||||
nfapi_nr_max_tdd_periodicity_t *p_list = &cfg->tdd_table.max_tdd_periodicity_list[slot];
|
||||
p_list->max_num_of_symbol_per_slot_list =
|
||||
calloc_or_fail(NR_NUMBER_OF_SYMBOLS_PER_SLOT, sizeof(*p_list->max_num_of_symbol_per_slot_list));
|
||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
p_list->max_num_of_symbol_per_slot_list = calloc_or_fail(NR_SYMBOLS_PER_SLOT, sizeof(*p_list->max_num_of_symbol_per_slot_list));
|
||||
for (int sym = 0; sym < NR_SYMBOLS_PER_SLOT; sym++) {
|
||||
// for each symbol, assign the TLV tag for usage when packing
|
||||
p_list->max_num_of_symbol_per_slot_list[sym].slot_config.tl.tag = NFAPI_NR_CONFIG_SLOT_CONFIG_TAG;
|
||||
}
|
||||
@@ -89,9 +88,9 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
|
||||
nfapi_nr_max_tdd_periodicity_t *list = &cfg->tdd_table.max_tdd_periodicity_list[slot_number];
|
||||
// FULL DOWNLINK SLOTS
|
||||
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_DOWNLINK_SLOT) {
|
||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value = 0;
|
||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) {
|
||||
for (int sym = 0; sym < NR_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym % NR_SYMBOLS_PER_SLOT].slot_config.value = 0;
|
||||
if ((sym + 1) % NR_SYMBOLS_PER_SLOT == 0) {
|
||||
slot_number++;
|
||||
list += 1;
|
||||
}
|
||||
@@ -101,7 +100,7 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
|
||||
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_MIXED_SLOT) {
|
||||
int nrofDLSymbolsInSlot = tdd_slot_bitmap[slot_index].num_dl_symbols;
|
||||
int nrofULSymbolsInSlot = tdd_slot_bitmap[slot_index].num_ul_symbols;
|
||||
AssertFatal(nrofDLSymbolsInSlot + nrofULSymbolsInSlot < NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
AssertFatal(nrofDLSymbolsInSlot + nrofULSymbolsInSlot < NR_SYMBOLS_PER_SLOT,
|
||||
"illegal symbol configuration DL %d, UL %d\n",
|
||||
nrofDLSymbolsInSlot,
|
||||
nrofULSymbolsInSlot);
|
||||
@@ -110,11 +109,11 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
|
||||
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 0;
|
||||
}
|
||||
// Flexible Symbols
|
||||
for (int sym = nrofDLSymbolsInSlot; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym++) {
|
||||
for (int sym = nrofDLSymbolsInSlot; sym < NR_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 2;
|
||||
}
|
||||
// UL Symbols
|
||||
for (int sym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
for (int sym = NR_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym < NR_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 1;
|
||||
}
|
||||
slot_number++;
|
||||
@@ -122,9 +121,9 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
|
||||
}
|
||||
// FULL UPLINK SLOTS
|
||||
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value = 1;
|
||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) {
|
||||
for (int sym = 0; sym < NR_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym % NR_SYMBOLS_PER_SLOT].slot_config.value = 1;
|
||||
if ((sym + 1) % NR_SYMBOLS_PER_SLOT == 0) {
|
||||
slot_number++;
|
||||
list += 1;
|
||||
}
|
||||
@@ -134,14 +133,14 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
|
||||
// Dump 1 period on the output
|
||||
for (int s = 0; s < fs->numb_slots_period; s++) {
|
||||
if (tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT) {
|
||||
char flexi_slot[NR_NUMBER_OF_SYMBOLS_PER_SLOT + 1];
|
||||
char flexi_slot[NR_SYMBOLS_PER_SLOT + 1];
|
||||
memset(flexi_slot, 0, sizeof(flexi_slot));
|
||||
for (int symb = 0; symb < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symb++) {
|
||||
for (int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
|
||||
uint8_t val = cfg->tdd_table.max_tdd_periodicity_list[s].max_num_of_symbol_per_slot_list[symb].slot_config.value;
|
||||
char *symb_type_s[] = {"D", "U", "F"};
|
||||
flexi_slot[symb] = *symb_type_s[val];
|
||||
}
|
||||
flexi_slot[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = '\0';
|
||||
flexi_slot[NR_SYMBOLS_PER_SLOT] = '\0';
|
||||
LOG_I(NR_PHY, "TDD period configuration: slot %d is FLEXIBLE: %s\n", s, flexi_slot);
|
||||
} else {
|
||||
LOG_I(NR_PHY,
|
||||
@@ -163,25 +162,25 @@ int nr_slot_select(const nfapi_nr_config_request_scf_t *cfg, int nr_frame, int n
|
||||
return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
|
||||
}
|
||||
|
||||
for (int symbol_count = 0; symbol_count < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
for (int symbol_count = 0; symbol_count < NR_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value == 1) {
|
||||
check_slot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
|
||||
if (check_slot == NR_SYMBOLS_PER_SLOT) {
|
||||
return (NR_UPLINK_SLOT);
|
||||
}
|
||||
|
||||
check_slot = 0;
|
||||
|
||||
for (int symbol_count = 0; symbol_count < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
for (int symbol_count = 0; symbol_count < NR_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value == 0) {
|
||||
check_slot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
|
||||
if (check_slot == NR_SYMBOLS_PER_SLOT) {
|
||||
return (NR_DOWNLINK_SLOT);
|
||||
} else {
|
||||
return (NR_MIXED_SLOT);
|
||||
|
||||
@@ -146,7 +146,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
|
||||
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol);
|
||||
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming;
|
||||
c16_t ***txdataF = gNB->common_vars.txdataF;
|
||||
int txdataF_offset = slot * fp->samples_per_slot_wCP;
|
||||
// beam number in a scenario with multiple concurrent beams
|
||||
int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols
|
||||
int beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
@@ -156,15 +155,15 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
|
||||
fp->symbols_per_slot,
|
||||
bitmap);
|
||||
|
||||
nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_pss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
uint16_t slots_per_hf = (fp->slots_per_frame) >> 1;
|
||||
int n_hf = slot < slots_per_hf ? 0 : 1;
|
||||
|
||||
int hf = fp->Lmax == 4 ? n_hf : 0;
|
||||
nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7),
|
||||
&txdataF[beam_nb][0][txdataF_offset],
|
||||
txdataF[beam_nb][0],
|
||||
gNB->TX_AMP,
|
||||
ssb_start_symbol,
|
||||
cfg,
|
||||
@@ -182,7 +181,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
|
||||
|
||||
nr_generate_pbch(gNB,
|
||||
ssb_pdu,
|
||||
&txdataF[beam_nb][0][txdataF_offset],
|
||||
txdataF[beam_nb][0],
|
||||
ssb_start_symbol,
|
||||
n_hf,
|
||||
frame,
|
||||
@@ -246,7 +245,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
{
|
||||
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
const int txdataF_offset = slot * fp->samples_per_slot_wCP;
|
||||
|
||||
if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT))
|
||||
return;
|
||||
@@ -254,7 +252,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
// clear the transmit data array and beam index for the current slot
|
||||
for (int i = 0; i < gNB->common_vars.num_beams_period; i++) {
|
||||
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
memset(&gNB->common_vars.txdataF[i][aa][txdataF_offset], 0, fp->samples_per_slot_wCP * sizeof(***gNB->common_vars.txdataF));
|
||||
memset(gNB->common_vars.txdataF[i][aa], 0, fp->samples_per_slot_wCP * sizeof(***gNB->common_vars.txdataF));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,13 +266,13 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
{
|
||||
int slot_prs = (slot - i * prs_config->PRSResourceTimeGap + fp->slots_per_frame) % fp->slots_per_frame;
|
||||
LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id);
|
||||
nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, fp);
|
||||
nr_generate_prs(slot_prs, gNB->common_vars.txdataF[0][0], AMP, prs_config, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < UL_dci_req->numPdus; ++i)
|
||||
nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot);
|
||||
nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, &gNB->frame_parms, slot);
|
||||
|
||||
int num_pdsch = 0;
|
||||
for (int i = 0; i < DL_req->dl_tti_request_body.nPDUs; ++i) {
|
||||
@@ -284,7 +282,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
nr_common_signal_procedures(gNB, frame, slot, &dl_tti_pdu->ssb_pdu);
|
||||
break;
|
||||
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
|
||||
nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot);
|
||||
nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, &gNB->frame_parms, slot);
|
||||
break;
|
||||
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
|
||||
nr_generate_csi_rs_gNB(gNB, slot, &dl_tti_pdu->csi_rs_pdu);
|
||||
@@ -321,7 +319,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
if (gNB->phase_comp) {
|
||||
apply_nr_rotation_TX(fp,
|
||||
&gNB->common_vars.txdataF[i][aa][txdataF_offset],
|
||||
gNB->common_vars.txdataF[i][aa],
|
||||
true,
|
||||
fp->symbol_rotation[0],
|
||||
slot,
|
||||
fp->N_RB_DL,
|
||||
@@ -333,7 +332,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
T_INT(frame),
|
||||
T_INT(slot),
|
||||
T_INT(aa),
|
||||
T_BUFFER(&gNB->common_vars.txdataF[i][aa][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t)));
|
||||
T_BUFFER(gNB->common_vars.txdataF[i][aa], fp->samples_per_slot_wCP * sizeof(int32_t)));
|
||||
}
|
||||
}
|
||||
stop_meas(&gNB->phase_comp_stats);
|
||||
@@ -980,7 +979,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
const uint16_t ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
const int nb_symb = frame_parms->symbols_per_slot;
|
||||
const uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
||||
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
|
||||
{
|
||||
@@ -993,7 +991,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
|
||||
int first_symb = 0, num_symb = 0;
|
||||
if (frame_parms->frame_type == TDD)
|
||||
for (int symbol_count = 0; symbol_count < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
for (int symbol_count = 0; symbol_count < frame_parms->symbols_per_slot; symbol_count++) {
|
||||
if (slot_conf[symbol_count].slot_config.value == 1) {
|
||||
if (num_symb == 0)
|
||||
first_symb = symbol_count;
|
||||
@@ -1001,11 +999,11 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
}
|
||||
}
|
||||
else
|
||||
num_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT;
|
||||
num_symb = frame_parms->symbols_per_slot;
|
||||
gNB_I0_measurements(gNB, slot_rx, first_symb, num_symb, rb_mask_ul);
|
||||
}
|
||||
|
||||
const int soffset = (slot_rx & 3) * nb_symb * ofdm_symbol_size;
|
||||
const int soffset = (slot_rx & 3) * frame_parms->symbols_per_slot * ofdm_symbol_size;
|
||||
start_meas(&gNB->phy_proc_rx);
|
||||
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
@@ -1368,7 +1366,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
T(T_GNB_PHY_PUCCH_PUSCH_IQ,
|
||||
T_INT(frame_rx),
|
||||
T_INT(slot_rx),
|
||||
T_BUFFER(&gNB->common_vars.rxdataF[0][0][0], nb_symb * ofdm_symbol_size * 4));
|
||||
T_BUFFER(&gNB->common_vars.rxdataF[0][0][0], frame_parms->symbols_per_slot * ofdm_symbol_size * 4));
|
||||
}
|
||||
|
||||
return pusch_DTX;
|
||||
|
||||
@@ -304,10 +304,10 @@ static void configure_srs_info(fapi_nr_ul_config_srs_pdu *srs_config_pdu, nr_srs
|
||||
*
|
||||
*********************************************************************/
|
||||
bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t **txdataF,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t **txdataF,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
if(phy_data->srs_vars.active == false) {
|
||||
return false;
|
||||
@@ -375,7 +375,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx % 1024), T_INT(slot_tx));
|
||||
#endif
|
||||
|
||||
const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * ue->frame_parms.ofdm_symbol_size;
|
||||
const int samplesF_per_slot = ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size;
|
||||
c16_t txdataF_buf[ue->frame_parms.nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32)));
|
||||
memset(txdataF_buf, 0, sizeof(txdataF_buf));
|
||||
c16_t *txdataF[ue->frame_parms.nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */
|
||||
@@ -383,7 +383,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
txdataF[i] = &txdataF_buf[i * samplesF_per_slot];
|
||||
|
||||
LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
|
||||
start_meas_nr_ue_phy(ue, PHY_PROC_TX);
|
||||
|
||||
@@ -618,7 +618,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
toFree2,
|
||||
dlsch[0].Nl,
|
||||
ue->frame_parms.nb_antennas_rx,
|
||||
rx_size_symbol * NR_SYMBOLS_PER_SLOT,
|
||||
rx_size_symbol * ue->frame_parms.symbols_per_slot,
|
||||
false);
|
||||
|
||||
uint32_t nvar = 0;
|
||||
@@ -1027,22 +1027,21 @@ void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
/* process PDCCH */
|
||||
LOG_D(PHY, " ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", proc->frame_rx % 1024, proc->nr_slot_rx);
|
||||
start_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
|
||||
int num_monitoring_occ = get_max_pdcch_monOcc(phy_pdcch_config);
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
int num_monitoring_occ = get_max_pdcch_monOcc(phy_pdcch_config, fp->symbols_per_slot);
|
||||
int max_nb_symb_pdcch = get_max_pdcch_symb(phy_pdcch_config);
|
||||
int llr_size_symbol = get_pdcch_max_rbs(phy_pdcch_config) * 9;
|
||||
c16_t pdcch_llr[phy_pdcch_config->nb_search_space][num_monitoring_occ][max_nb_symb_pdcch * llr_size_symbol];
|
||||
|
||||
int start_symb_pdcch, last_symb_pdcch;
|
||||
set_first_last_pdcch_symb(phy_pdcch_config, &start_symb_pdcch, &last_symb_pdcch);
|
||||
set_first_last_pdcch_symb(phy_pdcch_config, fp->symbols_per_slot, &start_symb_pdcch, &last_symb_pdcch);
|
||||
|
||||
/* Temporarily loop over symbols in the slot, perform OFDM demod and process PDCCH.
|
||||
When symbol based proc design is fully merged, this function will be called to process only one symbol
|
||||
and OFDM demod will be removed from here. */
|
||||
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
|
||||
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
|
||||
|
||||
for (int symbol = start_symb_pdcch; symbol <= last_symb_pdcch; symbol++) {
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
nr_slot_fep(ue, fp, proc->nr_slot_rx, symbol, rxdataF, link_type_dl, 0, ue->common_vars.rxdata);
|
||||
__attribute__((aligned(32))) c16_t rxdataF_symb[fp->nb_antennas_rx][((fp->ofdm_symbol_size + 7) / 8) * 8];
|
||||
|
||||
@@ -1058,7 +1057,7 @@ void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
|
||||
TracyCZoneEnd(ctx);
|
||||
if (ue->phy_sim_rxdataF)
|
||||
memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * max_nb_symb_pdcch * ue->frame_parms.ofdm_symbol_size);
|
||||
memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * max_nb_symb_pdcch * fp->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
@@ -1248,7 +1247,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
|
||||
// do procedures for CSI-RS
|
||||
if (phy_data->csirs_vars.active == 1) {
|
||||
for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
|
||||
for(int symb = 0; symb < ue->frame_parms.symbols_per_slot; symb++) {
|
||||
if(is_csi_rs_in_symbol(phy_data->csirs_vars.csirs_config_pdu, symb)) {
|
||||
if (!slot_fep_map[symb]) {
|
||||
nr_slot_fep(ue, &ue->frame_parms, proc->nr_slot_rx, symb, rxdataF, link_type_dl, 0, ue->common_vars.rxdata);
|
||||
|
||||
@@ -300,7 +300,7 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
tx_action = 1;
|
||||
}
|
||||
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT];
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT];
|
||||
for (int i = 0; i < 14; i++)
|
||||
was_symbol_used[i] = true;
|
||||
if (tx_action) {
|
||||
|
||||
@@ -136,7 +136,7 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
const int nr_slot_tx = proc->nr_slot_tx;
|
||||
NR_UE_PUCCH *pucch_vars = &phy_data->pucch_vars;
|
||||
|
||||
@@ -56,7 +56,7 @@ PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
UE_nr_rxtx_proc_t proc;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
|
||||
@@ -104,7 +104,7 @@ const char *__asan_default_options()
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
double cpuf;
|
||||
char *uecap_file;
|
||||
|
||||
@@ -1123,40 +1123,53 @@ int main(int argc, char **argv)
|
||||
phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot);
|
||||
stop_meas(&gNB->phy_proc_tx);
|
||||
|
||||
int txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
|
||||
if (n_trials==1) {
|
||||
LOG_M("txsigF0.m","txsF0=",
|
||||
&gNB->common_vars.txdataF[0][0][txdataF_offset +2 * frame_parms->ofdm_symbol_size],
|
||||
&gNB->common_vars.txdataF[0][0][2 * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
1);
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("txsigF1.m","txsF1=",
|
||||
&gNB->common_vars.txdataF[0][1][txdataF_offset + 2 * frame_parms->ofdm_symbol_size],
|
||||
&gNB->common_vars.txdataF[0][1][2 * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
1);
|
||||
}
|
||||
if (n_trials == 1)
|
||||
printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset);
|
||||
printf("slot_offset %d\n", slot_offset);
|
||||
|
||||
//TODO: loop over slots
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
|
||||
c16_t fft_in_buff[frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot] __attribute__((aligned(64)));
|
||||
memset(fft_in_buff, 0, sizeof(fft_in_buff));
|
||||
if (cyclic_prefix_type == 1) {
|
||||
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][txdataF_offset],
|
||||
fft_shift(gNB->common_vars.txdataF[0][aa],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
frame_parms->N_RB_DL,
|
||||
fft_in_buff,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
0,
|
||||
12);
|
||||
PHY_ofdm_mod((int *)fft_in_buff,
|
||||
(int *)&txdata[aa][slot_offset],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT];
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT];
|
||||
for (int i = 0; i < 14; i++) {
|
||||
was_symbol_used[i] = true;
|
||||
}
|
||||
nr_normal_prefix_mod(&gNB->common_vars.txdataF[0][aa][txdataF_offset],
|
||||
fft_shift(gNB->common_vars.txdataF[0][aa],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
frame_parms->N_RB_DL,
|
||||
fft_in_buff,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
0,
|
||||
14);
|
||||
nr_normal_prefix_mod(fft_in_buff,
|
||||
&txdata[aa][slot_offset],
|
||||
14,
|
||||
frame_parms,
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
|
||||
@@ -525,17 +525,28 @@ int main(int argc, char **argv)
|
||||
nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]);
|
||||
|
||||
int samp = get_samples_slot_timestamp(frame_parms, slot);
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
for (aa = 0; aa < gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
c16_t fft_in_buff[frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot] __attribute__((aligned(64)));
|
||||
memset(fft_in_buff, 0, sizeof(fft_in_buff));
|
||||
if (cyclic_prefix_type == 1) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
gNB->common_vars.txdataF[0][aa],
|
||||
true,
|
||||
frame_parms->symbol_rotation[0],
|
||||
slot,
|
||||
frame_parms->N_RB_DL,
|
||||
0,
|
||||
12);
|
||||
|
||||
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa],
|
||||
fft_shift(gNB->common_vars.txdataF[0][aa],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
frame_parms->N_RB_DL,
|
||||
fft_in_buff,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
0,
|
||||
12);
|
||||
|
||||
PHY_ofdm_mod((int *)fft_in_buff,
|
||||
(int *)&txdata[aa][samp],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
@@ -544,21 +555,30 @@ int main(int argc, char **argv)
|
||||
} else {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
gNB->common_vars.txdataF[0][aa],
|
||||
true,
|
||||
frame_parms->symbol_rotation[0],
|
||||
slot,
|
||||
frame_parms->N_RB_DL,
|
||||
0,
|
||||
14);
|
||||
|
||||
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa],
|
||||
(int*)&txdata[aa][samp],
|
||||
fft_shift(gNB->common_vars.txdataF[0][aa],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
frame_parms->N_RB_DL,
|
||||
fft_in_buff,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
0,
|
||||
14);
|
||||
|
||||
PHY_ofdm_mod((int *)fft_in_buff,
|
||||
(int *)&txdata[aa][samp],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples0,
|
||||
CYCLIC_PREFIX);
|
||||
|
||||
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][frame_parms->ofdm_symbol_size],
|
||||
(int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size],
|
||||
PHY_ofdm_mod((int *)fft_in_buff + frame_parms->ofdm_symbol_size,
|
||||
(int *)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
13,
|
||||
frame_parms->nb_prefix_samples,
|
||||
@@ -567,9 +587,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0][0],frame_length_complex_samples_no_prefix, 1, 1);
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[0][1],frame_length_complex_samples_no_prefix, 1, 1);
|
||||
LOG_M("txsigF0.m", "txsF0", gNB->common_vars.txdataF[0][0], frame_parms->samples_per_slot_wCP, 1, 1);
|
||||
if (gNB->frame_parms.nb_antennas_tx > 1)
|
||||
LOG_M("txsigF1.m", "txsF1", gNB->common_vars.txdataF[0][1], frame_parms->samples_per_slot_wCP, 1, 1);
|
||||
|
||||
} else {
|
||||
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
|
||||
|
||||
@@ -79,7 +79,7 @@ RU_t *ru;
|
||||
double cpuf;
|
||||
//uint8_t nfapi_mode=0;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint32_t N_RB_DL = 106;
|
||||
|
||||
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); }
|
||||
|
||||
@@ -71,7 +71,7 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, uint8_t *nb_dmrs_re_per
|
||||
}
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
THREAD_STRUCT thread_struct;
|
||||
instance_t DUuniqInstance = 0;
|
||||
instance_t CUuniqInstance = 0;
|
||||
@@ -246,7 +246,7 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, in
|
||||
sl_ue2->sl_config.sl_sync_source.rx_slss_id);
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &sl_ue1->sl_frame_params;
|
||||
const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size;
|
||||
const int samplesF_per_slot = fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32)));
|
||||
memset(txdataF_buf, 0, sizeof(txdataF_buf));
|
||||
c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */
|
||||
|
||||
@@ -53,7 +53,7 @@ THREAD_STRUCT thread_struct;
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
|
||||
@@ -48,7 +48,7 @@ PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
char *uecap_file = NULL;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
@@ -496,7 +496,7 @@ int main(int argc, char *argv[])
|
||||
proc.frame_tx = frame;
|
||||
proc.nr_slot_tx = slot;
|
||||
proc.nr_slot_rx = slot;
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
int slot_offset = get_samples_slot_timestamp(fp, slot);
|
||||
uint16_t ofdm_symbol_size = fp->ofdm_symbol_size;
|
||||
int slot_offsetF = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * ofdm_symbol_size;
|
||||
|
||||
@@ -55,7 +55,7 @@ THREAD_STRUCT thread_struct;
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
static softmodem_params_t softmodem_params;
|
||||
|
||||
@@ -106,7 +106,7 @@ PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
char *uecap_file;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int64_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
//uint8_t nfapi_mode = 0;
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef XNAP_MESSAGES_TYPES_H_
|
||||
#define XNAP_MESSAGES_TYPES_H_
|
||||
|
||||
#include "common/5g_platform_types.h"
|
||||
|
||||
typedef struct {
|
||||
// PLMN Identity
|
||||
plmn_id_t plmn;
|
||||
// Number of supported S-NSSAIs
|
||||
uint16_t num_nssai;
|
||||
// List of supported S-NSSAIs
|
||||
nssai_t *nssai;
|
||||
} xnap_plmn_support_t;
|
||||
|
||||
typedef struct {
|
||||
// Tracking Area Code
|
||||
uint32_t tac;
|
||||
// Number of supported PLMNs
|
||||
uint8_t num_plmn;
|
||||
// List of supported PLMNs
|
||||
xnap_plmn_support_t *plmn_support;
|
||||
} xnap_tai_support_t;
|
||||
|
||||
typedef struct {
|
||||
// PLMN Identity
|
||||
plmn_id_t plmn;
|
||||
// AMF Region Identifier
|
||||
uint8_t amf_region_id;
|
||||
} xnap_amf_region_info_t;
|
||||
|
||||
/* 3GPP TS 38.423 9.1.3.1 – Xn Setup Request */
|
||||
typedef struct {
|
||||
// Global NG-RAN Node ID (gNB_id+plmn) (M)
|
||||
uint32_t gNB_id;
|
||||
plmn_id_t plmn;
|
||||
// TAI Support List (M)
|
||||
uint16_t num_tai;
|
||||
xnap_tai_support_t *tai_support;
|
||||
// AMF Region Information (M)
|
||||
uint8_t num_amf_regions;
|
||||
xnap_amf_region_info_t *amf_region_info;
|
||||
} xnap_setup_req_t;
|
||||
|
||||
/* 3GPP TS 38.423 9.1.3.2 – Xn Setup Response */
|
||||
typedef struct {
|
||||
// Global NG-RAN Node ID (gNB_id+plmn) (M)
|
||||
uint32_t gNB_id;
|
||||
plmn_id_t plmn;
|
||||
// TAI Support List (M)
|
||||
uint16_t num_tai;
|
||||
xnap_tai_support_t *tai_support;
|
||||
} xnap_setup_resp_t;
|
||||
|
||||
typedef enum xnap_cause_radio_network_e {
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_CELL_NOT_AVAILABLE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_HANDOVER_DESIRABLE_FOR_RADIO_REASONS,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_HANDOVER_TARGET_NOT_ALLOWED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_INVALID_AMF_SET_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_NO_RADIO_RESOURCES_AVAILABLE_IN_TARGET_CELL,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_PARTIAL_HANDOVER,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_REDUCE_LOAD_IN_SERVING_CELL,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_RESOURCE_OPTIMISATION_HANDOVER,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TIME_CRITICAL_HANDOVER,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_RELOCOVERALL_EXPIRY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_RELOCPREP_EXPIRY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_GUAMI_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_LOCAL_NG_RAN_NODE_UE_XNAP_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_INCONSISTENT_REMOTE_NG_RAN_NODE_UE_XNAP_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_ENCRYPTION_AND_OR_INTEGRITY_PROTECTION_ALGORITHMS_NOT_SUPPORTED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_PROTECTION_ALGORITHMS_NOT_SUPPORTED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_MULTIPLE_PDU_SESSION_ID_INSTANCES,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_PDU_SESSION_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_QOS_FLOW_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_MULTIPLE_QOS_FLOW_ID_INSTANCES,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_SWITCH_OFF_ONGOING,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_NOT_SUPPORTED_5QI_VALUE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_DCOVERALL_EXPIRY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_DCPREP_EXPIRY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_ACTION_DESIRABLE_FOR_RADIO_REASONS,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_REDUCE_LOAD,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_RESOURCE_OPTIMISATION,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TIME_CRITICAL_ACTION,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_TARGET_NOT_ALLOWED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_NO_RADIO_RESOURCES_AVAILABLE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_INVALID_QOS_COMBINATION,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_ENCRYPTION_ALGORITHMS_NOT_SUPPORTED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_PROCEDURE_CANCELLED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_RRM_PURPOSE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_IMPROVE_USER_BIT_RATE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_USER_INACTIVITY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_RADIO_CONNECTION_WITH_UE_LOST,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_FAILURE_IN_THE_RADIO_INTERFACE_PROCEDURE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_BEARER_OPTION_NOT_SUPPORTED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UP_INTEGRITY_PROTECTION_NOT_POSSIBLE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UP_CONFIDENTIALITY_PROTECTION_NOT_POSSIBLE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_RESOURCES_NOT_AVAILABLE_FOR_THE_SLICE_S,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UE_MAX_IP_DATA_RATE_REASON,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_CP_INTEGRITY_PROTECTION_FAILURE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UP_INTEGRITY_PROTECTION_FAILURE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_SLICE_NOT_SUPPORTED_BY_NG_RAN,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_MN_MOBILITY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_SN_MOBILITY,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_COUNT_REACHES_MAX_VALUE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_OLD_NG_RAN_NODE_UE_XNAP_ID,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_PDCP_OVERLOAD,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_DRB_ID_NOT_AVAILABLE,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UNSPECIFIED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_UE_CONTEXT_ID_NOT_KNOWN,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_NON_RELOCATION_OF_CONTEXT,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_CHO_CPC_RESOURCES_TOBECHANGED,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_RSN_NOT_AVAILABLE_FOR_THE_UP,
|
||||
XNAP_CAUSE_RADIO_NETWORK_LAYER_NPN_ACCESS_DENIED
|
||||
} xnap_cause_radio_network_t;
|
||||
|
||||
typedef enum xnap_cause_transport_layer_e {
|
||||
XNAP_CAUSE_TRANSPORT_LAYER_TRANSPORT_RESOURCE_UNAVAILABLE,
|
||||
XNAP_CAUSE_TRANSPORT_LAYER_UNSPECIFIED
|
||||
} xnap_cause_transport_layer_t;
|
||||
|
||||
typedef enum xnap_cause_protocol_e {
|
||||
XNAP_CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR,
|
||||
XNAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT,
|
||||
XNAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE_AND_NOTIFY,
|
||||
XNAP_CAUSE_PROTOCOL_MESSAGE_NOT_COMPATIBLE_WITH_RECEIVER_STATE,
|
||||
XNAP_CAUSE_PROTOCOL_SEMANTIC_ERROR,
|
||||
XNAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED,
|
||||
XNAP_CAUSE_PROTOCOL_UNSPECIFIED
|
||||
} xnap_cause_protocol_t;
|
||||
|
||||
typedef enum xnap_cause_misc_e {
|
||||
XNAP_CAUSE_MISC_CONTROL_PROCESSING_OVERLOAD,
|
||||
XNAP_CAUSE_MISC_HARDWARE_FAILURE,
|
||||
XNAP_CAUSE_MISC_O_AND_M_INTERVENTION,
|
||||
XNAP_CAUSE_MISC_NOT_ENOUGH_USER_PLANE_PROCESSING_RESOURCES,
|
||||
XNAP_CAUSE_MISC_UNSPECIFIED
|
||||
} xnap_cause_misc_t;
|
||||
|
||||
typedef enum xnap_cause_group_e {
|
||||
XNAP_CAUSE_NOTHING,
|
||||
XNAP_CAUSE_RADIO_NETWORK,
|
||||
XNAP_CAUSE_TRANSPORT,
|
||||
XNAP_CAUSE_PROTOCOL,
|
||||
XNAP_CAUSE_MISC,
|
||||
} xnap_cause_group_t;
|
||||
|
||||
typedef struct xnap_cause_s {
|
||||
/* Cause group (e.g. radioNetwork, transport, protocol, misc) */
|
||||
xnap_cause_group_t type;
|
||||
/* Specific cause value within the selected cause group */
|
||||
uint8_t value;
|
||||
} xnap_cause_t;
|
||||
|
||||
/* 3GPP TS 38.423 9.1.3.3 – Xn Setup Failure */
|
||||
typedef struct {
|
||||
// Cause (M)
|
||||
xnap_cause_t cause;
|
||||
} xnap_setup_failure_t;
|
||||
|
||||
#endif /* XNAP_MESSAGES_TYPES_H_ */
|
||||
@@ -1184,6 +1184,7 @@ typedef struct {
|
||||
} nr_prach_info_3gpp_fr2_t;
|
||||
|
||||
// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum
|
||||
// and NTN-FR2 and paired as defined in 38.211v18.06
|
||||
static const nr_prach_info_3gpp_fr2_t table_6_3_3_2_4_prachConfig_Index[256] = {
|
||||
// format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot,
|
||||
// duration
|
||||
@@ -1458,7 +1459,8 @@ int get_format0(uint8_t index, uint8_t unpaired, frequency_range_t frequency_ran
|
||||
if (frequency_range==FR1)
|
||||
format = table_6_3_3_2_2_prachConfig_Index[index].format;
|
||||
else
|
||||
AssertFatal(0==1,"no paired spectrum for FR2\n");
|
||||
// Table defined for NTN-FR2 and paired in 3GPP Spec 38.211v18.06
|
||||
format = table_6_3_3_2_4_prachConfig_Index[index].format;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
@@ -96,28 +96,28 @@ static void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, const frame_str
|
||||
for (int i = 0; i < fs->numb_slots_period; i++) {
|
||||
fapi_nr_max_tdd_periodicity_t *period_list = &tdd_table->max_tdd_periodicity_list[i];
|
||||
period_list->max_num_of_symbol_per_slot_list =
|
||||
malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT * sizeof(*period_list->max_num_of_symbol_per_slot_list));
|
||||
malloc(NR_SYMBOLS_PER_SLOT * sizeof(*period_list->max_num_of_symbol_per_slot_list));
|
||||
if (pc->tdd_slot_bitmap[i].slot_type == TDD_NR_DOWNLINK_SLOT) {
|
||||
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) {
|
||||
for (int s = 0; s < NR_SYMBOLS_PER_SLOT; s++) {
|
||||
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 0;
|
||||
}
|
||||
}
|
||||
if (pc->tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) {
|
||||
for (int s = 0; s < NR_SYMBOLS_PER_SLOT; s++) {
|
||||
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 1;
|
||||
}
|
||||
}
|
||||
if (pc->tdd_slot_bitmap[i].slot_type == TDD_NR_MIXED_SLOT) {
|
||||
int dl_symb = pc->tdd_slot_bitmap[i].num_dl_symbols;
|
||||
int ul_symb = pc->tdd_slot_bitmap[i].num_ul_symbols;
|
||||
int g_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT - dl_symb - ul_symb;
|
||||
int g_symb = NR_SYMBOLS_PER_SLOT - dl_symb - ul_symb;
|
||||
for (int s = 0; s < dl_symb; s++) {
|
||||
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 0;
|
||||
}
|
||||
for (int s = dl_symb; s < dl_symb + g_symb; s++) {
|
||||
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 2;
|
||||
}
|
||||
for (int s = dl_symb + g_symb; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) {
|
||||
for (int s = dl_symb + g_symb; s < NR_SYMBOLS_PER_SLOT; s++) {
|
||||
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,19 +77,19 @@ void sl_set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
|
||||
|
||||
for(int memory_alloc = 0 ; memory_alloc < nb_slots_per_period; memory_alloc++)
|
||||
tdd_table->max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list =
|
||||
(fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof(fapi_nr_max_num_of_symbol_per_slot_t));
|
||||
(fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_SYMBOLS_PER_SLOT*sizeof(fapi_nr_max_num_of_symbol_per_slot_t));
|
||||
|
||||
int slot_number = (nb_slots_per_period - nrofUplinkSlots) - (nrofUplinkSymbols ? 1 : 0);
|
||||
if (nrofUplinkSymbols != 0) {
|
||||
for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
|
||||
for(int number_of_symbol = NR_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol < NR_SYMBOLS_PER_SLOT; number_of_symbol++) {
|
||||
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 1;
|
||||
}
|
||||
slot_number++;
|
||||
}
|
||||
while(slot_number < nb_slots_per_period) {
|
||||
for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
|
||||
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 1;
|
||||
if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
|
||||
for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots * NR_SYMBOLS_PER_SLOT; number_of_symbol++) {
|
||||
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_SYMBOLS_PER_SLOT].slot_config = 1;
|
||||
if((number_of_symbol + 1) % NR_SYMBOLS_PER_SLOT == 0)
|
||||
slot_number++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,8 +425,8 @@ static bool check_mixed_slot_prach(frame_structure_t *fs, int slot, int start_pr
|
||||
tdd_bitmap_t *bitmap = &fs->period_cfg.tdd_slot_bitmap[slot % fs->numb_slots_period];
|
||||
if (bitmap->num_ul_symbols == 0)
|
||||
return false;
|
||||
int ul_end = NR_NUMBER_OF_SYMBOLS_PER_SLOT - 1;
|
||||
int ul_start = NR_NUMBER_OF_SYMBOLS_PER_SLOT - bitmap->num_ul_symbols;
|
||||
int ul_end = NR_SYMBOLS_PER_SLOT - 1;
|
||||
int ul_start = NR_SYMBOLS_PER_SLOT - bitmap->num_ul_symbols;
|
||||
if (start_prach < ul_start || end_prach > ul_end)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3898,6 +3898,8 @@ static int nr_ue_validate_successrar(uint8_t *pduP, int32_t pdu_len, NR_UE_MAC_I
|
||||
return n;
|
||||
}
|
||||
|
||||
#define MAX_NUM_DATA_IND 1024
|
||||
|
||||
///////////////////////////////////
|
||||
// brief: nr_ue_process_mac_pdu
|
||||
// function: parsing DL PDU header
|
||||
@@ -3962,6 +3964,9 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_
|
||||
pdu_len -= n;
|
||||
}
|
||||
|
||||
nr_rlc_data_ind_t data_ind[MAX_NUM_DATA_IND] = {0};
|
||||
int num_data_ind = 0;
|
||||
|
||||
while (!done && pdu_len > 0){
|
||||
uint16_t mac_len = 0x0000;
|
||||
uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
|
||||
@@ -3992,7 +3997,9 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_
|
||||
|
||||
if (mac_len > 0) {
|
||||
LOG_DDUMP(NR_MAC, (void *)pduP, mac_subheader_len + mac_len, LOG_DUMP_CHAR, "DL_SCH_LCID_CCCH (e.g. RRCSetup) payload: ");
|
||||
nr_mac_rlc_data_ind(mac->ue_id, mac->ue_id, false, rx_lcid, (char *)(pduP + mac_subheader_len), mac_len);
|
||||
nr_rlc_data_ind_t ind = {.ch = rx_lcid, .buf = pduP + mac_subheader_len, .len = mac_len};
|
||||
data_ind[num_data_ind++] = ind;
|
||||
DevAssert(num_data_ind < MAX_NUM_DATA_IND);
|
||||
}
|
||||
break;
|
||||
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
|
||||
@@ -4104,15 +4111,20 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_
|
||||
// MAC SDU
|
||||
// From values 1 to 32 it equals to the identity of the logical channel
|
||||
case 1 ... 32:
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return;
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) {
|
||||
LOG_E(MAC, "get_mac_len(): invalid pdu_len %d (mac_len %d mac_subheader_len %d)\n", pdu_len, mac_len, mac_subheader_len);
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
// discard the received subPDU if RB is suspended
|
||||
if (is_lcid_suspended(mac, rx_lcid)) {
|
||||
LOG_W(NR_MAC, "Received PDU for a suspended RB, corresponding to LCID %d. Dropping it.\n", rx_lcid);
|
||||
break;
|
||||
}
|
||||
LOG_D(NR_MAC, "%4d.%2d : DLSCH -> LCID %d %d bytes\n", frameP, slot, rx_lcid, mac_len);
|
||||
nr_mac_rlc_data_ind(mac->ue_id, mac->ue_id, false, rx_lcid, (char *)(pduP + mac_subheader_len), mac_len);
|
||||
nr_rlc_data_ind_t ind = {.ch = rx_lcid, .buf = pduP + mac_subheader_len, .len = mac_len};
|
||||
data_ind[num_data_ind++] = ind;
|
||||
DevAssert(num_data_ind < MAX_NUM_DATA_IND);
|
||||
break;
|
||||
default:
|
||||
LOG_W(MAC, "unknown lcid %02x\n", rx_lcid);
|
||||
@@ -4120,9 +4132,13 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_
|
||||
}
|
||||
pduP += (mac_subheader_len + mac_len);
|
||||
pdu_len -= (mac_subheader_len + mac_len);
|
||||
if (pdu_len < 0)
|
||||
if (pdu_len < 0) {
|
||||
LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", mac->ue_id, frameP, slot, pdu_len);
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
nr_mac_rlc_data_ind(mac->ue_id, mac->ue_id, false, data_ind, num_data_ind);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1461,23 +1461,24 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent)
|
||||
|
||||
static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP)
|
||||
{
|
||||
logical_chan_id_t ch[NR_MAX_NUM_LCID] = {0};
|
||||
int n = 0;
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||
if (lc_info->rb_suspended)
|
||||
continue;
|
||||
int lcid = lc_info->lcid;
|
||||
ch[n++] = lc_info->lcid;
|
||||
}
|
||||
|
||||
mac_rlc_status_resp_t ret[NR_MAX_NUM_LCID] = {0};
|
||||
nr_mac_rlc_status_ind(mac->ue_id, frameP, n, ch, ret);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
const logical_chan_id_t lcid = ch[i];
|
||||
const rlc_buffer_occupancy_t b = ret[i].bytes_in_buffer;
|
||||
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
mac_rlc_status_resp_t rlc_status = nr_mac_rlc_status_ind(mac->ue_id, frameP, lcid);
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(NR_MAC,
|
||||
"[UE %d] LCID %d has %d bytes to transmit at sfn %d.%d\n",
|
||||
mac->ue_id,
|
||||
lcid,
|
||||
rlc_status.bytes_in_buffer,
|
||||
frameP,
|
||||
slotP);
|
||||
}
|
||||
lc_sched_info->LCID_buffer_remain = rlc_status.bytes_in_buffer;
|
||||
if (b > 0)
|
||||
LOG_D(NR_MAC, "[UE %d] LCID %d has %d bytes to transmit at sfn %d.%d\n", mac->ue_id, lcid, b, frameP, slotP);
|
||||
lc_sched_info->LCID_buffer_remain = b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ static uint8_t sl_get_elapsed_slots(uint32_t slot, uint32_t sl_slot_bitmap)
|
||||
*/
|
||||
static uint8_t sl_determine_if_sidelink_slot(uint8_t sl_startsym, uint8_t sl_lensym, uint8_t num_ulsym)
|
||||
{
|
||||
uint8_t ul_startsym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - num_ulsym;
|
||||
uint8_t ul_startsym = NR_SYMBOLS_PER_SLOT - num_ulsym;
|
||||
|
||||
if ((sl_startsym >= ul_startsym) && (sl_lensym <= NR_NUMBER_OF_SYMBOLS_PER_SLOT)) {
|
||||
if ((sl_startsym >= ul_startsym) && (sl_lensym <= NR_SYMBOLS_PER_SLOT)) {
|
||||
LOG_D(MAC,
|
||||
"MIXED SLOT is a SIDELINK SLOT. Sidelink Symbols: %d-%d, Uplink Symbols: %d-%d\n",
|
||||
sl_startsym,
|
||||
@@ -107,13 +107,13 @@ int sl_nr_ue_slot_select(const sl_nr_phy_config_request_t *cfg, int slot, uint8_
|
||||
|
||||
const fapi_nr_max_tdd_periodicity_t *current_slot = &tdd_table->max_tdd_periodicity_list[rel_slot];
|
||||
|
||||
for (int symbol_count = 0; symbol_count < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
for (int symbol_count = 0; symbol_count < NR_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
if (current_slot->max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
|
||||
ul_sym++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ul_sym == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
|
||||
if (ul_sym == NR_SYMBOLS_PER_SLOT) {
|
||||
slot_type = NR_SIDELINK_SLOT;
|
||||
} else if (ul_sym) {
|
||||
slot_type = sl_determine_if_sidelink_slot(cfg->sl_bwp_config.sl_start_symbol, cfg->sl_bwp_config.sl_num_symbols, ul_sym);
|
||||
|
||||
@@ -1024,7 +1024,7 @@ static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
|
||||
int s = get_slot_idx_in_period(temp_slot, fs);
|
||||
const tdd_bitmap_t *bm = &fs->period_cfg.tdd_slot_bitmap[s];
|
||||
bool is_mixed = is_mixed_slot(s, fs);
|
||||
uint16_t slot_mask = is_mixed ? SL_to_bitmap(NR_NUMBER_OF_SYMBOLS_PER_SLOT - bm->num_ul_symbols, bm->num_ul_symbols) : 0x3fff;
|
||||
uint16_t slot_mask = is_mixed ? SL_to_bitmap(NR_SYMBOLS_PER_SLOT - bm->num_ul_symbols, bm->num_ul_symbols) : 0x3fff;
|
||||
long startSymbolAndLength = tda_list->list.array[i]->startSymbolAndLength;
|
||||
int start, nr;
|
||||
SLIV2SL(startSymbolAndLength, &start, &nr);
|
||||
@@ -1699,21 +1699,23 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||
int current_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
|
||||
logical_chan_id_t lcid = DL_SCH_LCID_CCCH;
|
||||
logical_chan_id_t lcid = 0;
|
||||
if (current_harq_pid < 0) {
|
||||
// Check for data on SRB0 (RRCSetup)
|
||||
mac_rlc_status_resp_t srb_status = nr_mac_rlc_status_ind(UE->rnti, frameP, lcid);
|
||||
const logical_chan_id_t lcid_l[2] = {DL_SCH_LCID_CCCH, DL_SCH_LCID_DCCH};
|
||||
mac_rlc_status_resp_t stat[2];
|
||||
nr_mac_rlc_status_ind(UE->rnti, frameP, 2, lcid_l, stat);
|
||||
|
||||
if (srb_status.bytes_in_buffer == 0) {
|
||||
lcid = DL_SCH_LCID_DCCH;
|
||||
// Check for data on SRB1 (RRCReestablishment, RRCReconfiguration)
|
||||
srb_status = nr_mac_rlc_status_ind(UE->rnti, frameP, lcid);
|
||||
if (stat[0].bytes_in_buffer > 0) {
|
||||
// some data in SRB0 (likely RRCSetup)
|
||||
mac_sdu_length = stat[0].bytes_in_buffer;
|
||||
lcid = lcid_l[0];
|
||||
} else if (stat[1].bytes_in_buffer > 0) {
|
||||
// some data in SRB1 (likely RRCReestablishmnt/RRCReconfiguration)
|
||||
mac_sdu_length = stat[1].bytes_in_buffer;
|
||||
lcid = lcid_l[1];
|
||||
} else {
|
||||
return; // no data to forward
|
||||
}
|
||||
|
||||
// Need to wait until data for Msg4 is ready
|
||||
if (srb_status.bytes_in_buffer == 0)
|
||||
return;
|
||||
mac_sdu_length = srb_status.bytes_in_buffer;
|
||||
}
|
||||
|
||||
const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame;
|
||||
|
||||
@@ -101,7 +101,7 @@ static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc,
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map[beam];
|
||||
const int extra_prb = ssb_subcarrier_offset > 0;
|
||||
for (int rb = 0; rb < 20 + extra_prb; rb++)
|
||||
vrb_map[rbStart + rb] = SL_to_bitmap(symStart % NR_NUMBER_OF_SYMBOLS_PER_SLOT, 4);
|
||||
vrb_map[rbStart + rb] = SL_to_bitmap(symStart % NR_SYMBOLS_PER_SLOT, 4);
|
||||
}
|
||||
|
||||
static int encode_mib(NR_BCCH_BCH_Message_t *mib, frame_t frame, uint8_t *buffer, int buf_size)
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
#define WORD 32
|
||||
//#define SIZE_OF_POINTER sizeof (void *)
|
||||
|
||||
#define MAX_NUM_DATA_REQ 1024
|
||||
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot)
|
||||
{
|
||||
/* we assume that this function is mutex-protected from outside */
|
||||
@@ -326,31 +328,38 @@ static uint32_t update_dlsch_buffer(frame_t frame, slot_t slot, NR_UE_info_t *UE
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
sched_ctrl->dl_pdus_total = 0;
|
||||
|
||||
logical_chan_id_t ch[NR_MAX_NUM_LCID] = {0};
|
||||
int n = 0;
|
||||
/* loop over all activated logical channels */
|
||||
for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) {
|
||||
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i);
|
||||
const int lcid = c->lcid;
|
||||
const uint16_t rnti = UE->rnti;
|
||||
LOG_D(NR_MAC, "UE %x: LCID %d\n", rnti, lcid);
|
||||
memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid]));
|
||||
if (c->suspended)
|
||||
FOR_EACH_SEQ_ARR(const nr_lc_config_t *, c, &sched_ctrl->lc_config ) {
|
||||
logical_chan_id_t lcid = c->lcid;
|
||||
if (c->suspended || (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt))) {
|
||||
memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid]));
|
||||
continue;
|
||||
if (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt))
|
||||
continue;
|
||||
sched_ctrl->rlc_status[lcid] = nr_mac_rlc_status_ind(rnti, frame, lcid);
|
||||
}
|
||||
ch[n++] = lcid;
|
||||
}
|
||||
|
||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||
mac_rlc_status_resp_t ret[NR_MAX_NUM_LCID] = {0};
|
||||
nr_mac_rlc_status_ind(UE->rnti, frame, n, ch, ret);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
logical_chan_id_t lcid = ch[i];
|
||||
|
||||
if (ret[i].bytes_in_buffer == 0)
|
||||
continue;
|
||||
|
||||
sched_ctrl->rlc_status[lcid] = ret[i];
|
||||
sched_ctrl->dl_pdus_total += sched_ctrl->rlc_status[lcid].pdus_in_buffer;
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d UE %04x LCID %d status: %d bytes, total buffer %d bytes %d PDUs\n",
|
||||
"%4d.%2d UE %04x LCID %d status: %d bytes, %d PDUs, total buffer %d bytes %d PDUs\n",
|
||||
frame,
|
||||
slot,
|
||||
UE->rnti,
|
||||
lcid,
|
||||
sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||
ret[i].bytes_in_buffer,
|
||||
ret[i].pdus_in_buffer,
|
||||
sched_ctrl->num_total_bytes,
|
||||
sched_ctrl->dl_pdus_total);
|
||||
}
|
||||
@@ -1289,47 +1298,25 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
|
||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||
continue; // no data for this LC tbs_size_t len = 0;
|
||||
|
||||
int lcid_bytes=0;
|
||||
while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) {
|
||||
// we do not know how much data we will get from RLC, i.e., whether it
|
||||
// will be longer than 256B or not. Therefore, reserve space for long header, then
|
||||
// fetch data, then fill real length
|
||||
|
||||
tb_size_t pdu_siz[MAX_NUM_DATA_REQ];
|
||||
int num = nr_mac_rlc_multi_data_req(module_id, rnti, true, lcid, bufEnd - buf, (char *)buf, pdu_siz, sizeofArray(pdu_siz));
|
||||
DevAssert(num <= sizeofArray(pdu_siz));
|
||||
|
||||
sdus += num;
|
||||
int lcid_bytes = 0;
|
||||
for (int j = 0; j < num; ++j) {
|
||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||
/* limit requested number of bytes to what preprocessor specified, or
|
||||
* such that TBS is full */
|
||||
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
tbs_size_t len = nr_mac_rlc_data_req(module_id,
|
||||
rnti,
|
||||
true,
|
||||
lcid,
|
||||
ndata,
|
||||
(char *)buf+sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n",
|
||||
frame,
|
||||
slot,
|
||||
rnti,
|
||||
len,
|
||||
lcid < 4 ? "DCCH" : "DTCH",
|
||||
lcid,
|
||||
ndata,
|
||||
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
|
||||
T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid)));
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = lcid;
|
||||
header->L = htons(len);
|
||||
buf += len+sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
dlsch_total_bytes += len;
|
||||
lcid_bytes += len;
|
||||
sdus += 1;
|
||||
header->L = htons(pdu_siz[j]);
|
||||
buf += pdu_siz[j] + sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
dlsch_total_bytes += pdu_siz[j];
|
||||
lcid_bytes += pdu_siz[j];
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(lcid_bytes), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid)));
|
||||
UE->mac_stats.dl.lc_bytes[lcid] += lcid_bytes;
|
||||
}
|
||||
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
|
||||
|
||||
@@ -104,7 +104,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
|
||||
// select beam for PDSCH in current slot based on SSB beam
|
||||
if ((ssb_start_symbol / NR_NUMBER_OF_SYMBOLS_PER_SLOT) == (slot % mac->frame_structure.numb_slots_period)) {
|
||||
if ((ssb_start_symbol / NR_SYMBOLS_PER_SLOT) == (slot % mac->frame_structure.numb_slots_period)) {
|
||||
ssb_idx_beam = i_ssb;
|
||||
break;
|
||||
}
|
||||
@@ -144,11 +144,11 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
DevAssert(seq_arr_size(&sched_ctrl->lc_config) == 1);
|
||||
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, 0);
|
||||
const int lcid = c->lcid;
|
||||
const logical_chan_id_t lcid = c->lcid;
|
||||
const uint16_t rnti = UE->rnti;
|
||||
/* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
|
||||
* if available */
|
||||
sched_ctrl->rlc_status[lcid] = nr_mac_rlc_status_ind(rnti, frame, lcid);
|
||||
nr_mac_rlc_status_ind(rnti, frame, 1, &lcid, &sched_ctrl->rlc_status[lcid]);
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
|
||||
int CCEIndex = get_cce_index(mac,
|
||||
|
||||
@@ -479,7 +479,7 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac,
|
||||
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
|
||||
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
|
||||
uint16_t num = 1 << srs_pdu->num_symbols; // 0,1,2 means 1,2,4 symbols, see 222.10.04 table 3-105
|
||||
const uint8_t l0 = NR_NUMBER_OF_SYMBOLS_PER_SLOT - 1 - srs_pdu->time_start_position;
|
||||
const uint8_t l0 = NR_SYMBOLS_PER_SLOT - 1 - srs_pdu->time_start_position;
|
||||
uint16_t mask = SL_to_bitmap(l0, num);
|
||||
DevAssert(mask != 0);
|
||||
for (int i = 0; i < srs_pdu->bwp_size; ++i) {
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
|
||||
//#define SRS_IND_DEBUG
|
||||
#define MAX_NUM_DATA_IND 1024
|
||||
|
||||
/* \brief Get the number of UL TDAs that could be used in slot, reachable
|
||||
* via specific k2. The output parameter first_idx is a pointer to the first
|
||||
@@ -395,6 +396,8 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
log_dump(NR_MAC, pduP, pdu_len, LOG_DUMP_CHAR, "\n");
|
||||
#endif
|
||||
|
||||
nr_rlc_data_ind_t data_ind[MAX_NUM_DATA_IND] = {0};
|
||||
int num_data_ind = 0;
|
||||
while (pdu_len > 0) {
|
||||
uint16_t mac_len = 0;
|
||||
uint8_t lcid = 0;
|
||||
@@ -416,7 +419,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
for (int i = 0; i < print_len; i++)
|
||||
printf("%02x ", pduP[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
@@ -456,7 +459,9 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
}
|
||||
|
||||
if (prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE)) {
|
||||
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, 0, (char *)(pduP + mac_subheader_len), mac_len);
|
||||
nr_rlc_data_ind_t ind = {.ch = 0, .buf = pduP + mac_subheader_len, .len = mac_len};
|
||||
data_ind[num_data_ind++] = ind;
|
||||
DevAssert(num_data_ind < MAX_NUM_DATA_IND);
|
||||
} else {
|
||||
LOG_E(NR_MAC, "prepare_initial_ul_rrc_message() returned false, cannot forward CCCH message\n");
|
||||
}
|
||||
@@ -475,7 +480,9 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
if (!srbc || srbc->suspended) {
|
||||
LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len);
|
||||
} else {
|
||||
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len);
|
||||
nr_rlc_data_ind_t ind = {.ch = lcid, .buf = pduP + mac_subheader_len, .len = mac_len};
|
||||
data_ind[num_data_ind++] = ind;
|
||||
DevAssert(num_data_ind < MAX_NUM_DATA_IND);
|
||||
|
||||
UE->mac_stats.ul.total_sdu_bytes += mac_len;
|
||||
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
|
||||
@@ -499,7 +506,9 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
} else {
|
||||
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
|
||||
|
||||
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len);
|
||||
nr_rlc_data_ind_t ind = {.ch = lcid, .buf = pduP + mac_subheader_len, .len = mac_len};
|
||||
data_ind[num_data_ind++] = ind;
|
||||
DevAssert(num_data_ind < MAX_NUM_DATA_IND);
|
||||
|
||||
sdus += 1;
|
||||
/* Updated estimated buffer when receiving data */
|
||||
@@ -530,7 +539,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
||||
if (harq_pid < 0) {
|
||||
LOG_E(NR_MAC, "Invalid HARQ PID %d\n", harq_pid);
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
|
||||
|
||||
@@ -605,14 +614,18 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
|
||||
case UL_SCH_LCID_PADDING:
|
||||
// End of MAC PDU, can ignore the rest.
|
||||
return 0;
|
||||
// 38.321 Sec 6.1.5: "Presence and length of padding is implicit based
|
||||
// on TB size, size of MAC subPDU(s)."
|
||||
mac_len = pdu_len - mac_subheader_len; // will make pdu_len go to 0
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_MAC, "RNTI %0x [%d.%d], received unknown MAC header (LCID = 0x%02x)\n", UE->rnti, frameP, slot, lcid);
|
||||
return -1;
|
||||
mac_len = pdu_len - mac_subheader_len; // will make pdu_len go to 0
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||
if (lcid < 45 || lcid == 52 || lcid == 63) {
|
||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, lcid);
|
||||
@@ -629,6 +642,8 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
pdu_len -= (mac_subheader_len + mac_len);
|
||||
}
|
||||
|
||||
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, data_ind, num_data_ind);
|
||||
|
||||
UE->mac_stats.ul.num_mac_sdu += sdus;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1145,7 +1145,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i
|
||||
int nb_slots_per_period = ((1 << mu) * 10) / nb_periods_per_frame;
|
||||
|
||||
// make TDA for the mixed slot
|
||||
long mixed_sliv = get_SLIV(NR_NUMBER_OF_SYMBOLS_PER_SLOT - ul_symb, ul_symb - 1);
|
||||
long mixed_sliv = get_SLIV(NR_SYMBOLS_PER_SLOT - ul_symb, ul_symb - 1);
|
||||
int mixed_min_ul_symb = 3; // need at least two symbols PUSCH + PUCCH
|
||||
bool has_ul_mixed = ul_symb >= mixed_min_ul_symb;
|
||||
if (has_ul_mixed && (k2 <= N_dl1 || (p2 && N_ul2 == 0))) {
|
||||
@@ -1207,10 +1207,16 @@ static void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedbac
|
||||
long *delay[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int curr_delay = i + min_feedback_time;
|
||||
// dl-DataToUL-ACK SEQUENCE (SIZE (1..8)) OF INTEGER (0..15)
|
||||
if (curr_delay > 15)
|
||||
break;
|
||||
delay[i] = calloc(1,sizeof(*delay[i]));
|
||||
*delay[i] = curr_delay;
|
||||
asn1cSeqAdd(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
|
||||
}
|
||||
AssertFatal(pucch_Config->dl_DataToUL_ACK->list.count > 0,
|
||||
"Minimum feedback time too high %d, cannot set any dl_DataToUL_ACK value\n",
|
||||
min_feedback_time);
|
||||
}
|
||||
|
||||
// PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213)
|
||||
|
||||
@@ -163,12 +163,12 @@ void nr_rlc_release_entity(int ue_id, logical_chan_id_t channel_id)
|
||||
void nr_mac_rlc_data_ind(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
const logical_chan_id_t channel_idP,
|
||||
char *buffer_pP,
|
||||
const tb_size_t tb_sizeP)
|
||||
const nr_rlc_data_ind_t *data,
|
||||
int num_data)
|
||||
{
|
||||
if (gnb_flagP)
|
||||
T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(ue_id), T_INT(channel_idP), T_INT(tb_sizeP));
|
||||
for (int i = 0; i < num_data; ++i)
|
||||
T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(ue_id), T_INT(data[i].ch), T_INT(data[i].len));
|
||||
|
||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
||||
@@ -176,20 +176,65 @@ void nr_mac_rlc_data_ind(const module_id_t module_idP,
|
||||
if(ue == NULL)
|
||||
LOG_I(RLC, "RLC instance for the given UE was not found \n");
|
||||
|
||||
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
||||
|
||||
if (rb != NULL) {
|
||||
LOG_D(RLC, "RB found! (channel ID %d) \n", channel_idP);
|
||||
rb->set_time(rb, get_nr_rlc_current_time());
|
||||
rb->recv_pdu(rb, buffer_pP, tb_sizeP);
|
||||
} else {
|
||||
LOG_E(RLC, "Fatal: no RB found (channel ID %d UE ID %d)\n", channel_idP, ue_id);
|
||||
// exit(1);
|
||||
for (int i = 0; i < num_data; ++i) {
|
||||
logical_chan_id_t ch = data[i].ch;
|
||||
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, ch);
|
||||
if (rb != NULL) {
|
||||
LOG_D(RLC, "RB found! (channel ID %d) \n", ch);
|
||||
rb->set_time(rb, get_nr_rlc_current_time());
|
||||
rb->recv_pdu(rb, (char *)data[i].buf, data[i].len);
|
||||
} else {
|
||||
LOG_W(RLC, "no RB found (channel ID %d UE ID %d)\n", ch, ue_id);
|
||||
}
|
||||
}
|
||||
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
|
||||
int nr_mac_rlc_multi_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
const logical_chan_id_t channel_idP,
|
||||
tb_size_t tb_sizeP,
|
||||
char *buffer_pP,
|
||||
tb_size_t *pdu_siz,
|
||||
int pdu_siz_len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
||||
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
||||
|
||||
if (rb != NULL) {
|
||||
rb->set_time(rb, get_nr_rlc_current_time());
|
||||
while (tb_sizeP - 3 > 0 && pdu_siz_len > 0) {
|
||||
// fill PDU in buffer, store size of PDU
|
||||
pdu_siz[0] = rb->generate_pdu(rb, buffer_pP + 3, tb_sizeP - 3);
|
||||
if (pdu_siz[0] == 0)
|
||||
break;
|
||||
LOG_D(RLC, "MAC PDU created: channel_idP %d len %d\n", channel_idP, pdu_siz[0]);
|
||||
// reserve header
|
||||
tb_sizeP -= 3 + pdu_siz[0];
|
||||
buffer_pP += 3 + pdu_siz[0];
|
||||
pdu_siz++;
|
||||
pdu_siz_len--;
|
||||
ret++;
|
||||
}
|
||||
} else {
|
||||
LOG_D(RLC, "MAC PDU failed to get created for channel_idP:%d \n", channel_idP);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
|
||||
if (gnb_flagP)
|
||||
T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(ue_id),
|
||||
T_INT(channel_idP), T_INT(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tbs_size_t nr_mac_rlc_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
@@ -223,12 +268,10 @@ tbs_size_t nr_mac_rlc_data_req(const module_id_t module_idP,
|
||||
return ret;
|
||||
}
|
||||
|
||||
mac_rlc_status_resp_t nr_mac_rlc_status_ind(const uint16_t ue_id, const frame_t frame, const logical_chan_id_t channel_idP)
|
||||
static mac_rlc_status_resp_t _nr_rlc_status_ind(nr_rlc_ue_t *ue, frame_t frame, logical_chan_id_t channel_idP)
|
||||
{
|
||||
mac_rlc_status_resp_t ret;
|
||||
|
||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
||||
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
||||
|
||||
if (rb != NULL) {
|
||||
@@ -243,12 +286,10 @@ mac_rlc_status_resp_t nr_mac_rlc_status_ind(const uint16_t ue_id, const frame_t
|
||||
ret.bytes_in_buffer = buf_stat.status_size + buf_stat.retx_size + buf_stat.tx_size;
|
||||
} else {
|
||||
if (!(frame % 128) || channel_idP == 0) //to suppress this warning message
|
||||
LOG_W(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id);
|
||||
LOG_W(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue->ue_id);
|
||||
ret.bytes_in_buffer = 0;
|
||||
}
|
||||
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
|
||||
ret.pdus_in_buffer = 0;
|
||||
/* TODO: creation time may be important (unit: frame, as it seems) */
|
||||
ret.head_sdu_creation_time = 0;
|
||||
@@ -257,6 +298,16 @@ mac_rlc_status_resp_t nr_mac_rlc_status_ind(const uint16_t ue_id, const frame_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nr_mac_rlc_status_ind(uint16_t ue_id, frame_t frame, int n_ch, const logical_chan_id_t *ch, mac_rlc_status_resp_t *ret)
|
||||
{
|
||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
||||
for (int i = 0; i < n_ch; ++i) {
|
||||
ret[i] = _nr_rlc_status_ind(ue, frame, ch[i]);
|
||||
}
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
|
||||
rlc_op_status_t nr_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
@@ -1022,7 +1073,7 @@ bool nr_rlc_get_statistics(int ue_id, int srb_flag, int rb_id, nr_rlc_statistics
|
||||
|
||||
// Patch buffer status using OAI results (no need to change anything in the RB)
|
||||
// rb->set_time(rb, get_nr_rlc_current_time());
|
||||
nr_rlc_entity_buffer_status_t oai_stat = rb->buffer_status(rb, 1000*1000);
|
||||
nr_rlc_entity_buffer_status_t oai_stat = rb->buffer_status(rb, 256 * 1000);
|
||||
out->rxbuf_occ_bytes = oai_stat.status_size;
|
||||
out->txbuf_occ_bytes = oai_stat.tx_size + oai_stat.retx_size;
|
||||
} else {
|
||||
|
||||
@@ -41,12 +41,32 @@ struct NR_RLC_Config;
|
||||
struct NR_LogicalChannelConfig;
|
||||
|
||||
int nr_rlc_module_init(nr_rlc_op_mode_t mode);
|
||||
typedef struct nr_rlc_data_ind {
|
||||
logical_chan_id_t ch;
|
||||
uint8_t *buf;
|
||||
tb_size_t len;
|
||||
} nr_rlc_data_ind_t;
|
||||
void nr_mac_rlc_data_ind(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
const logical_chan_id_t channel_idP,
|
||||
char *buffer_pP,
|
||||
const tb_size_t tb_sizeP);
|
||||
const nr_rlc_data_ind_t *data,
|
||||
int num_data);
|
||||
/* \brief Fill up to pdu_siz_len RLC PDUs into buffer pointed to by buffer_pP,
|
||||
* or until tb_sizeP is reached. Each PDU is preceded by 3 bytes (nothing is
|
||||
* written) that have to be filled by the consumer (with a MAC sub-PDU
|
||||
* subheader). This function fills up to an entire TB in a single call, unlike
|
||||
* nr_mac_rlc_data_req() that fills only one RLC PDU in one step. */
|
||||
int nr_mac_rlc_multi_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
const logical_chan_id_t channel_idP,
|
||||
const tb_size_t tb_sizeP,
|
||||
char *buffer_pP,
|
||||
tb_size_t *pdu_siz,
|
||||
int pdu_siz_len);
|
||||
/* \brief Fill one RLC PDU into buffer pointed to by buffer_pP, or until
|
||||
* tb_sizeP is reached. Note that NO header is prepended (for a MAC sub-PDU
|
||||
* subheader), and the user of the API has to fill the necessary data. */
|
||||
tbs_size_t nr_mac_rlc_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
@@ -59,7 +79,7 @@ rlc_op_status_t nr_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
const mui_t muiP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
uint8_t *sdu_pP);
|
||||
mac_rlc_status_resp_t nr_mac_rlc_status_ind(const uint16_t ue_id, const frame_t frame, const logical_chan_id_t channel_idP);
|
||||
void nr_mac_rlc_status_ind(uint16_t ue_id, frame_t frame, int n_ch, const logical_chan_id_t *ch, mac_rlc_status_resp_t *ret);
|
||||
|
||||
void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
||||
void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
||||
|
||||
@@ -252,9 +252,9 @@ static bool check_srs_config(NR_SRS_Config_t *srs_Config)
|
||||
if (srs_Config->srs_ResourceToAddModList) {
|
||||
for (int i = 0; i < srs_Config->srs_ResourceToAddModList->list.count; i++) {
|
||||
NR_SRS_Resource_t *res = srs_Config->srs_ResourceToAddModList->list.array[i];
|
||||
int start = NR_NUMBER_OF_SYMBOLS_PER_SLOT - res->resourceMapping.startPosition - 1;
|
||||
int start = NR_SYMBOLS_PER_SLOT - res->resourceMapping.startPosition - 1;
|
||||
int num = 1 << res->resourceMapping.nrofSymbols;
|
||||
if (start + num > NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
|
||||
if (start + num > NR_SYMBOLS_PER_SLOT) {
|
||||
LOG_E(NR_RRC, "The configured SRS resource exceeds the slot boundary\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(MESSAGES)
|
||||
add_library(xnap xnap_common.c)
|
||||
target_link_libraries(xnap
|
||||
PUBLIC asn1_xnap
|
||||
PRIVATE nr_rrc)
|
||||
target_include_directories(xnap PUBLIC ${CMAKE_CURRENT_DIR})
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
set( XNAP_GRAMMAR ASN1/xnap_R16.2.0.asn)
|
||||
set(XNAP_GRAMMAR ASN1/xnap_R16.2.0.asn)
|
||||
|
||||
set(xnap_source
|
||||
ANY.c
|
||||
@@ -9,6 +9,7 @@ set(xnap_source
|
||||
asn_application.c
|
||||
asn_bit_data.c
|
||||
asn_codecs_prim.c
|
||||
asn_codecs_prim_xer.c
|
||||
asn_internal.c
|
||||
asn_random_fill.c
|
||||
asn_SEQUENCE_OF.c
|
||||
@@ -16,20 +17,73 @@ set(xnap_source
|
||||
ber_tlv_length.c
|
||||
ber_tlv_tag.c
|
||||
BIT_STRING.c
|
||||
BIT_STRING_print.c
|
||||
BIT_STRING_rfill.c
|
||||
BIT_STRING_uper.c
|
||||
BIT_STRING_xer.c
|
||||
constraints.c
|
||||
constr_CHOICE.c
|
||||
constr_CHOICE_aper.c
|
||||
constr_CHOICE_rfill.c
|
||||
constr_CHOICE_print.c
|
||||
constr_CHOICE_uper.c
|
||||
constr_CHOICE_xer.c
|
||||
constr_SEQUENCE.c
|
||||
constr_SEQUENCE_aper.c
|
||||
constr_SEQUENCE_OF.c
|
||||
constr_SEQUENCE_OF_aper.c
|
||||
constr_SEQUENCE_OF_uper.c
|
||||
constr_SEQUENCE_OF_xer.c
|
||||
constr_SEQUENCE_print.c
|
||||
constr_SEQUENCE_rfill.c
|
||||
constr_SEQUENCE_uper.c
|
||||
constr_SEQUENCE_xer.c
|
||||
constr_SET_OF.c
|
||||
constr_SET_OF_aper.c
|
||||
constr_SET_OF_print.c
|
||||
constr_SET_OF_rfill.c
|
||||
constr_SET_OF_uper.c
|
||||
constr_SET_OF_xer.c
|
||||
constr_TYPE.c
|
||||
INTEGER.c
|
||||
INTEGER_aper.c
|
||||
INTEGER_print.c
|
||||
INTEGER_rfill.c
|
||||
INTEGER_uper.c
|
||||
INTEGER_xer.c
|
||||
Makefile.am.libasncodec
|
||||
NativeEnumerated.c
|
||||
NativeEnumerated_aper.c
|
||||
NativeEnumerated_uper.c
|
||||
NativeEnumerated_xer.c
|
||||
NativeInteger.c
|
||||
NativeInteger_aper.c
|
||||
NativeInteger_print.c
|
||||
NativeInteger_rfill.c
|
||||
NativeInteger_uper.c
|
||||
NativeInteger_xer.c
|
||||
NULL.c
|
||||
NULL_aper.c
|
||||
NULL_print.c
|
||||
NULL_rfill.c
|
||||
NULL_uper.c
|
||||
NULL_xer.c
|
||||
OBJECT_IDENTIFIER.c
|
||||
OBJECT_IDENTIFIER_print.c
|
||||
OBJECT_IDENTIFIER_rfill.c
|
||||
OBJECT_IDENTIFIER_xer.c
|
||||
OCTET_STRING.c
|
||||
OCTET_STRING_aper.c
|
||||
OCTET_STRING_print.c
|
||||
OCTET_STRING_rfill.c
|
||||
OCTET_STRING_uper.c
|
||||
OCTET_STRING_xer.c
|
||||
OPEN_TYPE.c
|
||||
OPEN_TYPE_aper.c
|
||||
OPEN_TYPE_uper.c
|
||||
OPEN_TYPE_xer.c
|
||||
per_opentype.c
|
||||
per_encoder.c
|
||||
VisibleString.c
|
||||
xer_decoder.c
|
||||
xer_encoder.c
|
||||
@@ -819,14 +873,22 @@ set(xnap_source
|
||||
XNAP_XnUAddressIndication.c
|
||||
XNAP_XnUAddressInfoperPDUSession-Item.c
|
||||
XNAP_XnUAddressInfoperPDUSession-List.c
|
||||
uper_encoder.c
|
||||
uper_opentype.c
|
||||
uper_support.c
|
||||
)
|
||||
|
||||
set(xnap_headers
|
||||
ANY.h
|
||||
aper_decoder.h
|
||||
aper_encoder.h
|
||||
aper_opentype.h
|
||||
aper_support.h
|
||||
asn_application.h
|
||||
asn_bit_data.h
|
||||
asn_codecs.h
|
||||
asn_codecs_prim.h
|
||||
asn_codecs_prim_xer.h
|
||||
asn_internal.h
|
||||
asn_ioc.h
|
||||
asn_random_fill.h
|
||||
@@ -836,23 +898,72 @@ set(xnap_headers
|
||||
ber_tlv_length.h
|
||||
ber_tlv_tag.h
|
||||
BIT_STRING.h
|
||||
BIT_STRING_print.h
|
||||
BIT_STRING_rfill.h
|
||||
BIT_STRING_uper.h
|
||||
BIT_STRING_xer.h
|
||||
constraints.h
|
||||
constr_CHOICE.h
|
||||
constr_CHOICE_aper.h
|
||||
constr_CHOICE_print.h
|
||||
constr_CHOICE_rfill.h
|
||||
constr_CHOICE_uper.h
|
||||
constr_CHOICE_xer.h
|
||||
constr_SEQUENCE.h
|
||||
constr_SEQUENCE_aper.h
|
||||
constr_SEQUENCE_OF.h
|
||||
constr_SEQUENCE_OF_aper.h
|
||||
constr_SEQUENCE_OF_uper.h
|
||||
constr_SEQUENCE_OF_xer.h
|
||||
constr_SEQUENCE_print.h
|
||||
constr_SEQUENCE_rfill.h
|
||||
constr_SEQUENCE_uper.h
|
||||
constr_SEQUENCE_xer.h
|
||||
constr_SET_OF.h
|
||||
constr_SET_OF_aper.h
|
||||
constr_SET_OF_print.h
|
||||
constr_SET_OF_rfill.h
|
||||
constr_SET_OF_uper.h
|
||||
constr_SET_OF_xer.h
|
||||
constr_TYPE.h
|
||||
INTEGER.h
|
||||
INTEGER_aper.h
|
||||
INTEGER_print.h
|
||||
INTEGER_rfill.h
|
||||
INTEGER_uper.h
|
||||
INTEGER_xer.h
|
||||
NativeEnumerated.h
|
||||
NativeEnumerated_aper.h
|
||||
NativeEnumerated_uper.h
|
||||
NativeEnumerated_xer.h
|
||||
NativeInteger.h
|
||||
NativeInteger_aper.h
|
||||
NativeInteger_print.h
|
||||
NativeInteger_rfill.h
|
||||
NativeInteger_xer.h
|
||||
NativeInteger_uper.h
|
||||
NULL.h
|
||||
NULL_aper.h
|
||||
NULL_print.h
|
||||
NULL_rfill.h
|
||||
NULL_uper.h
|
||||
NULL_xer.h
|
||||
OBJECT_IDENTIFIER.h
|
||||
OBJECT_IDENTIFIER_print.h
|
||||
OBJECT_IDENTIFIER_rfill.h
|
||||
OBJECT_IDENTIFIER_xer.h
|
||||
OCTET_STRING.h
|
||||
OCTET_STRING_aper.h
|
||||
OCTET_STRING_print.h
|
||||
OCTET_STRING_rfill.h
|
||||
OCTET_STRING_uper.h
|
||||
OCTET_STRING_xer.h
|
||||
OPEN_TYPE.h
|
||||
aper_decoder.h
|
||||
aper_encoder.h
|
||||
aper_opentype.h
|
||||
aper_support.h
|
||||
OPEN_TYPE_aper.h
|
||||
OPEN_TYPE_uper.h
|
||||
OPEN_TYPE_xer.h
|
||||
per_encoder.h
|
||||
per_opentype.h
|
||||
VisibleString.h
|
||||
xer_decoder.h
|
||||
xer_encoder.h
|
||||
@@ -1643,5 +1754,8 @@ set(xnap_headers
|
||||
XNAP_XnUAddressIndication.h
|
||||
XNAP_XnUAddressInfoperPDUSession-Item.h
|
||||
XNAP_XnUAddressInfoperPDUSession-List.h
|
||||
uper_encoder.h
|
||||
uper_opentype.h
|
||||
uper_support.h
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
add_library(xnap_lib OBJECT
|
||||
xnap_lib_common.c
|
||||
xnap_gNB_interface_management.c
|
||||
)
|
||||
target_link_libraries(xnap_lib PRIVATE asn1_xnap ds)
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
target_compile_definitions(xnap_lib PRIVATE ENABLE_TESTS)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* \brief xnap interface handler procedures for gNB
|
||||
*/
|
||||
|
||||
#include "xnap_gNB_interface_management.h"
|
||||
#include "xnap_lib_common.h"
|
||||
#include "xnap_lib_includes.h"
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Request encoding
|
||||
*/
|
||||
XNAP_XnAP_PDU_t *encode_xn_setup_request(const xnap_setup_req_t *msg)
|
||||
{
|
||||
XNAP_XnAP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
|
||||
|
||||
/* PDU type */
|
||||
pdu->present = XNAP_XnAP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu->choice.initiatingMessage, initMsg);
|
||||
initMsg->procedureCode = XNAP_ProcedureCode_id_xnSetup;
|
||||
initMsg->criticality = XNAP_Criticality_reject;
|
||||
initMsg->value.present = XNAP_InitiatingMessage__value_PR_XnSetupRequest;
|
||||
|
||||
XNAP_XnSetupRequest_t *out = &initMsg->value.choice.XnSetupRequest;
|
||||
|
||||
/* Global NG-RAN Node ID (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupRequest_IEs_t, ieC1);
|
||||
ieC1->id = XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID;
|
||||
ieC1->criticality = XNAP_Criticality_reject;
|
||||
ieC1->value.present = XNAP_XnSetupRequest_IEs__value_PR_GlobalNG_RANNode_ID;
|
||||
|
||||
XNAP_GlobalNG_RANNode_ID_t *global = &ieC1->value.choice.GlobalNG_RANNode_ID;
|
||||
global->present = XNAP_GlobalNG_RANNode_ID_PR_gNB;
|
||||
asn1cCalloc(global->choice.gNB, gnb);
|
||||
|
||||
MCC_MNC_TO_PLMNID(msg->plmn.mcc, msg->plmn.mnc, msg->plmn.mnc_digit_length, &gnb->plmn_id);
|
||||
gnb->gnb_id.present = XNAP_GNB_ID_Choice_PR_gnb_ID;
|
||||
MACRO_GNB_ID_TO_BIT_STRING(msg->gNB_id, &gnb->gnb_id.choice.gnb_ID);
|
||||
|
||||
/* TAI Support List (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupRequest_IEs_t, ieC2);
|
||||
ieC2->id = XNAP_ProtocolIE_ID_id_TAISupport_list;
|
||||
ieC2->criticality = XNAP_Criticality_reject;
|
||||
ieC2->value.present = XNAP_XnSetupRequest_IEs__value_PR_TAISupport_List;
|
||||
|
||||
for (int i = 0; i < msg->num_tai; i++) {
|
||||
asn1cSequenceAdd(ieC2->value.choice.TAISupport_List.list, XNAP_TAISupport_Item_t, taiItem);
|
||||
INT24_TO_OCTET_STRING(msg->tai_support[i].tac, &taiItem->tac);
|
||||
|
||||
for (int j = 0; j < msg->tai_support[i].num_plmn; j++) {
|
||||
const xnap_plmn_support_t *plmn = &msg->tai_support[i].plmn_support[j];
|
||||
asn1cSequenceAdd(taiItem->broadcastPLMNs.list, XNAP_BroadcastPLMNinTAISupport_Item_t, plmnItem);
|
||||
MCC_MNC_TO_PLMNID(plmn->plmn.mcc, plmn->plmn.mnc, plmn->plmn.mnc_digit_length, &plmnItem->plmn_id);
|
||||
|
||||
for (int k = 0; k < plmn->num_nssai; k++) {
|
||||
asn1cSequenceAdd(plmnItem->tAISliceSupport_List.list, XNAP_S_NSSAI_t, nssai);
|
||||
INT8_TO_OCTET_STRING(plmn->nssai[k].sst, &nssai->sst);
|
||||
if (plmn->nssai[k].sd) { asn1cCalloc(nssai->sd, sd); INT24_TO_OCTET_STRING(plmn->nssai[k].sd, sd); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* AMF Region Information (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupRequest_IEs_t, ieC3);
|
||||
ieC3->id = XNAP_ProtocolIE_ID_id_AMF_Region_Information;
|
||||
ieC3->criticality = XNAP_Criticality_reject;
|
||||
ieC3->value.present = XNAP_XnSetupRequest_IEs__value_PR_AMF_Region_Information;
|
||||
|
||||
for (int i = 0; i < msg->num_amf_regions; i++) {
|
||||
const xnap_amf_region_info_t *amf = &msg->amf_region_info[i];
|
||||
asn1cSequenceAdd(ieC3->value.choice.AMF_Region_Information.list, XNAP_GlobalAMF_Region_Information_t, amfItem);
|
||||
MCC_MNC_TO_PLMNID(amf->plmn.mcc, amf->plmn.mnc, amf->plmn.mnc_digit_length, &amfItem->plmn_ID);
|
||||
INT8_TO_OCTET_STRING(amf->amf_region_id, &amfItem->amf_region_id);
|
||||
}
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Request decoding
|
||||
*/
|
||||
bool decode_xn_setup_request(xnap_setup_req_t *out, const XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
/* Check presence of message type */
|
||||
_EQ_CHECK_INT(pdu->present, XNAP_XnAP_PDU_PR_initiatingMessage);
|
||||
AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL");
|
||||
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, XNAP_ProcedureCode_id_xnSetup);
|
||||
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, XNAP_InitiatingMessage__value_PR_XnSetupRequest);
|
||||
/* XnSetupRequest container */
|
||||
XNAP_XnSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.XnSetupRequest;
|
||||
|
||||
XNAP_XnSetupRequest_IEs_t *ie;
|
||||
/* Check presence of mandatory IEs */
|
||||
XNAP_LIB_FIND_IE(XNAP_XnSetupRequest_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID, true);
|
||||
XNAP_LIB_FIND_IE(XNAP_XnSetupRequest_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_TAISupport_list, true);
|
||||
XNAP_LIB_FIND_IE(XNAP_XnSetupRequest_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_AMF_Region_Information, true);
|
||||
|
||||
/* Loop over all IEs */
|
||||
for (int i = 0; i < in->protocolIEs.list.count; i++) {
|
||||
AssertError(in->protocolIEs.list.array[i] != NULL, return false, "protocolIEs.list.array[i] is NULL");
|
||||
ie = in->protocolIEs.list.array[i];
|
||||
switch (ie->id) {
|
||||
case XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID: {
|
||||
/* Global NG-RAN Node ID (M) */
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_XnSetupRequest_IEs__value_PR_GlobalNG_RANNode_ID);
|
||||
XNAP_GlobalNG_RANNode_ID_t *global_id = &ie->value.choice.GlobalNG_RANNode_ID;
|
||||
AssertError(global_id->present == XNAP_GlobalNG_RANNode_ID_PR_gNB, return false, "Only gNB supported");
|
||||
AssertError(global_id->choice.gNB != NULL, return false, "gNB is NULL");
|
||||
/* Decode PLMN */
|
||||
PLMNID_TO_MCC_MNC(&global_id->choice.gNB->plmn_id,
|
||||
out->plmn.mcc,
|
||||
out->plmn.mnc,
|
||||
out->plmn.mnc_digit_length);
|
||||
/* Decode gNB ID */
|
||||
AssertError(global_id->choice.gNB->gnb_id.present == XNAP_GNB_ID_Choice_PR_gnb_ID, return false, "Unsupported gNB ID choice");
|
||||
MACRO_BIT_STRING_TO_GNB_ID(&global_id->choice.gNB->gnb_id.choice.gnb_ID, out->gNB_id);
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_TAISupport_list: {
|
||||
/* TAI Support List (M) */
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_XnSetupRequest_IEs__value_PR_TAISupport_List);
|
||||
int tai_count = ie->value.choice.TAISupport_List.list.count;
|
||||
out->num_tai = tai_count;
|
||||
out->tai_support = calloc_or_fail(tai_count, sizeof(*out->tai_support));
|
||||
for (int m = 0; m < tai_count; m++) {
|
||||
XNAP_TAISupport_Item_t *tai_item = ie->value.choice.TAISupport_List.list.array[m];
|
||||
/* TAC */
|
||||
OCTET_STRING_TO_INT24(&tai_item->tac, out->tai_support[m].tac);
|
||||
/* PLMN list */
|
||||
out->tai_support[m].num_plmn = tai_item->broadcastPLMNs.list.count;
|
||||
out->tai_support[m].plmn_support = calloc_or_fail(out->tai_support[m].num_plmn, sizeof(*out->tai_support[m].plmn_support));
|
||||
for (int j = 0; j < out->tai_support[m].num_plmn; j++) {
|
||||
XNAP_BroadcastPLMNinTAISupport_Item_t *plmn_item = tai_item->broadcastPLMNs.list.array[j];
|
||||
xnap_plmn_support_t *plmn = &out->tai_support[m].plmn_support[j];
|
||||
PLMNID_TO_MCC_MNC(&plmn_item->plmn_id,
|
||||
plmn->plmn.mcc,
|
||||
plmn->plmn.mnc,
|
||||
plmn->plmn.mnc_digit_length);
|
||||
/* NSSAI */
|
||||
plmn->num_nssai = plmn_item->tAISliceSupport_List.list.count;
|
||||
plmn->nssai = calloc_or_fail(plmn->num_nssai, sizeof(*plmn->nssai));
|
||||
for (int k = 0; k < plmn->num_nssai; k++) {
|
||||
OCTET_STRING_TO_INT8(&plmn_item->tAISliceSupport_List.list.array[k]->sst, plmn->nssai[k].sst);
|
||||
if (plmn_item->tAISliceSupport_List.list.array[k]->sd) {
|
||||
OCTET_STRING_TO_INT24(plmn_item->tAISliceSupport_List.list.array[k]->sd, plmn->nssai[k].sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_AMF_Region_Information: {
|
||||
/* AMF Region Information (M) */
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_XnSetupRequest_IEs__value_PR_AMF_Region_Information);
|
||||
out->num_amf_regions = ie->value.choice.AMF_Region_Information.list.count;
|
||||
out->amf_region_info = calloc_or_fail(out->num_amf_regions, sizeof(*out->amf_region_info));
|
||||
for (int a = 0; a < out->num_amf_regions; a++) {
|
||||
XNAP_GlobalAMF_Region_Information_t *amf = ie->value.choice.AMF_Region_Information.list.array[a];
|
||||
PLMNID_TO_MCC_MNC(&amf->plmn_ID,
|
||||
out->amf_region_info[a].plmn.mcc,
|
||||
out->amf_region_info[a].plmn.mnc,
|
||||
out->amf_region_info[a].plmn.mnc_digit_length);
|
||||
OCTET_STRING_TO_INT8(&amf->amf_region_id, out->amf_region_info[a].amf_region_id);
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
AssertError(0, return false, "Unknown XnAP IE id %ld\n", ie->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Request main equality check
|
||||
*/
|
||||
bool eq_xnap_setup_request(const xnap_setup_req_t *a, const xnap_setup_req_t *b)
|
||||
{
|
||||
_EQ_CHECK_UINT32(a->gNB_id, b->gNB_id);
|
||||
if (!eq_xnap_plmn(&a->plmn, &b->plmn)) return false;
|
||||
|
||||
_EQ_CHECK_INT(a->num_tai, b->num_tai);
|
||||
for (int i = 0; i < a->num_tai; i++) {
|
||||
if (!eq_xnap_tai_support(&a->tai_support[i], &b->tai_support[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
_EQ_CHECK_INT(a->num_amf_regions, b->num_amf_regions);
|
||||
for (int i = 0; i < a->num_amf_regions; i++) {
|
||||
if (!eq_xnap_plmn(&a->amf_region_info[i].plmn, &b->amf_region_info[i].plmn))
|
||||
return false;
|
||||
_EQ_CHECK_INT(a->amf_region_info[i].amf_region_id, b->amf_region_info[i].amf_region_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void free_xnap_plmn_support(xnap_plmn_support_t *plmn_support, uint8_t num_plmn)
|
||||
{
|
||||
if (!plmn_support) return;
|
||||
for (int i = 0; i < num_plmn; i++) {
|
||||
free(plmn_support[i].nssai);
|
||||
}
|
||||
free(plmn_support);
|
||||
}
|
||||
|
||||
static void free_xnap_tai_support(xnap_tai_support_t *tai_support, uint16_t num_tai)
|
||||
{
|
||||
if (!tai_support) return;
|
||||
for (int i = 0; i < num_tai; i++) {
|
||||
free_xnap_plmn_support(tai_support[i].plmn_support,
|
||||
tai_support[i].num_plmn);
|
||||
}
|
||||
free(tai_support);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Request memory management
|
||||
*/
|
||||
void free_xnap_setup_request(const xnap_setup_req_t *msg)
|
||||
{
|
||||
DevAssert(msg != NULL);
|
||||
free_xnap_tai_support(msg->tai_support, msg->num_tai);
|
||||
free(msg->amf_region_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Response encoding
|
||||
*/
|
||||
XNAP_XnAP_PDU_t *encode_xn_setup_response(const xnap_setup_resp_t *resp)
|
||||
{
|
||||
XNAP_XnAP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
|
||||
|
||||
/* PDU type */
|
||||
pdu->present = XNAP_XnAP_PDU_PR_successfulOutcome;
|
||||
asn1cCalloc(pdu->choice.successfulOutcome, succMsg);
|
||||
succMsg->procedureCode = XNAP_ProcedureCode_id_xnSetup;
|
||||
succMsg->criticality = XNAP_Criticality_reject;
|
||||
succMsg->value.present = XNAP_SuccessfulOutcome__value_PR_XnSetupResponse;
|
||||
|
||||
XNAP_XnSetupResponse_t *out = &succMsg->value.choice.XnSetupResponse;
|
||||
|
||||
/* Global NG-RAN Node ID (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupResponse_IEs_t, ie1);
|
||||
ie1->id = XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID;
|
||||
ie1->criticality = XNAP_Criticality_reject;
|
||||
ie1->value.present = XNAP_XnSetupResponse_IEs__value_PR_GlobalNG_RANNode_ID;
|
||||
|
||||
XNAP_GlobalNG_RANNode_ID_t *global = &ie1->value.choice.GlobalNG_RANNode_ID;
|
||||
global->present = XNAP_GlobalNG_RANNode_ID_PR_gNB;
|
||||
asn1cCalloc(global->choice.gNB, gnb);
|
||||
|
||||
MCC_MNC_TO_PLMNID(resp->plmn.mcc, resp->plmn.mnc, resp->plmn.mnc_digit_length, &gnb->plmn_id);
|
||||
gnb->gnb_id.present = XNAP_GNB_ID_Choice_PR_gnb_ID;
|
||||
MACRO_GNB_ID_TO_BIT_STRING(resp->gNB_id, &gnb->gnb_id.choice.gnb_ID);
|
||||
|
||||
/* TAI Support List (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupResponse_IEs_t, ie2);
|
||||
ie2->id = XNAP_ProtocolIE_ID_id_TAISupport_list;
|
||||
ie2->criticality = XNAP_Criticality_reject;
|
||||
ie2->value.present = XNAP_XnSetupResponse_IEs__value_PR_TAISupport_List;
|
||||
|
||||
for (int i = 0; i < resp->num_tai; i++) {
|
||||
asn1cSequenceAdd(ie2->value.choice.TAISupport_List.list, XNAP_TAISupport_Item_t, taiItem);
|
||||
INT24_TO_OCTET_STRING(resp->tai_support[i].tac, &taiItem->tac);
|
||||
|
||||
for (int j = 0; j < resp->tai_support[i].num_plmn; j++) {
|
||||
const xnap_plmn_support_t *plmn = &resp->tai_support[i].plmn_support[j];
|
||||
asn1cSequenceAdd(taiItem->broadcastPLMNs.list, XNAP_BroadcastPLMNinTAISupport_Item_t, plmnItem);
|
||||
MCC_MNC_TO_PLMNID(plmn->plmn.mcc, plmn->plmn.mnc, plmn->plmn.mnc_digit_length, &plmnItem->plmn_id);
|
||||
|
||||
for (int k = 0; k < plmn->num_nssai; k++) {
|
||||
asn1cSequenceAdd(plmnItem->tAISliceSupport_List.list, XNAP_S_NSSAI_t, nssai);
|
||||
INT8_TO_OCTET_STRING(plmn->nssai[k].sst, &nssai->sst);
|
||||
if (plmn->nssai[k].sd) { asn1cCalloc(nssai->sd, sd); INT24_TO_OCTET_STRING(plmn->nssai[k].sd, sd); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Response decoding
|
||||
*/
|
||||
bool decode_xn_setup_response(xnap_setup_resp_t *out, const XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
/* Check presence of message type */
|
||||
_EQ_CHECK_INT(pdu->present, XNAP_XnAP_PDU_PR_successfulOutcome);
|
||||
AssertError(pdu->choice.successfulOutcome != NULL, return false, "successfulOutcome is NULL");
|
||||
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, XNAP_ProcedureCode_id_xnSetup);
|
||||
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, XNAP_SuccessfulOutcome__value_PR_XnSetupResponse);
|
||||
|
||||
/* XnSetupResponse container */
|
||||
XNAP_XnSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.XnSetupResponse;
|
||||
XNAP_XnSetupResponse_IEs_t *ie;
|
||||
|
||||
/* Check presence of mandatory IEs */
|
||||
XNAP_LIB_FIND_IE(XNAP_XnSetupResponse_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID, true);
|
||||
XNAP_LIB_FIND_IE(XNAP_XnSetupResponse_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_TAISupport_list, true);
|
||||
|
||||
/* Loop over all IEs */
|
||||
for (int i = 0; i < in->protocolIEs.list.count; i++) {
|
||||
AssertError(in->protocolIEs.list.array[i] != NULL, return false, "protocolIEs.list.array[i] is NULL");
|
||||
ie = in->protocolIEs.list.array[i];
|
||||
|
||||
switch (ie->id) {
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID: {
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_XnSetupResponse_IEs__value_PR_GlobalNG_RANNode_ID);
|
||||
XNAP_GlobalNG_RANNode_ID_t *global = &ie->value.choice.GlobalNG_RANNode_ID;
|
||||
AssertError(global->present == XNAP_GlobalNG_RANNode_ID_PR_gNB, return false, "Only gNB supported");
|
||||
AssertError(global->choice.gNB != NULL, return false, "gNB is NULL");
|
||||
|
||||
PLMNID_TO_MCC_MNC(&global->choice.gNB->plmn_id, out->plmn.mcc, out->plmn.mnc, out->plmn.mnc_digit_length);
|
||||
AssertError(global->choice.gNB->gnb_id.present == XNAP_GNB_ID_Choice_PR_gnb_ID, return false, "Unsupported gNB ID");
|
||||
MACRO_BIT_STRING_TO_GNB_ID(&global->choice.gNB->gnb_id.choice.gnb_ID, out->gNB_id);
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_TAISupport_list: {
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_XnSetupResponse_IEs__value_PR_TAISupport_List);
|
||||
out->num_tai = ie->value.choice.TAISupport_List.list.count;
|
||||
out->tai_support = calloc_or_fail(out->num_tai, sizeof(*out->tai_support));
|
||||
|
||||
for (int m = 0; m < out->num_tai; m++) {
|
||||
XNAP_TAISupport_Item_t *tai = ie->value.choice.TAISupport_List.list.array[m];
|
||||
OCTET_STRING_TO_INT24(&tai->tac, out->tai_support[m].tac);
|
||||
|
||||
out->tai_support[m].num_plmn = tai->broadcastPLMNs.list.count;
|
||||
out->tai_support[m].plmn_support = calloc_or_fail(out->tai_support[m].num_plmn, sizeof(*out->tai_support[m].plmn_support));
|
||||
|
||||
for (int j = 0; j < out->tai_support[m].num_plmn; j++) {
|
||||
XNAP_BroadcastPLMNinTAISupport_Item_t *plmn_item = tai->broadcastPLMNs.list.array[j];
|
||||
xnap_plmn_support_t *plmn = &out->tai_support[m].plmn_support[j];
|
||||
|
||||
PLMNID_TO_MCC_MNC(&plmn_item->plmn_id, plmn->plmn.mcc, plmn->plmn.mnc, plmn->plmn.mnc_digit_length);
|
||||
|
||||
plmn->num_nssai = plmn_item->tAISliceSupport_List.list.count;
|
||||
plmn->nssai = calloc_or_fail(plmn->num_nssai, sizeof(*plmn->nssai));
|
||||
|
||||
for (int k = 0; k < plmn->num_nssai; k++) {
|
||||
OCTET_STRING_TO_INT8(&plmn_item->tAISliceSupport_List.list.array[k]->sst, plmn->nssai[k].sst);
|
||||
if (plmn_item->tAISliceSupport_List.list.array[k]->sd) {
|
||||
OCTET_STRING_TO_INT24(plmn_item->tAISliceSupport_List.list.array[k]->sd, plmn->nssai[k].sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
AssertError(0, return false, "Unknown XnAP IE id %ld\n", ie->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Response main equality check
|
||||
*/
|
||||
bool eq_xnap_setup_response(const xnap_setup_resp_t *a, const xnap_setup_resp_t *b)
|
||||
{
|
||||
_EQ_CHECK_UINT32(a->gNB_id, b->gNB_id);
|
||||
if (!eq_xnap_plmn(&a->plmn, &b->plmn)) return false;
|
||||
|
||||
_EQ_CHECK_INT(a->num_tai, b->num_tai);
|
||||
for (int i = 0; i < a->num_tai; i++) {
|
||||
if (!eq_xnap_tai_support(&a->tai_support[i], &b->tai_support[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Response memory management
|
||||
*/
|
||||
void free_xnap_setup_response(const xnap_setup_resp_t *msg)
|
||||
{
|
||||
DevAssert(msg != NULL);
|
||||
free_xnap_tai_support(msg->tai_support, msg->num_tai);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Failure encoding
|
||||
*/
|
||||
XNAP_XnAP_PDU_t *encode_xn_setup_failure(const xnap_setup_failure_t *fail)
|
||||
{
|
||||
XNAP_XnAP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
|
||||
|
||||
/* Message type */
|
||||
pdu->present = XNAP_XnAP_PDU_PR_unsuccessfulOutcome;
|
||||
asn1cCalloc(pdu->choice.unsuccessfulOutcome, failMsg);
|
||||
failMsg->procedureCode = XNAP_ProcedureCode_id_xnSetup;
|
||||
failMsg->criticality = XNAP_Criticality_reject;
|
||||
failMsg->value.present = XNAP_UnsuccessfulOutcome__value_PR_XnSetupFailure;
|
||||
|
||||
XNAP_XnSetupFailure_t *out = &failMsg->value.choice.XnSetupFailure;
|
||||
|
||||
/* Cause (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupFailure_IEs_t, ie1);
|
||||
ie1->id = XNAP_ProtocolIE_ID_id_Cause;
|
||||
ie1->criticality = XNAP_Criticality_ignore;
|
||||
ie1->value.present = XNAP_XnSetupFailure_IEs__value_PR_Cause;
|
||||
xnap_gNB_set_cause(&ie1->value.choice.Cause, &fail->cause);
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Failure decoding
|
||||
*/
|
||||
bool decode_xn_setup_failure(xnap_setup_failure_t *out, const XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
/* Check message type */
|
||||
_EQ_CHECK_INT(pdu->present, XNAP_XnAP_PDU_PR_unsuccessfulOutcome);
|
||||
AssertError(pdu->choice.unsuccessfulOutcome != NULL, return false, "unsuccessfulOutcome is NULL");
|
||||
_EQ_CHECK_LONG(pdu->choice.unsuccessfulOutcome->procedureCode, XNAP_ProcedureCode_id_xnSetup);
|
||||
_EQ_CHECK_INT(pdu->choice.unsuccessfulOutcome->value.present, XNAP_UnsuccessfulOutcome__value_PR_XnSetupFailure);
|
||||
|
||||
/* XnSetupFailure container */
|
||||
XNAP_XnSetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.XnSetupFailure;
|
||||
XNAP_XnSetupFailure_IEs_t *ie;
|
||||
|
||||
/* Check presence of mandatory IE */
|
||||
XNAP_LIB_FIND_IE(XNAP_XnSetupFailure_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_Cause, true);
|
||||
|
||||
/* Decode Cause */
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_XnSetupFailure_IEs__value_PR_Cause);
|
||||
out->cause = decode_xnap_cause(&ie->value.choice.Cause);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Failure equality check
|
||||
*/
|
||||
bool eq_xnap_setup_failure(const xnap_setup_failure_t *a, const xnap_setup_failure_t *b)
|
||||
{
|
||||
return eq_xnap_cause(&a->cause, &b->cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP Setup Failure memory management
|
||||
*/
|
||||
void free_xnap_setup_failure(xnap_setup_failure_t *msg)
|
||||
{
|
||||
// nothing to free
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_INTERFACE_MANAGEMENT_H_
|
||||
#define XNAP_GNB_INTERFACE_MANAGEMENT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "xnap_messages_types.h"
|
||||
typedef struct XNAP_XnAP_PDU XNAP_XnAP_PDU_t;
|
||||
|
||||
XNAP_XnAP_PDU_t *encode_xn_setup_request(const xnap_setup_req_t *req);
|
||||
XNAP_XnAP_PDU_t *encode_xn_setup_response(const xnap_setup_resp_t *resp);
|
||||
XNAP_XnAP_PDU_t *encode_xn_setup_failure(const xnap_setup_failure_t *fail);
|
||||
|
||||
bool decode_xn_setup_request(xnap_setup_req_t *req, const XNAP_XnAP_PDU_t *pdu);
|
||||
bool decode_xn_setup_response(xnap_setup_resp_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
bool decode_xn_setup_failure(xnap_setup_failure_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
|
||||
bool eq_xnap_setup_request(const xnap_setup_req_t *a, const xnap_setup_req_t *b);
|
||||
bool eq_xnap_setup_response(const xnap_setup_resp_t *a, const xnap_setup_resp_t *b);
|
||||
bool eq_xnap_setup_failure(const xnap_setup_failure_t *a, const xnap_setup_failure_t *b);
|
||||
|
||||
void free_xnap_setup_request(const xnap_setup_req_t *msg);
|
||||
void free_xnap_setup_response(const xnap_setup_resp_t *msg);
|
||||
void free_xnap_setup_failure(xnap_setup_failure_t *msg);
|
||||
|
||||
#endif /* XNAP_GNB_INTERFACE_MANAGEMENT_H_ */
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "xnap_lib_common.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
int xnap_gNB_set_cause(XNAP_Cause_t *cause_p,const xnap_cause_t *in)
|
||||
{
|
||||
DevAssert(cause_p != NULL);
|
||||
switch (in->type) {
|
||||
case XNAP_CAUSE_RADIO_NETWORK:
|
||||
cause_p->present = XNAP_Cause_PR_radioNetwork;
|
||||
cause_p->choice.radioNetwork = in->value;
|
||||
break;
|
||||
case XNAP_CAUSE_TRANSPORT:
|
||||
cause_p->present = XNAP_Cause_PR_transport;
|
||||
cause_p->choice.transport = in->value;
|
||||
break;
|
||||
case XNAP_CAUSE_PROTOCOL:
|
||||
cause_p->present = XNAP_Cause_PR_protocol;
|
||||
cause_p->choice.protocol = in->value;
|
||||
break;
|
||||
case XNAP_CAUSE_MISC:
|
||||
cause_p->present = XNAP_Cause_PR_misc;
|
||||
cause_p->choice.misc = in->value;
|
||||
break;
|
||||
case XNAP_CAUSE_NOTHING:
|
||||
default:
|
||||
AssertFatal(false, "unknown cause value %d\n", in->type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
xnap_cause_t decode_xnap_cause(const XNAP_Cause_t *in)
|
||||
{
|
||||
xnap_cause_t out = {0};
|
||||
switch (in->present) {
|
||||
case XNAP_Cause_PR_radioNetwork:
|
||||
out.type = XNAP_CAUSE_RADIO_NETWORK;
|
||||
out.value = in->choice.radioNetwork;
|
||||
break;
|
||||
|
||||
case XNAP_Cause_PR_transport:
|
||||
out.type = XNAP_CAUSE_TRANSPORT;
|
||||
out.value = in->choice.transport;
|
||||
break;
|
||||
|
||||
case XNAP_Cause_PR_protocol:
|
||||
out.type = XNAP_CAUSE_PROTOCOL;
|
||||
out.value = in->choice.protocol;
|
||||
break;
|
||||
|
||||
case XNAP_Cause_PR_misc:
|
||||
out.type = XNAP_CAUSE_MISC;
|
||||
out.value = in->choice.misc;
|
||||
break;
|
||||
case XNAP_Cause_PR_NOTHING:
|
||||
default:
|
||||
PRINT_ERROR("received illegal XNAP cause %d\n", in->present);
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool eq_xnap_cause(const xnap_cause_t *a, const xnap_cause_t *b)
|
||||
{
|
||||
_EQ_CHECK_INT(a->type, b->type);
|
||||
_EQ_CHECK_INT(a->value, b->value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_xnap_plmn(const plmn_id_t *a, const plmn_id_t *b)
|
||||
{
|
||||
_EQ_CHECK_INT(a->mcc, b->mcc);
|
||||
_EQ_CHECK_INT(a->mnc, b->mnc);
|
||||
_EQ_CHECK_INT(a->mnc_digit_length, b->mnc_digit_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_xnap_snssai(const nssai_t *a, const nssai_t *b)
|
||||
{
|
||||
_EQ_CHECK_INT(a->sst, b->sst);
|
||||
_EQ_CHECK_UINT32(a->sd, b->sd);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_xnap_plmn_support(const xnap_plmn_support_t *a, const xnap_plmn_support_t *b)
|
||||
{
|
||||
if (!eq_xnap_plmn(&a->plmn, &b->plmn)) return false;
|
||||
_EQ_CHECK_INT(a->num_nssai, b->num_nssai);
|
||||
for (int i = 0; i < a->num_nssai; i++) {
|
||||
if (!eq_xnap_snssai(&a->nssai[i], &b->nssai[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_xnap_tai_support(const xnap_tai_support_t *a, const xnap_tai_support_t *b)
|
||||
{
|
||||
_EQ_CHECK_UINT32(a->tac, b->tac);
|
||||
_EQ_CHECK_INT(a->num_plmn, b->num_plmn);
|
||||
for (int i = 0; i < a->num_plmn; i++) {
|
||||
if (!eq_xnap_plmn_support(&a->plmn_support[i], &b->plmn_support[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef XNAP_LIB_COMMON_H_
|
||||
#define XNAP_LIB_COMMON_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
#include "common/utils/oai_asn1.h"
|
||||
#include "common/utils/utils.h"
|
||||
#include "common/utils/eq_check.h"
|
||||
#include "xnap_messages_types.h"
|
||||
#include "xnap_lib_includes.h"
|
||||
|
||||
/* macro to look up XnAP IE. If mandatory and not found, macro will print
|
||||
* descriptive debug message to stderr and force exit in calling function */
|
||||
#define XNAP_LIB_FIND_IE(IE_TYPE, ie, IE_LIST, IE_ID, mandatory) \
|
||||
do { \
|
||||
ie = NULL; \
|
||||
for (IE_TYPE **ptr = (IE_LIST)->array; ptr < &(IE_LIST)->array[(IE_LIST)->count]; ptr++) { \
|
||||
if ((*ptr)->id == IE_ID) { \
|
||||
ie = *ptr; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if ((mandatory) && (ie == NULL)) { \
|
||||
fprintf(stderr, "%s(): could not find XnAP IE " #IE_ID " of type " #IE_TYPE "\n", __func__); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Function Prototypes */
|
||||
bool eq_xnap_plmn(const plmn_id_t *a, const plmn_id_t *b);
|
||||
bool eq_xnap_snssai(const nssai_t *a, const nssai_t *b);
|
||||
bool eq_xnap_tai_support(const xnap_tai_support_t *a, const xnap_tai_support_t *b);
|
||||
bool eq_xnap_plmn_support(const xnap_plmn_support_t *a, const xnap_plmn_support_t *b);
|
||||
bool eq_xnap_cause(const xnap_cause_t *a, const xnap_cause_t *b);
|
||||
|
||||
int xnap_gNB_set_cause(XNAP_Cause_t *cause_p,const xnap_cause_t *in);
|
||||
xnap_cause_t decode_xnap_cause(const XNAP_Cause_t *in);
|
||||
|
||||
#endif /* XNAP_LIB_COMMON_H_ */
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* \brief XnAP ASN.1 message definitions generated from specifications
|
||||
*/
|
||||
|
||||
#ifndef XNAP_LIB_INCLUDES_H
|
||||
#define XNAP_LIB_INCLUDES_H
|
||||
|
||||
#include "XNAP_XnAP-PDU.h"
|
||||
#include "XNAP_ProtocolIE-Field.h"
|
||||
#include "XNAP_InitiatingMessage.h"
|
||||
#include "XNAP_SuccessfulOutcome.h"
|
||||
#include "XNAP_UnsuccessfulOutcome.h"
|
||||
|
||||
#include "XNAP_GlobalgNB-ID.h"
|
||||
#include "XNAP_GlobalNG-RANNode-ID.h"
|
||||
#include "XNAP_GlobalAMF-Region-Information.h"
|
||||
#include "XNAP_TAISupport-Item.h"
|
||||
#include "XNAP_S-NSSAI.h"
|
||||
#include "XNAP_BroadcastPLMNinTAISupport-Item.h"
|
||||
#include "XNAP_Cause.h"
|
||||
|
||||
#endif // XNAP_LIB_INCLUDES_H
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
add_executable(xnap_lib_test xnap_lib_test.c)
|
||||
add_dependencies(tests xnap_lib_test)
|
||||
add_test(NAME xnap_lib_test COMMAND xnap_lib_test)
|
||||
target_link_libraries(xnap_lib_test PRIVATE xnap_lib ds LOG)
|
||||
target_link_libraries(xnap_lib_test PRIVATE asn1_xnap)
|
||||
target_include_directories(xnap_lib_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* \brief Test functions for XnAP encoding/decoding library
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/utils.h"
|
||||
#include "xnap_messages_types.h"
|
||||
#include "openair2/XNAP/lib/xnap_lib_common.h"
|
||||
#include "openair2/XNAP/lib/xnap_gNB_interface_management.h"
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
{
|
||||
printf("detected error at %s:%d:%s: %s\n", file, line, function, s);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Helper for ASN.1 Encoding/Decoding loop */
|
||||
static XNAP_XnAP_PDU_t *xnap_encode_decode(const XNAP_XnAP_PDU_t *enc_pdu)
|
||||
{
|
||||
//xer_fprint(stdout, &asn_DEF_XNAP_XnAP_PDU, enc_pdu);
|
||||
DevAssert(enc_pdu != NULL);
|
||||
char errbuf[1024];
|
||||
size_t errlen = sizeof(errbuf);
|
||||
int ret = asn_check_constraints(&asn_DEF_XNAP_XnAP_PDU, enc_pdu, errbuf, &errlen);
|
||||
AssertFatal(ret == 0, "asn_check_constraints() failed: %s\n", errbuf);
|
||||
|
||||
uint8_t msgbuf[16384];
|
||||
// 1. Encode
|
||||
asn_enc_rval_t enc = aper_encode_to_buffer(&asn_DEF_XNAP_XnAP_PDU, NULL, enc_pdu, msgbuf, sizeof(msgbuf));
|
||||
AssertFatal(enc.encoded > 0, "aper_encode_to_buffer() failed\n");
|
||||
|
||||
// 2. Decode
|
||||
XNAP_XnAP_PDU_t *dec_pdu = NULL;
|
||||
asn_codec_ctx_t st = {.max_stack_size = 100 * 1000};
|
||||
asn_dec_rval_t dec = aper_decode(&st, &asn_DEF_XNAP_XnAP_PDU, (void **)&dec_pdu, msgbuf, enc.encoded, 0, 0);
|
||||
AssertFatal(dec.code == RC_OK, "aper_decode() failed\n");
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_XNAP_XnAP_PDU, dec_pdu);
|
||||
|
||||
return dec_pdu;
|
||||
}
|
||||
|
||||
static void xnap_msg_free(XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_XNAP_XnAP_PDU, pdu);
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Xn Setup Request
|
||||
*/
|
||||
static void test_xn_setup_request(void)
|
||||
{
|
||||
/* ---------- Common PLMNs ---------- */
|
||||
plmn_id_t plmn0 = { .mcc = 208, .mnc = 95, .mnc_digit_length = 2 };
|
||||
plmn_id_t plmn1 = { .mcc = 208, .mnc = 93, .mnc_digit_length = 2 };
|
||||
|
||||
/* ---------- TAI support (2) ---------- */
|
||||
xnap_tai_support_t *tai_support = calloc_or_fail(2, sizeof(*tai_support));
|
||||
|
||||
/* ================= TAI 0 ================= */
|
||||
tai_support[0].tac = 1;
|
||||
tai_support[0].num_plmn = 2;
|
||||
tai_support[0].plmn_support = calloc_or_fail(2, sizeof(*tai_support[0].plmn_support));
|
||||
|
||||
/* ---- TAI 0 / PLMN 0 ---- */
|
||||
tai_support[0].plmn_support[0].plmn = plmn0;
|
||||
tai_support[0].plmn_support[0].num_nssai = 3;
|
||||
tai_support[0].plmn_support[0].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[0].plmn_support[0].nssai[0] = (nssai_t){ .sst = 1, .sd = 0x010203 };
|
||||
tai_support[0].plmn_support[0].nssai[1] = (nssai_t){ .sst = 1, .sd = 0x010204 };
|
||||
tai_support[0].plmn_support[0].nssai[2] = (nssai_t){ .sst = 1, .sd = 0x010205 };
|
||||
|
||||
/* ---- TAI 0 / PLMN 1 ---- */
|
||||
tai_support[0].plmn_support[1].plmn = plmn1;
|
||||
tai_support[0].plmn_support[1].num_nssai = 3;
|
||||
tai_support[0].plmn_support[1].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[0].plmn_support[1].nssai[0] = (nssai_t){ .sst = 2, .sd = 0x020203 };
|
||||
tai_support[0].plmn_support[1].nssai[1] = (nssai_t){ .sst = 2, .sd = 0x020204 };
|
||||
tai_support[0].plmn_support[1].nssai[2] = (nssai_t){ .sst = 2, .sd = 0x020205 };
|
||||
|
||||
/* ================= TAI 1 ================= */
|
||||
tai_support[1].tac = 2;
|
||||
tai_support[1].num_plmn = 2;
|
||||
tai_support[1].plmn_support = calloc_or_fail(2, sizeof(*tai_support[1].plmn_support));
|
||||
|
||||
/* ---- TAI 1 / PLMN 0 ---- */
|
||||
tai_support[1].plmn_support[0].plmn = plmn0;
|
||||
tai_support[1].plmn_support[0].num_nssai = 3;
|
||||
tai_support[1].plmn_support[0].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[1].plmn_support[0].nssai[0] = (nssai_t){ .sst = 3, .sd = 0x030203 };
|
||||
tai_support[1].plmn_support[0].nssai[1] = (nssai_t){ .sst = 3, .sd = 0x030204 };
|
||||
tai_support[1].plmn_support[0].nssai[2] = (nssai_t){ .sst = 3, .sd = 0x030205 };
|
||||
|
||||
/* ---- TAI 1 / PLMN 1 ---- */
|
||||
tai_support[1].plmn_support[1].plmn = plmn1;
|
||||
tai_support[1].plmn_support[1].num_nssai = 3;
|
||||
tai_support[1].plmn_support[1].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[1].plmn_support[1].nssai[0] = (nssai_t){ .sst = 4, .sd = 0x040203 };
|
||||
tai_support[1].plmn_support[1].nssai[1] = (nssai_t){ .sst = 4, .sd = 0x040204 };
|
||||
tai_support[1].plmn_support[1].nssai[2] = (nssai_t){ .sst = 4, .sd = 0x040205 };
|
||||
|
||||
/* ---------- AMF region info (2) ---------- */
|
||||
xnap_amf_region_info_t *amf_region_info = calloc_or_fail(2, sizeof(*amf_region_info));
|
||||
|
||||
amf_region_info[0].plmn = plmn0;
|
||||
amf_region_info[0].amf_region_id = 1;
|
||||
|
||||
amf_region_info[1].plmn = plmn1;
|
||||
amf_region_info[1].amf_region_id = 2;
|
||||
|
||||
/* ---------- create message ---------- */
|
||||
xnap_setup_req_t orig = {
|
||||
.gNB_id = 0xABCDE,
|
||||
.plmn = plmn0,
|
||||
.num_tai = 2,
|
||||
.tai_support = tai_support,
|
||||
.num_amf_regions = 2,
|
||||
.amf_region_info = amf_region_info,
|
||||
};
|
||||
/* ---------- encode ---------- */
|
||||
XNAP_XnAP_PDU_t *xnenc = encode_xn_setup_request(&orig);
|
||||
XNAP_XnAP_PDU_t *xndec = xnap_encode_decode(xnenc);
|
||||
xnap_msg_free(xnenc);
|
||||
|
||||
/* ---------- decode ---------- */
|
||||
xnap_setup_req_t decoded = {0};
|
||||
bool ret = decode_xn_setup_request(&decoded, xndec);
|
||||
AssertFatal(ret, "decode_xn_setup_request failed");
|
||||
xnap_msg_free(xndec);
|
||||
|
||||
/* ---------- equality ---------- */
|
||||
ret = eq_xnap_setup_request(&orig, &decoded);
|
||||
AssertFatal(ret, "Xn Setup Req mismatch\n");
|
||||
free_xnap_setup_request(&decoded);
|
||||
free_xnap_setup_request(&orig);
|
||||
printf("%s() successful \n", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. Xn Setup Response
|
||||
*/
|
||||
static void test_xn_setup_response(void)
|
||||
{
|
||||
/* ---------- Common PLMNs ---------- */
|
||||
plmn_id_t plmn0 = { .mcc = 208, .mnc = 95, .mnc_digit_length = 2 };
|
||||
plmn_id_t plmn1 = { .mcc = 208, .mnc = 93, .mnc_digit_length = 2 };
|
||||
|
||||
/* ---------- TAI support (2) ---------- */
|
||||
xnap_tai_support_t *tai_support = calloc_or_fail(2, sizeof(*tai_support));
|
||||
|
||||
/* ================= TAI 0 ================= */
|
||||
tai_support[0].tac = 1;
|
||||
tai_support[0].num_plmn = 2;
|
||||
tai_support[0].plmn_support = calloc_or_fail(2, sizeof(*tai_support[0].plmn_support));
|
||||
|
||||
/* ---- TAI 0 / PLMN 0 ---- */
|
||||
tai_support[0].plmn_support[0].plmn = plmn0;
|
||||
tai_support[0].plmn_support[0].num_nssai = 3;
|
||||
tai_support[0].plmn_support[0].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[0].plmn_support[0].nssai[0] = (nssai_t){ .sst = 1, .sd = 0x010203 };
|
||||
tai_support[0].plmn_support[0].nssai[1] = (nssai_t){ .sst = 1, .sd = 0x010204 };
|
||||
tai_support[0].plmn_support[0].nssai[2] = (nssai_t){ .sst = 1, .sd = 0x010205 };
|
||||
|
||||
/* ---- TAI 0 / PLMN 1 ---- */
|
||||
tai_support[0].plmn_support[1].plmn = plmn1;
|
||||
tai_support[0].plmn_support[1].num_nssai = 3;
|
||||
tai_support[0].plmn_support[1].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[0].plmn_support[1].nssai[0] = (nssai_t){ .sst = 2, .sd = 0x020203 };
|
||||
tai_support[0].plmn_support[1].nssai[1] = (nssai_t){ .sst = 2, .sd = 0x020204 };
|
||||
tai_support[0].plmn_support[1].nssai[2] = (nssai_t){ .sst = 2, .sd = 0x020205 };
|
||||
|
||||
/* ================= TAI 1 ================= */
|
||||
tai_support[1].tac = 2;
|
||||
tai_support[1].num_plmn = 2;
|
||||
tai_support[1].plmn_support = calloc_or_fail(2, sizeof(*tai_support[1].plmn_support));
|
||||
|
||||
/* ---- TAI 1 / PLMN 0 ---- */
|
||||
tai_support[1].plmn_support[0].plmn = plmn0;
|
||||
tai_support[1].plmn_support[0].num_nssai = 3;
|
||||
tai_support[1].plmn_support[0].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[1].plmn_support[0].nssai[0] = (nssai_t){ .sst = 3, .sd = 0x030203 };
|
||||
tai_support[1].plmn_support[0].nssai[1] = (nssai_t){ .sst = 3, .sd = 0x030204 };
|
||||
tai_support[1].plmn_support[0].nssai[2] = (nssai_t){ .sst = 3, .sd = 0x030205 };
|
||||
|
||||
/* ---- TAI 1 / PLMN 1 ---- */
|
||||
tai_support[1].plmn_support[1].plmn = plmn1;
|
||||
tai_support[1].plmn_support[1].num_nssai = 3;
|
||||
tai_support[1].plmn_support[1].nssai = calloc_or_fail(3, sizeof(nssai_t));
|
||||
|
||||
tai_support[1].plmn_support[1].nssai[0] = (nssai_t){ .sst = 4, .sd = 0x040203 };
|
||||
tai_support[1].plmn_support[1].nssai[1] = (nssai_t){ .sst = 4, .sd = 0x040204 };
|
||||
tai_support[1].plmn_support[1].nssai[2] = (nssai_t){ .sst = 4, .sd = 0x040205 };
|
||||
|
||||
/* ---------- create message ---------- */
|
||||
xnap_setup_resp_t orig = {
|
||||
.gNB_id = 0xABCDE,
|
||||
.plmn = plmn0,
|
||||
.num_tai = 2,
|
||||
.tai_support = tai_support,
|
||||
};
|
||||
/* ---------- encode ---------- */
|
||||
XNAP_XnAP_PDU_t *xnenc = encode_xn_setup_response(&orig);
|
||||
XNAP_XnAP_PDU_t *xndec = xnap_encode_decode(xnenc);
|
||||
xnap_msg_free(xnenc);
|
||||
|
||||
/* ---------- decode ---------- */
|
||||
xnap_setup_resp_t decoded = {0};
|
||||
bool ret = decode_xn_setup_response(&decoded, xndec);
|
||||
AssertFatal(ret, "decode_xn_setup_response failed");
|
||||
xnap_msg_free(xndec);
|
||||
|
||||
/* ---------- equality ---------- */
|
||||
ret = eq_xnap_setup_response(&orig, &decoded);
|
||||
AssertFatal(ret, "Xn Setup Response mismatch\n");
|
||||
free_xnap_setup_response(&decoded);
|
||||
free_xnap_setup_response(&orig);
|
||||
printf("%s() successful \n", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. Xn Setup Failure
|
||||
*/
|
||||
static void test_xn_setup_failure(void)
|
||||
{
|
||||
/* ---------- create message ---------- */
|
||||
xnap_setup_failure_t orig = {
|
||||
.cause.type = XNAP_CAUSE_TRANSPORT,
|
||||
.cause.value = XNAP_CAUSE_TRANSPORT_LAYER_TRANSPORT_RESOURCE_UNAVAILABLE,
|
||||
};
|
||||
|
||||
/* ---------- encode ---------- */
|
||||
XNAP_XnAP_PDU_t *xnenc = encode_xn_setup_failure(&orig);
|
||||
XNAP_XnAP_PDU_t *xndec = xnap_encode_decode(xnenc);
|
||||
xnap_msg_free(xnenc);
|
||||
|
||||
/* ---------- decode ---------- */
|
||||
xnap_setup_failure_t decoded = {0};
|
||||
bool ret = decode_xn_setup_failure(&decoded, xndec);
|
||||
AssertFatal(ret, "decode_xn_setup_failure failed");
|
||||
xnap_msg_free(xndec);
|
||||
|
||||
/* ---------- equality ---------- */
|
||||
ret = eq_xnap_setup_failure(&orig, &decoded);
|
||||
AssertFatal(ret, "Xn Setup Failure mismatch\n");
|
||||
free_xnap_setup_failure(&decoded);
|
||||
free_xnap_setup_failure(&orig);
|
||||
printf("%s() successful \n", __func__);
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("Starting XnAP Library Unit Tests...\n");
|
||||
|
||||
/* Xn Interface Testing */
|
||||
test_xn_setup_request();
|
||||
test_xn_setup_response();
|
||||
test_xn_setup_failure();
|
||||
|
||||
printf("All XnAP tests passed!\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -497,6 +497,16 @@ do { \
|
||||
(bITsTRING)->bits_unused = 4; \
|
||||
} while(0)
|
||||
|
||||
#define MACRO_BIT_STRING_TO_GNB_ID(bITsTRING, oUT) \
|
||||
do { \
|
||||
uint8_t *_buf = (bITsTRING)->buf; \
|
||||
(oUT) = \
|
||||
((uint32_t)_buf[0] << 20) | \
|
||||
((uint32_t)_buf[1] << 12) | \
|
||||
((uint32_t)_buf[2] << 4) | \
|
||||
(((uint32_t)_buf[3] & 0xF0) >> 4); \
|
||||
} while (0)
|
||||
|
||||
/* TS 36.413 v10.9.0 section 9.2.1.38:
|
||||
* E-UTRAN CGI/Cell Identity
|
||||
* The leftmost bits of the Cell
|
||||
|
||||
@@ -217,7 +217,7 @@ static void writerProcessWaitingQueue(nrue_ru_write_t nrue_ru_write, PHY_VARS_NR
|
||||
else
|
||||
wroteSamples = device->trx_write_func(device, timestamp, txp, nsamps, nbAnt, flags);
|
||||
if (wroteSamples != nsamps)
|
||||
LOG_E(HW, "Failed to write to rf\n");
|
||||
LOG_W(HW, "Failed to write to RF: wrote %d out of %d samples\n", wroteSamples, nsamps);
|
||||
}
|
||||
ctx->nextTS = timestamp + nsamps;
|
||||
pthread_mutex_lock(&ctx->mutex_store);
|
||||
@@ -258,6 +258,8 @@ int openair0_write_reorder_common(nrue_ru_write_t nrue_ru_write,
|
||||
wroteSamples = nrue_ru_write(UE, timestamp, txp, nsamps, nbAnt, flags);
|
||||
else
|
||||
wroteSamples = device->trx_write_func(device, timestamp, txp, nsamps, nbAnt, flags);
|
||||
if (wroteSamples != nsamps)
|
||||
LOG_W(HW, "Failed to write to RF: wrote %d out of %d samples\n", wroteSamples, nsamps);
|
||||
} else
|
||||
wroteSamples = nsamps;
|
||||
ctx->nextTS = timestamp + nsamps;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user