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:
Robert Schmidt
2026-03-13 08:39:06 +00:00
109 changed files with 3826 additions and 1211 deletions
+11
View File
@@ -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)
+1 -1
View File
@@ -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:
+7 -11
View File
@@ -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(){
+1
View File
@@ -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, ) \
+21
View File
@@ -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
View File
@@ -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);
+6 -4
View File
@@ -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;
+7 -1
View File
@@ -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));
+2 -2
View File
@@ -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 */
+5
View File
@@ -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 \
+5
View File
@@ -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 \
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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];
+8 -5
View File
@@ -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;
+1 -1
View File
@@ -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];
+1 -1
View File
@@ -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)
{
+1 -1
View File
@@ -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; }
+1 -1
View File
@@ -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
View File
@@ -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++;
}
+1 -1
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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;
+3 -2
View File
@@ -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)
+1 -1
View File
@@ -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));
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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);
+10 -1
View File
@@ -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
+35 -15
View File
@@ -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));
}
}
+1 -1
View File
@@ -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++) {
+2 -10
View File
@@ -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
-1
View File
@@ -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);
+31 -84
View File
@@ -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;
}
+4 -4
View File
@@ -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);
}
+6 -31
View File
@@ -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;
}
}
+1 -1
View File
@@ -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);
}
}
+4 -7
View File
@@ -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);
+1 -5
View File
@@ -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
+1 -4
View File
@@ -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);
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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));
+2 -3
View File
@@ -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;
}
+19 -16
View File
@@ -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);
+25 -22
View File
@@ -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;
}
+1 -1
View File
@@ -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;
-2
View File
@@ -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);
+16 -16
View File
@@ -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");
}
+18 -19
View File
@@ -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);
+15 -17
View File
@@ -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;
+14 -15
View File
@@ -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) {
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+23 -10
View File
@@ -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,
+30 -10
View File
@@ -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);
+1 -1
View File
@@ -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); }
+2 -2
View File
@@ -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. */
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+180
View File
@@ -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;
}
+5 -5
View File
@@ -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;
}
}
+5 -5
View File
@@ -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++;
}
}
+2 -2
View File
@@ -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;
}
+21 -5
View File
@@ -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);
}
/**
+13 -12
View File
@@ -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);
+15 -13
View File
@@ -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;
+7 -1
View File
@@ -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)
+71 -20
View File
@@ -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 {
+24 -4
View File
@@ -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);
+2 -2
View File
@@ -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;
}
+7 -5
View File
@@ -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()
+119 -5
View File
@@ -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
)
+10
View File
@@ -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_ */
+127
View File
@@ -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;
}
+64
View File
@@ -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_ */
+44
View File
@@ -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
+9
View File
@@ -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}
)
+292
View File
@@ -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;
}
+10
View File
@@ -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
+3 -1
View File
@@ -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