Merge branch 'integration_2024_w08' into 'develop'
CI: Integration Branch 2024 week 08 See merge request oai/openairinterface5g!2585 * !2540 NR UE max MIMO layers from UEcap * !2554 NR UE RRC minor improvements * !2563 Add missing backtick for proper code style in README.md * !2567 Avoid integer overflows, buffer overflows, in channel levelling * !2574 NR UE fix for configuring coreset0 and SS0 * !2575 NR UE fix init PDCP phy-test * !2551 NR UE improvements for contention resolution timer * !2570 CI: Replace nrmodule2 by up2
This commit is contained in:
@@ -9,16 +9,14 @@ idefix:
|
|||||||
MTU: 1500
|
MTU: 1500
|
||||||
Trace: True
|
Trace: True
|
||||||
LogStore: /media/usb-drive/ci_qlogs
|
LogStore: /media/usb-drive/ci_qlogs
|
||||||
nrmodule2_quectel:
|
|
||||||
Host: nrmodule2
|
up2:
|
||||||
InitScript: sudo stdbuf -oL /home/nrmodule2/quectel-CM/quectel-CM -4 -s oai.ipv4 &> /tmp/quecel-cm.log &
|
Host: up2
|
||||||
TermScript: sudo -S killall --signal SIGKILL quectel-CM
|
AttachScript: sudo /opt/mbim/start_quectel_mbim.sh
|
||||||
AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
|
DetachScript: sudo /opt/mbim/stop_quectel_mbim.sh
|
||||||
DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
|
|
||||||
NetworkScript: ip a show dev wwan0
|
NetworkScript: ip a show dev wwan0
|
||||||
IF: wwan0
|
IF: wwan0
|
||||||
MTU: 1500
|
MTU: 1500
|
||||||
LogStore: /media/ci_qlogs
|
|
||||||
|
|
||||||
adb_ue_1:
|
adb_ue_1:
|
||||||
Host: nano
|
Host: nano
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Modified by Karim Boutiba (karim.boutiba@eurecom.fr)
|
||||||
|
# mbim-set-ip script version 1.1
|
||||||
|
# Modified mbimcli IPv4 IPv6 parsing script based on parts of project https://github.com/grandcentrix/thinkpad-x260-modem-scripts
|
||||||
|
# Licensed under the Apache License, Version 2.0
|
||||||
|
# Modified by Jörgen Storvist, Techship http://www.techship.com
|
||||||
|
# Further details in the Techship FAQ sections on using MBIM and setting correct modes in cellular modules:
|
||||||
|
# https://techship.com/faq/how-to-set-up-a-simple-data-connection-over-the-mbim-interface-using-libmbim-and-driver-cdc-mbim-in-linux/
|
||||||
|
#
|
||||||
|
# Installation & Usage:
|
||||||
|
#
|
||||||
|
# Verify that the cellular module is exposing the MBIM interface over the USB interface.
|
||||||
|
# Use mbimcli to check status for the cellular connection and enter the PIN code if necessary.
|
||||||
|
# Configure mbim-network.conf and place in /etc/ (example file included in the archive, check link bellow for details).
|
||||||
|
# https://www.freedesktop.org/software/libmbim/man/latest/mbim-network.1.html
|
||||||
|
# Start the mbim data connection with command:
|
||||||
|
# mbim-network <MBIM-INTERFACE> start
|
||||||
|
# Ensure execution of mbim-set-ip script with sufficient system priviledges
|
||||||
|
# ./mbim-set-ip <MBIM-INTERFACE> <NETWORK-INTERFACE>
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# mbimcli -d /dev/cdc-wdm0 -p --query-device-caps
|
||||||
|
# mbimcli -d /dev/cdc-wdm0 -p --enter-pin=1234
|
||||||
|
# mbim-network /dev/cdc-wdm0 start
|
||||||
|
# ./mbim-set-ip /dev/cdc-wdm0 wwan0
|
||||||
|
#
|
||||||
|
# You should now be able to ping over the data connection.
|
||||||
|
# IP v4 ping: (only if IPv4 address was acquired from cellular module)
|
||||||
|
# ping -4 -I wwan0 8.8.8.8
|
||||||
|
# ping -4 -I wwan0 google.com
|
||||||
|
|
||||||
|
# IP v6 ping: (only if IPv6 address was acquired from cellular module)
|
||||||
|
# ping -6 -I wwan0 2001:4860:4860::8888
|
||||||
|
# ping -6 -I wwan0 google.com
|
||||||
|
#
|
||||||
|
# The script relies on the linux tools mbimcli, ip, systemd-resolve
|
||||||
|
# (Tested on libmbim 1.16.0 running on Ubuntu 18.10 cosmic (development) with kernel version 4.15.0)
|
||||||
|
|
||||||
|
# Details on mbim-network and mbimcli
|
||||||
|
# https://www.freedesktop.org/software/libmbim/man/latest/mbim-network.1.html
|
||||||
|
# https://www.freedesktop.org/software/libmbim/man/latest/mbimcli.1.html
|
||||||
|
|
||||||
|
ipv4_addresses=()
|
||||||
|
ipv4_gateway=""
|
||||||
|
ipv4_dns=()
|
||||||
|
ipv4_mtu=""
|
||||||
|
ipv6_addresses=()
|
||||||
|
ipv6_gateway=""
|
||||||
|
ipv6_dns=()
|
||||||
|
ipv6_mtu=""
|
||||||
|
|
||||||
|
#CONTROL-IFACE
|
||||||
|
CONTROLDEV="$1"
|
||||||
|
#WWAN-IFACE
|
||||||
|
DEV="$2"
|
||||||
|
SESSION="$3"
|
||||||
|
echo $SESSION
|
||||||
|
echo "Requesting IPv4 and IPv6 information through mbimcli proxy:"
|
||||||
|
mbimcli -d $CONTROLDEV -p --query-ip-configuration
|
||||||
|
IPDATA=$(mbimcli -d $CONTROLDEV -p --query-ip-configuration=$SESSION)
|
||||||
|
|
||||||
|
function parse_ip {
|
||||||
|
# IP [0]: '10.134.203.177/30'
|
||||||
|
local line_re="IP \[([0-9]+)\]: '(.+)'"
|
||||||
|
local input=$1
|
||||||
|
if [[ $input =~ $line_re ]]; then
|
||||||
|
local ip_cnt=${BASH_REMATCH[1]}
|
||||||
|
local ip=${BASH_REMATCH[2]}
|
||||||
|
fi
|
||||||
|
echo "$ip"
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_gateway {
|
||||||
|
# Gateway: '10.134.203.178'
|
||||||
|
local line_re="Gateway: '(.+)'"
|
||||||
|
local input=$1
|
||||||
|
if [[ $input =~ $line_re ]]; then
|
||||||
|
local gw=${BASH_REMATCH[1]}
|
||||||
|
fi
|
||||||
|
echo "$gw"
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_dns {
|
||||||
|
# DNS [0]: '10.134.203.177/30'
|
||||||
|
local line_re="DNS \[([0-9]+)\]: '(.+)'"
|
||||||
|
local input=$1
|
||||||
|
if [[ $input =~ $line_re ]]; then
|
||||||
|
local dns_cnt=${BASH_REMATCH[1]}
|
||||||
|
local dns=${BASH_REMATCH[2]}
|
||||||
|
fi
|
||||||
|
echo "$dns"
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_mtu {
|
||||||
|
# MTU: '1500'
|
||||||
|
local line_re="MTU: '([0-9]+)'"
|
||||||
|
local input=$1
|
||||||
|
if [[ $input =~ $line_re ]]; then
|
||||||
|
local mtu=${BASH_REMATCH[1]}
|
||||||
|
fi
|
||||||
|
echo "$mtu"
|
||||||
|
}
|
||||||
|
while read -r line || [[ -n "$line" ]] ; do
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
case "$line" in
|
||||||
|
*"IPv4 configuration available: 'none'"*)
|
||||||
|
state="start"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"IPv4 configuration available"*)
|
||||||
|
state="ipv4"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"IPv6 configuration available: 'none'"*)
|
||||||
|
state="start"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"IPv6 configuration available"*)
|
||||||
|
state="ipv6"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$state" in
|
||||||
|
"ipv4")
|
||||||
|
|
||||||
|
case "$line" in
|
||||||
|
*"IP"*)
|
||||||
|
row=$(parse_ip "$line")
|
||||||
|
ipv4_addresses+=("$row")
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"Gateway"*)
|
||||||
|
row=$(parse_gateway "$line")
|
||||||
|
ipv4_gateway="$row"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"DNS"*)
|
||||||
|
row=$(parse_dns "$line")
|
||||||
|
ipv4_dns+=("$row")
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"MTU"*)
|
||||||
|
row=$(parse_mtu "$line")
|
||||||
|
ipv4_mtu="$row"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
|
||||||
|
"ipv6")
|
||||||
|
case "$line" in
|
||||||
|
*"IP"*)
|
||||||
|
row=$(parse_ip "$line")
|
||||||
|
ipv6_addresses+=("$row")
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"Gateway"*)
|
||||||
|
row=$(parse_gateway "$line")
|
||||||
|
ipv6_gateway="$row"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"DNS"*)
|
||||||
|
row=$(parse_dns "$line")
|
||||||
|
ipv6_dns+=("$row")
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*"MTU"*)
|
||||||
|
row=$(parse_mtu "$line")
|
||||||
|
ipv6_mtu="$row"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done <<< "$IPDATA"
|
||||||
|
|
||||||
|
execfile=$(mktemp)
|
||||||
|
|
||||||
|
printf "ip link set $DEV down\n" >> $execfile
|
||||||
|
printf "ip addr flush dev $DEV \n" >> $execfile
|
||||||
|
printf "ip -6 addr flush dev $DEV \n" >> $execfile
|
||||||
|
printf "ip link set $DEV up\n" >> $execfile
|
||||||
|
|
||||||
|
if [[ "${#ipv4_addresses[@]}" > 0 ]]; then
|
||||||
|
printf "ip addr add %s dev $DEV broadcast +\n" "${ipv4_addresses[@]}" >> $execfile
|
||||||
|
printf "ip route add 192.168.61.0/24 via $ipv4_gateway dev $DEV\n" >> $execfile
|
||||||
|
|
||||||
|
if [ -n "$ipv4_mtu" ]; then
|
||||||
|
printf "ip link set mtu $ipv4_mtu dev $DEV \n" >> $execfile
|
||||||
|
fi
|
||||||
|
if [[ "${#ipv4_dns[@]}" > 0 ]]; then
|
||||||
|
printf "resolvectl -4 --interface=$DEV --set-dns=%s\n" "${ipv4_dns[@]}" >>$execfile
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${#ipv6_addresses[@]}" > 0 ]]; then
|
||||||
|
printf "ip -6 addr add %s dev $DEV\n" "${ipv6_addresses[@]}" >> $execfile
|
||||||
|
printf "ip -6 route add default via $ipv6_gateway dev $DEV\n" >> $execfile
|
||||||
|
if [ -n "$ipv6_mtu" ]; then
|
||||||
|
printf "ip -6 link set mtu $ipv6_mtu dev $DEV\n" >> $execfile
|
||||||
|
fi
|
||||||
|
if [[ "${#ipv6_dns[@]}" > 0 ]]; then
|
||||||
|
printf "systemd-resolve -6 --interface=$DEV --set-dns=%s\n" "${ipv6_dns[@]}" >>$execfile
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "Applying the following network interface configurations:"
|
||||||
|
cat $execfile
|
||||||
|
bash $execfile
|
||||||
|
rm $execfile
|
||||||
|
echo "Network interface configurations completed."
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
set -x
|
||||||
|
|
||||||
|
sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off
|
||||||
|
sleep 1
|
||||||
|
sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=on
|
||||||
|
sleep 2
|
||||||
|
sudo mbimcli -p -d /dev/cdc-wdm0 --attach-packet-service
|
||||||
|
|
||||||
|
sudo mbimcli -p -d /dev/cdc-wdm0 --connect=session-id=0,access-string=oai.ipv4,ip-type=ipv4
|
||||||
|
sudo /opt/mbim/mbim-set-ip.sh /dev/cdc-wdm0 wwan0 0
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
set -x
|
||||||
|
|
||||||
|
sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
111111
|
111111
|
||||||
100000
|
100000
|
||||||
010000
|
010010
|
||||||
030101
|
030101
|
||||||
010001
|
010001
|
||||||
000001
|
000001
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
070000
|
070000
|
||||||
070001
|
070001
|
||||||
010010
|
010010
|
||||||
010002
|
|
||||||
030201
|
030201
|
||||||
|
|
||||||
</TestCaseRequestedList>
|
</TestCaseRequestedList>
|
||||||
@@ -80,28 +79,16 @@
|
|||||||
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
<testCase id="010000">
|
|
||||||
<class>Initialize_UE</class>
|
|
||||||
<desc>Initialize Quectel</desc>
|
|
||||||
<id>nrmodule2_quectel</id>
|
|
||||||
</testCase>
|
|
||||||
|
|
||||||
<testCase id="010002">
|
|
||||||
<class>Terminate_UE</class>
|
|
||||||
<desc>Terminate Quectel</desc>
|
|
||||||
<id>nrmodule2_quectel</id>
|
|
||||||
</testCase>
|
|
||||||
|
|
||||||
<testCase id="010001">
|
<testCase id="010001">
|
||||||
<class>Attach_UE</class>
|
<class>Attach_UE</class>
|
||||||
<desc>Attach UE</desc>
|
<desc>Attach UE</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
<testCase id="050000">
|
<testCase id="050000">
|
||||||
<class>Ping</class>
|
<class>Ping</class>
|
||||||
<desc>Ping: 20 pings</desc>
|
<desc>Ping: 20 pings</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<ping_args>-c 20 %cn_ip%</ping_args>
|
<ping_args>-c 20 %cn_ip%</ping_args>
|
||||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||||
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
||||||
@@ -110,8 +97,8 @@
|
|||||||
<testCase id="050001">
|
<testCase id="050001">
|
||||||
<class>Ping</class>
|
<class>Ping</class>
|
||||||
<desc>Ping: 100 pings, size 1024</desc>
|
<desc>Ping: 100 pings, size 1024</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<ping_args>-c 100 -s 1024 -i 0,2 %cn_ip%</ping_args>
|
<ping_args>-c 100 -s 1024 -i 0.2 %cn_ip%</ping_args>
|
||||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||||
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
||||||
</testCase>
|
</testCase>
|
||||||
@@ -121,7 +108,7 @@
|
|||||||
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||||
<iperf_args>-u -b 26M -t 60</iperf_args>
|
<iperf_args>-u -b 26M -t 60</iperf_args>
|
||||||
<direction>DL</direction>
|
<direction>DL</direction>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||||
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
||||||
<iperf_profile>single-ue</iperf_profile>
|
<iperf_profile>single-ue</iperf_profile>
|
||||||
@@ -132,7 +119,7 @@
|
|||||||
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||||
<iperf_args>-u -b 7M -t 60</iperf_args>
|
<iperf_args>-u -b 7M -t 60</iperf_args>
|
||||||
<direction>UL</direction>
|
<direction>UL</direction>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||||
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
||||||
<iperf_profile>single-ue</iperf_profile>
|
<iperf_profile>single-ue</iperf_profile>
|
||||||
@@ -141,7 +128,7 @@
|
|||||||
<testCase id="010010">
|
<testCase id="010010">
|
||||||
<class>Detach_UE</class>
|
<class>Detach_UE</class>
|
||||||
<desc>Detach UE</desc>
|
<desc>Detach UE</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
<testCase id="030201">
|
<testCase id="030201">
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
111111
|
111111
|
||||||
100000
|
100000
|
||||||
010000
|
010010
|
||||||
030101
|
030101
|
||||||
010001
|
010001
|
||||||
000001
|
000001
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
070000
|
070000
|
||||||
070001
|
070001
|
||||||
010010
|
010010
|
||||||
010002
|
|
||||||
030201
|
030201
|
||||||
|
|
||||||
</TestCaseRequestedList>
|
</TestCaseRequestedList>
|
||||||
@@ -80,28 +79,16 @@
|
|||||||
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
<testCase id="010000">
|
|
||||||
<class>Initialize_UE</class>
|
|
||||||
<desc>Initialize Quectel</desc>
|
|
||||||
<id>nrmodule2_quectel</id>
|
|
||||||
</testCase>
|
|
||||||
|
|
||||||
<testCase id="010002">
|
|
||||||
<class>Terminate_UE</class>
|
|
||||||
<desc>Terminate Quectel</desc>
|
|
||||||
<id>nrmodule2_quectel</id>
|
|
||||||
</testCase>
|
|
||||||
|
|
||||||
<testCase id="010001">
|
<testCase id="010001">
|
||||||
<class>Attach_UE</class>
|
<class>Attach_UE</class>
|
||||||
<desc>Attach UE</desc>
|
<desc>Attach UE</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
<testCase id="050000">
|
<testCase id="050000">
|
||||||
<class>Ping</class>
|
<class>Ping</class>
|
||||||
<desc>Ping: 20 pings</desc>
|
<desc>Ping: 20 pings</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<ping_args>-c 20 %cn_ip%</ping_args>
|
<ping_args>-c 20 %cn_ip%</ping_args>
|
||||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||||
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
||||||
@@ -110,8 +97,8 @@
|
|||||||
<testCase id="050001">
|
<testCase id="050001">
|
||||||
<class>Ping</class>
|
<class>Ping</class>
|
||||||
<desc>Ping: 100 pings, size 1024</desc>
|
<desc>Ping: 100 pings, size 1024</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<ping_args>-c 100 -s 1024 -i 0,2 %cn_ip%</ping_args>
|
<ping_args>-c 100 -s 1024 -i 0.2 %cn_ip%</ping_args>
|
||||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||||
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
<ping_rttavg_threshold>60</ping_rttavg_threshold>
|
||||||
</testCase>
|
</testCase>
|
||||||
@@ -121,7 +108,7 @@
|
|||||||
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||||
<iperf_args>-u -b 1M -t 60</iperf_args>
|
<iperf_args>-u -b 1M -t 60</iperf_args>
|
||||||
<direction>DL</direction>
|
<direction>DL</direction>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||||
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
||||||
<iperf_profile>single-ue</iperf_profile>
|
<iperf_profile>single-ue</iperf_profile>
|
||||||
@@ -132,7 +119,7 @@
|
|||||||
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||||
<iperf_args>-u -b 7M -t 60</iperf_args>
|
<iperf_args>-u -b 7M -t 60</iperf_args>
|
||||||
<direction>UL</direction>
|
<direction>UL</direction>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
|
||||||
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
||||||
<iperf_profile>single-ue</iperf_profile>
|
<iperf_profile>single-ue</iperf_profile>
|
||||||
@@ -141,7 +128,7 @@
|
|||||||
<testCase id="010010">
|
<testCase id="010010">
|
||||||
<class>Detach_UE</class>
|
<class>Detach_UE</class>
|
||||||
<desc>Detach UE</desc>
|
<desc>Detach UE</desc>
|
||||||
<id>nrmodule2_quectel</id>
|
<id>up2</id>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
<testCase id="030201">
|
<testCase id="030201">
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ $ docker logout
|
|||||||
All the following commands **SHALL** be run from the `ci-scripts/yaml_files/5g_rfsimulator` folder for a deployment with monolithic gNB.
|
All the following commands **SHALL** be run from the `ci-scripts/yaml_files/5g_rfsimulator` folder for a deployment with monolithic gNB.
|
||||||
|
|
||||||
For a deployment with the gNB split in CU and DU components, please refer to the `../5g_f1_rfsimulator` folder.
|
For a deployment with the gNB split in CU and DU components, please refer to the `../5g_f1_rfsimulator` folder.
|
||||||
For a deployment with the gNB split in CU-CP, CU-UP, and DU components, please refer to the ../5g_rfsimulator_e1` folder.
|
For a deployment with the gNB split in CU-CP, CU-UP, and DU components, please refer to the `../5g_rfsimulator_e1` folder.
|
||||||
|
|
||||||
## 2.1. Deploy OAI 5G Core Network ##
|
## 2.1. Deploy OAI 5G Core Network ##
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -533,20 +533,23 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void processSlotTX(void *arg) {
|
void processSlotTX(void *arg)
|
||||||
|
{
|
||||||
nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
|
nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
|
||||||
const UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
|
const UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
|
||||||
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
||||||
nr_phy_data_tx_t phy_data = {0};
|
nr_phy_data_tx_t phy_data = {0};
|
||||||
|
|
||||||
|
if (UE->if_inst)
|
||||||
|
UE->if_inst->slot_indication(UE->Mod_id);
|
||||||
|
|
||||||
LOG_D(PHY,
|
LOG_D(PHY,
|
||||||
"SlotTx %d.%d => slot type %d, wait: %d \n",
|
"SlotTx %d.%d => slot type %d, wait: %d \n",
|
||||||
proc->frame_tx,
|
proc->frame_tx,
|
||||||
proc->nr_slot_tx,
|
proc->nr_slot_tx,
|
||||||
proc->tx_slot_type,
|
proc->tx_slot_type,
|
||||||
rxtxD->tx_wait_for_dlsch);
|
rxtxD->tx_wait_for_dlsch);
|
||||||
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
|
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) {
|
||||||
if (rxtxD->tx_wait_for_dlsch)
|
if (rxtxD->tx_wait_for_dlsch)
|
||||||
LOG_D(PHY, "enter wait for tx, slot %d, nb events to wait %d; ", proc->nr_slot_tx, rxtxD->tx_wait_for_dlsch);
|
LOG_D(PHY, "enter wait for tx, slot %d, nb events to wait %d; ", proc->nr_slot_tx, rxtxD->tx_wait_for_dlsch);
|
||||||
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
|
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
|
||||||
|
|||||||
@@ -515,14 +515,11 @@ int main(int argc, char **argv)
|
|||||||
uint16_t node_number = get_softmodem_params()->node_number;
|
uint16_t node_number = get_softmodem_params()->node_number;
|
||||||
ue_id_g = (node_number == 0) ? 0 : node_number - 2;
|
ue_id_g = (node_number == 0) ? 0 : node_number - 2;
|
||||||
AssertFatal(ue_id_g >= 0, "UE id is expected to be nonnegative.\n");
|
AssertFatal(ue_id_g >= 0, "UE id is expected to be nonnegative.\n");
|
||||||
if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa || get_softmodem_params()->nsa) {
|
|
||||||
if(node_number == 0) {
|
if(node_number == 0)
|
||||||
init_pdcp(0);
|
init_pdcp(0);
|
||||||
}
|
else
|
||||||
else {
|
init_pdcp(mode_offset + ue_id_g);
|
||||||
init_pdcp(mode_offset + ue_id_g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init_NR_UE(NB_UE_INST, uecap_file, reconfig_file, rbconfig_file);
|
init_NR_UE(NB_UE_INST, uecap_file, reconfig_file, rbconfig_file);
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,12 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
|
|||||||
uint16_t dlDmrsSymbPos,
|
uint16_t dlDmrsSymbPos,
|
||||||
int chest_time_type);
|
int chest_time_type);
|
||||||
|
|
||||||
static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, int32_t dl_ch_estimates_ext[][rx_size_symbol], int32_t *median, int n_tx, int n_rx, int length);
|
static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol,
|
||||||
|
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||||
|
int32_t median[MAX_ANT][MAX_ANT],
|
||||||
|
int n_tx,
|
||||||
|
int n_rx,
|
||||||
|
int length);
|
||||||
|
|
||||||
/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for
|
/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for
|
||||||
16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
|
16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
|
||||||
@@ -205,7 +210,7 @@ static void nr_dlsch_channel_level(uint32_t rx_size_symbol,
|
|||||||
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
uint8_t n_tx,
|
uint8_t n_tx,
|
||||||
int32_t *avg,
|
int32_t avg[MAX_ANT][MAX_ANT],
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
uint32_t len,
|
uint32_t len,
|
||||||
unsigned short nb_rb);
|
unsigned short nb_rb);
|
||||||
@@ -271,7 +276,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
const int nr_slot_rx = proc->nr_slot_rx;
|
const int nr_slot_rx = proc->nr_slot_rx;
|
||||||
const int gNB_id = proc->gNB_id;
|
const int gNB_id = proc->gNB_id;
|
||||||
|
|
||||||
int avg[16];
|
|
||||||
uint8_t slot = 0;
|
uint8_t slot = 0;
|
||||||
|
|
||||||
int32_t codeword_TB0 = -1;
|
int32_t codeword_TB0 = -1;
|
||||||
@@ -431,27 +435,28 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
if (meas_enabled)
|
if (meas_enabled)
|
||||||
start_meas(&meas);
|
start_meas(&meas);
|
||||||
if (first_symbol_flag == 1) {
|
if (first_symbol_flag == 1) {
|
||||||
|
int32_t avg[MAX_ANT][MAX_ANT];
|
||||||
nr_dlsch_channel_level(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, avg, symbol, nb_re_pdsch, nb_rb_pdsch);
|
nr_dlsch_channel_level(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, avg, symbol, nb_re_pdsch, nb_rb_pdsch);
|
||||||
int avgs = 0;
|
int avgs = 0;
|
||||||
int32_t median[16];
|
int32_t median[MAX_ANT][MAX_ANT];
|
||||||
for (int aatx = 0; aatx < nl; aatx++)
|
for (int aatx = 0; aatx < nl; aatx++)
|
||||||
for (int aarx = 0; aarx < n_rx; aarx++) {
|
for (int aarx = 0; aarx < n_rx; aarx++) {
|
||||||
// LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*n_rx+aarx]);
|
// LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*n_rx+aarx]);
|
||||||
avgs = cmax(avgs, avg[(aatx * n_rx) + aarx]);
|
avgs = cmax(avgs, avg[aatx][aarx]);
|
||||||
// LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
|
// LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
|
||||||
median[(aatx * n_rx) + aarx] = avg[(aatx * n_rx) + aarx];
|
median[aatx][aarx] = avg[aatx][aarx];
|
||||||
}
|
}
|
||||||
if (nl > 1) {
|
if (nl > 1) {
|
||||||
nr_dlsch_channel_level_median(rx_size_symbol, dl_ch_estimates_ext, median, nl, n_rx, nb_re_pdsch);
|
nr_dlsch_channel_level_median(rx_size_symbol, dl_ch_estimates_ext, median, nl, n_rx, nb_re_pdsch);
|
||||||
for (int aatx = 0; aatx < nl; aatx++) {
|
for (int aatx = 0; aatx < nl; aatx++) {
|
||||||
for (int aarx = 0; aarx < n_rx; aarx++) {
|
for (int aarx = 0; aarx < n_rx; aarx++) {
|
||||||
avgs = cmax(avgs, median[aatx*n_rx + aarx]);
|
avgs = cmax(avgs, median[aatx][aarx]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
*log2_maxh = (log2_approx(avgs) / 2) + 1;
|
||||||
*log2_maxh = (log2_approx(avgs)/2) + 1;
|
// LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, log2_maxh);
|
||||||
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, log2_maxh);
|
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs);
|
||||||
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d,%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avg[0], avgs);
|
|
||||||
}
|
}
|
||||||
if (meas_enabled) {
|
if (meas_enabled) {
|
||||||
stop_meas(&meas);
|
stop_meas(&meas);
|
||||||
@@ -465,15 +470,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
meas.p_time / (cpuf * 1000.0));
|
meas.p_time / (cpuf * 1000.0));
|
||||||
}
|
}
|
||||||
#if T_TRACER
|
#if T_TRACER
|
||||||
T(T_UE_PHY_PDSCH_ENERGY,
|
T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id), T_INT(0), T_INT(frame % 1024), T_INT(nr_slot_rx));
|
||||||
T_INT(gNB_id),
|
|
||||||
T_INT(0),
|
|
||||||
T_INT(frame % 1024),
|
|
||||||
T_INT(nr_slot_rx),
|
|
||||||
T_INT(avg[0]),
|
|
||||||
T_INT(avg[1]),
|
|
||||||
T_INT(avg[2]),
|
|
||||||
T_INT(avg[3]));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@@ -1108,7 +1105,7 @@ void nr_dlsch_channel_level(uint32_t rx_size_symbol,
|
|||||||
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
uint8_t n_tx,
|
uint8_t n_tx,
|
||||||
int32_t *avg,
|
int32_t avg[MAX_ANT][MAX_ANT],
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
uint32_t len,
|
uint32_t len,
|
||||||
unsigned short nb_rb)
|
unsigned short nb_rb)
|
||||||
@@ -1137,62 +1134,45 @@ void nr_dlsch_channel_level(uint32_t rx_size_symbol,
|
|||||||
avg128D = simde_mm_add_epi32(avg128D,simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
|
avg128D = simde_mm_add_epi32(avg128D,simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
|
||||||
dl_ch128+=3;
|
dl_ch128+=3;
|
||||||
}
|
}
|
||||||
|
int32_t *tmp = (int32_t *)&avg128D;
|
||||||
avg[(aatx*frame_parms->nb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] +
|
avg[aatx][aarx] = ((int64_t)tmp[0] + tmp[1] + tmp[2] + tmp[3]) / y;
|
||||||
((int32_t*)&avg128D)[1] +
|
|
||||||
((int32_t*)&avg128D)[2] +
|
|
||||||
((int32_t*)&avg128D)[3])/y;
|
|
||||||
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
|
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
simde_mm_empty();
|
|
||||||
simde_m_empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, int32_t dl_ch_estimates_ext[][rx_size_symbol], int32_t *median, int n_tx, int n_rx, int length)
|
static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol,
|
||||||
|
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||||
|
int32_t median[MAX_ANT][MAX_ANT],
|
||||||
|
int n_tx,
|
||||||
|
int n_rx,
|
||||||
|
int length)
|
||||||
{
|
{
|
||||||
|
for (int aatx = 0; aatx < n_tx; aatx++) {
|
||||||
|
for (int aarx = 0; aarx < n_rx; aarx++) {
|
||||||
|
int64_t max = median[aatx][aarx]; // initialize the med point for max
|
||||||
|
int64_t min = median[aatx][aarx]; // initialize the med point for min
|
||||||
|
simde__m128i *dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[aatx * n_rx + aarx];
|
||||||
|
|
||||||
|
const int length2 = length >> 2; // length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop
|
||||||
|
|
||||||
short ii;
|
for (int ii = 0; ii < length2; ii++) {
|
||||||
int aatx,aarx;
|
simde__m128i norm128D =
|
||||||
int length2;
|
simde_mm_srai_epi32(simde_mm_madd_epi16(*dl_ch128, *dl_ch128), 2); //[|H_0|²/4 |H_1|²/4 |H_2|²/4 |H_3|²/4]
|
||||||
int max = 0, min=0;
|
int32_t *tmp = (int32_t *)&norm128D;
|
||||||
int norm_pack;
|
int64_t norm_pack = (int64_t)tmp[0] + tmp[1] + tmp[2] + tmp[3];
|
||||||
simde__m128i *dl_ch128, norm128D;
|
|
||||||
|
|
||||||
for (aatx=0; aatx<n_tx; aatx++) {
|
|
||||||
for (aarx=0; aarx<n_rx; aarx++) {
|
|
||||||
max = median[aatx*n_rx + aarx];//initialize the med point for max
|
|
||||||
min = median[aatx*n_rx + aarx];//initialize the med point for min
|
|
||||||
norm128D = simde_mm_setzero_si128();
|
|
||||||
|
|
||||||
dl_ch128=(simde__m128i *)dl_ch_estimates_ext[aatx*n_rx + aarx];
|
|
||||||
|
|
||||||
length2 = length>>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop
|
|
||||||
|
|
||||||
for (ii=0;ii<length2;ii++) {
|
|
||||||
norm128D = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 2);//[|H_0|²/4 |H_1|²/4 |H_2|²/4 |H_3|²/4]
|
|
||||||
//print_ints("norm128D",&norm128D[0]);
|
|
||||||
|
|
||||||
norm_pack = ((int32_t*)&norm128D)[0] +
|
|
||||||
((int32_t*)&norm128D)[1] +
|
|
||||||
((int32_t*)&norm128D)[2] +
|
|
||||||
((int32_t*)&norm128D)[3];// compute the sum
|
|
||||||
|
|
||||||
if (norm_pack > max)
|
if (norm_pack > max)
|
||||||
max = norm_pack;//store values more than max
|
max = norm_pack;
|
||||||
if (norm_pack < min)
|
if (norm_pack < min)
|
||||||
min = norm_pack;//store values less than min
|
min = norm_pack;
|
||||||
dl_ch128+=1;
|
dl_ch128+=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
median[aatx*n_rx + aarx] = (max+min)>>1;
|
median[aatx][aarx] = (max + min) >> 1;
|
||||||
//printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min);
|
//printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
simde_mm_empty();
|
|
||||||
simde_m_empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
|
|||||||
@@ -698,9 +698,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
validate_input_pmi(&gNB_mac->config[0], pdsch_AntennaPorts, g_nrOfLayers, g_pmi);
|
validate_input_pmi(&gNB_mac->config[0], pdsch_AntennaPorts, g_nrOfLayers, g_pmi);
|
||||||
|
|
||||||
NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
NR_UE_NR_Capability_t *UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
||||||
prepare_sim_uecap(UE_Capability_nr,scc,mu,
|
prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_DL, g_mcsTableIdx, 0);
|
||||||
N_RB_DL,g_mcsTableIdx,0);
|
|
||||||
|
|
||||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
|
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
|
||||||
|
|
||||||
@@ -869,7 +868,7 @@ int main(int argc, char **argv)
|
|||||||
//Configure UE
|
//Configure UE
|
||||||
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
||||||
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
||||||
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup);
|
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup, UE_Capability_nr);
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
|
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
|
||||||
|
|
||||||
|
|||||||
@@ -420,9 +420,7 @@ void release_common_ss_cset(NR_BWP_PDCCH_t *pdcch)
|
|||||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
|
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
|
||||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->ra_SS);
|
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->ra_SS);
|
||||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->paging_SS);
|
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->paging_SS);
|
||||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->search_space_zero);
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, pdcch->commonControlResourceSet);
|
asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, pdcch->commonControlResourceSet);
|
||||||
asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, pdcch->coreset0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void modlist_ss(NR_SearchSpace_t *source, NR_SearchSpace_t *target)
|
static void modlist_ss(NR_SearchSpace_t *source, NR_SearchSpace_t *target)
|
||||||
@@ -443,12 +441,13 @@ static void modlist_ss(NR_SearchSpace_t *source, NR_SearchSpace_t *target)
|
|||||||
UPDATE_MAC_IE(target->searchSpaceType, source->searchSpaceType, struct NR_SearchSpace__searchSpaceType);
|
UPDATE_MAC_IE(target->searchSpaceType, source->searchSpaceType, struct NR_SearchSpace__searchSpaceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList,
|
static NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac,
|
||||||
|
const struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList,
|
||||||
const NR_BWP_PDCCH_t *pdcch,
|
const NR_BWP_PDCCH_t *pdcch,
|
||||||
const NR_SearchSpaceId_t ss_id)
|
const NR_SearchSpaceId_t ss_id)
|
||||||
{
|
{
|
||||||
if (ss_id == 0)
|
if (ss_id == 0)
|
||||||
return pdcch->search_space_zero;
|
return mac->search_space_zero;
|
||||||
|
|
||||||
NR_SearchSpace_t *css = NULL;
|
NR_SearchSpace_t *css = NULL;
|
||||||
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
|
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
|
||||||
@@ -462,12 +461,15 @@ static NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCom
|
|||||||
return css;
|
return css;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon)
|
static void configure_common_ss_coreset(const NR_UE_MAC_INST_t *mac,
|
||||||
|
NR_BWP_PDCCH_t *pdcch,
|
||||||
|
NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon)
|
||||||
{
|
{
|
||||||
if (pdcch_ConfigCommon) {
|
if (pdcch_ConfigCommon) {
|
||||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
|
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
|
||||||
if (pdcch_ConfigCommon->searchSpaceOtherSystemInformation)
|
if (pdcch_ConfigCommon->searchSpaceOtherSystemInformation)
|
||||||
pdcch->otherSI_SS = get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList,
|
pdcch->otherSI_SS = get_common_search_space(mac,
|
||||||
|
pdcch_ConfigCommon->commonSearchSpaceList,
|
||||||
pdcch,
|
pdcch,
|
||||||
*pdcch_ConfigCommon->searchSpaceOtherSystemInformation);
|
*pdcch_ConfigCommon->searchSpaceOtherSystemInformation);
|
||||||
|
|
||||||
@@ -477,7 +479,7 @@ static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCo
|
|||||||
pdcch->ra_SS = pdcch->otherSI_SS;
|
pdcch->ra_SS = pdcch->otherSI_SS;
|
||||||
else
|
else
|
||||||
pdcch->ra_SS =
|
pdcch->ra_SS =
|
||||||
get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->ra_SearchSpace);
|
get_common_search_space(mac, pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->ra_SearchSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->paging_SS);
|
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->paging_SS);
|
||||||
@@ -488,7 +490,7 @@ static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCo
|
|||||||
pdcch->paging_SS = pdcch->ra_SS;
|
pdcch->paging_SS = pdcch->ra_SS;
|
||||||
if (!pdcch->paging_SS)
|
if (!pdcch->paging_SS)
|
||||||
pdcch->paging_SS =
|
pdcch->paging_SS =
|
||||||
get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->pagingSearchSpace);
|
get_common_search_space(mac, pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->pagingSearchSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
UPDATE_MAC_IE(pdcch->commonControlResourceSet, pdcch_ConfigCommon->commonControlResourceSet, NR_ControlResourceSet_t);
|
UPDATE_MAC_IE(pdcch->commonControlResourceSet, pdcch_ConfigCommon->commonControlResourceSet, NR_ControlResourceSet_t);
|
||||||
@@ -1304,7 +1306,7 @@ static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Do
|
|||||||
NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id];
|
NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id];
|
||||||
if (dl_common->pdcch_ConfigCommon) {
|
if (dl_common->pdcch_ConfigCommon) {
|
||||||
if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup)
|
if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup)
|
||||||
configure_common_ss_coreset(pdcch, dl_common->pdcch_ConfigCommon->choice.setup);
|
configure_common_ss_coreset(mac, pdcch, dl_common->pdcch_ConfigCommon->choice.setup);
|
||||||
if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_release)
|
if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_release)
|
||||||
release_common_ss_cset(pdcch);
|
release_common_ss_cset(pdcch);
|
||||||
}
|
}
|
||||||
@@ -1905,9 +1907,64 @@ static void configure_BWPs(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_mac_uecap_info(NR_UE_MAC_INST_t *mac, NR_UE_NR_Capability_t *ue_Capability)
|
||||||
|
{
|
||||||
|
if (!ue_Capability->featureSets)
|
||||||
|
return;
|
||||||
|
if (ue_Capability->featureSets->featureSetsDownlinkPerCC) {
|
||||||
|
struct NR_FeatureSets__featureSetsDownlinkPerCC *fs_dlcc_list = ue_Capability->featureSets->featureSetsDownlinkPerCC;
|
||||||
|
for (int i = 0; i < fs_dlcc_list->list.count; i++) {
|
||||||
|
NR_FeatureSetDownlinkPerCC_t *fs_dl_cc = fs_dlcc_list->list.array[i];
|
||||||
|
if (mac->current_DL_BWP->scs != fs_dl_cc->supportedSubcarrierSpacingDL)
|
||||||
|
continue;
|
||||||
|
int uecap_bw_index;
|
||||||
|
if (fs_dl_cc->supportedBandwidthDL.present == NR_SupportedBandwidth_PR_fr1) {
|
||||||
|
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr1;
|
||||||
|
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
|
||||||
|
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
|
||||||
|
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_dl_cc->channelBW_90mhz)
|
||||||
|
uecap_bw_index++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr2;
|
||||||
|
int dl_bw_mhz = mac->phy_config.config_req.carrier_config.dl_bandwidth;
|
||||||
|
if (dl_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
|
||||||
|
continue;
|
||||||
|
if (fs_dl_cc->maxNumberMIMO_LayersPDSCH)
|
||||||
|
mac->uecap_maxMIMO_PDSCH_layers = 2 << *fs_dl_cc->maxNumberMIMO_LayersPDSCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ue_Capability->featureSets->featureSetsUplinkPerCC) {
|
||||||
|
struct NR_FeatureSets__featureSetsUplinkPerCC *fs_ulcc_list = ue_Capability->featureSets->featureSetsUplinkPerCC;
|
||||||
|
for (int i = 0; i < fs_ulcc_list->list.count; i++) {
|
||||||
|
NR_FeatureSetUplinkPerCC_t *fs_ul_cc = fs_ulcc_list->list.array[i];
|
||||||
|
if (mac->current_UL_BWP->scs != fs_ul_cc->supportedSubcarrierSpacingUL)
|
||||||
|
continue;
|
||||||
|
int uecap_bw_index;
|
||||||
|
if (fs_ul_cc->supportedBandwidthUL.present == NR_SupportedBandwidth_PR_fr1) {
|
||||||
|
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr1;
|
||||||
|
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
|
||||||
|
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
|
||||||
|
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_ul_cc->channelBW_90mhz)
|
||||||
|
uecap_bw_index++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr2;
|
||||||
|
int ul_bw_mhz = mac->phy_config.config_req.carrier_config.uplink_bandwidth;
|
||||||
|
if (ul_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
|
||||||
|
continue;
|
||||||
|
if (fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH)
|
||||||
|
mac->uecap_maxMIMO_PUSCH_layers_nocb = 1 << *fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH;
|
||||||
|
if (fs_ul_cc->mimo_CB_PUSCH && fs_ul_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH)
|
||||||
|
mac->uecap_maxMIMO_PUSCH_layers_cb = 1 << *fs_ul_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||||
int cc_idP,
|
int cc_idP,
|
||||||
NR_CellGroupConfig_t *cell_group_config)
|
NR_CellGroupConfig_t *cell_group_config,
|
||||||
|
NR_UE_NR_Capability_t *ue_Capability)
|
||||||
{
|
{
|
||||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||||
AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
|
AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
|
||||||
@@ -1937,6 +1994,9 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
|||||||
cell_group_config->rlc_BearerToAddModList,
|
cell_group_config->rlc_BearerToAddModList,
|
||||||
cell_group_config->rlc_BearerToReleaseList);
|
cell_group_config->rlc_BearerToReleaseList);
|
||||||
|
|
||||||
|
if (ue_Capability)
|
||||||
|
handle_mac_uecap_info(mac, ue_Capability);
|
||||||
|
|
||||||
// Setup the SSB to Rach Occasions mapping according to the config
|
// Setup the SSB to Rach Occasions mapping according to the config
|
||||||
// Only if RACH is configured for current BWP
|
// Only if RACH is configured for current BWP
|
||||||
if (mac->current_UL_BWP->rach_ConfigCommon)
|
if (mac->current_UL_BWP->rach_ConfigCommon)
|
||||||
|
|||||||
@@ -322,10 +322,8 @@ typedef struct {
|
|||||||
/// Msg3 buffer
|
/// Msg3 buffer
|
||||||
uint8_t *Msg3_buffer;
|
uint8_t *Msg3_buffer;
|
||||||
|
|
||||||
/// Random-access Contention Resolution Timer active flag
|
/// Random-access Contention Resolution Timer
|
||||||
uint8_t RA_contention_resolution_timer_active;
|
NR_timer_t contention_resolution_timer;
|
||||||
int RA_contention_resolution_target_frame;
|
|
||||||
int RA_contention_resolution_target_slot;
|
|
||||||
/// Transmitted UE Contention Resolution Identifier
|
/// Transmitted UE Contention Resolution Identifier
|
||||||
uint8_t cont_res_id[6];
|
uint8_t cont_res_id[6];
|
||||||
|
|
||||||
@@ -446,9 +444,7 @@ typedef struct {
|
|||||||
NR_SearchSpace_t *otherSI_SS;
|
NR_SearchSpace_t *otherSI_SS;
|
||||||
NR_SearchSpace_t *ra_SS;
|
NR_SearchSpace_t *ra_SS;
|
||||||
NR_SearchSpace_t *paging_SS;
|
NR_SearchSpace_t *paging_SS;
|
||||||
NR_ControlResourceSet_t *coreset0;
|
|
||||||
NR_ControlResourceSet_t *commonControlResourceSet;
|
NR_ControlResourceSet_t *commonControlResourceSet;
|
||||||
NR_SearchSpace_t *search_space_zero;
|
|
||||||
A_SEQUENCE_OF(NR_ControlResourceSet_t) list_Coreset;
|
A_SEQUENCE_OF(NR_ControlResourceSet_t) list_Coreset;
|
||||||
A_SEQUENCE_OF(NR_SearchSpace_t) list_SS;
|
A_SEQUENCE_OF(NR_SearchSpace_t) list_SS;
|
||||||
} NR_BWP_PDCCH_t;
|
} NR_BWP_PDCCH_t;
|
||||||
@@ -472,12 +468,18 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
A_SEQUENCE_OF(NR_UE_DL_BWP_t) dl_BWPs;
|
A_SEQUENCE_OF(NR_UE_DL_BWP_t) dl_BWPs;
|
||||||
A_SEQUENCE_OF(NR_UE_UL_BWP_t) ul_BWPs;
|
A_SEQUENCE_OF(NR_UE_UL_BWP_t) ul_BWPs;
|
||||||
NR_BWP_PDCCH_t config_BWP_PDCCH[MAX_NUM_BWP_UE];
|
NR_BWP_PDCCH_t config_BWP_PDCCH[MAX_NUM_BWP_UE];
|
||||||
|
NR_ControlResourceSet_t *coreset0;
|
||||||
|
NR_SearchSpace_t *search_space_zero;
|
||||||
NR_UE_DL_BWP_t *current_DL_BWP;
|
NR_UE_DL_BWP_t *current_DL_BWP;
|
||||||
NR_UE_UL_BWP_t *current_UL_BWP;
|
NR_UE_UL_BWP_t *current_UL_BWP;
|
||||||
|
|
||||||
bool harq_ACK_SpatialBundlingPUCCH;
|
bool harq_ACK_SpatialBundlingPUCCH;
|
||||||
bool harq_ACK_SpatialBundlingPUSCH;
|
bool harq_ACK_SpatialBundlingPUSCH;
|
||||||
|
|
||||||
|
uint32_t uecap_maxMIMO_PDSCH_layers;
|
||||||
|
uint32_t uecap_maxMIMO_PUSCH_layers_cb;
|
||||||
|
uint32_t uecap_maxMIMO_PUSCH_layers_nocb;
|
||||||
|
|
||||||
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
|
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
|
||||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
|
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@
|
|||||||
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac);
|
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac);
|
||||||
|
|
||||||
void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
|
void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
|
||||||
|
void update_mac_timers(NR_UE_MAC_INST_t *mac);
|
||||||
|
|
||||||
/**\brief apply default configuration values in nr_mac instance
|
/**\brief apply default configuration values in nr_mac instance
|
||||||
\param mac mac instance */
|
\param mac mac instance */
|
||||||
@@ -179,7 +180,8 @@ void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long chan
|
|||||||
|
|
||||||
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||||
int cc_idP,
|
int cc_idP,
|
||||||
NR_CellGroupConfig_t *cell_group_config);
|
NR_CellGroupConfig_t *cell_group_config,
|
||||||
|
NR_UE_NR_Capability_t *ue_Capability);
|
||||||
|
|
||||||
void nr_rrc_mac_config_req_mib(module_id_t module_id,
|
void nr_rrc_mac_config_req_mib(module_id_t module_id,
|
||||||
int cc_idP,
|
int cc_idP,
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
|||||||
mac->servCellIndex = 0;
|
mac->servCellIndex = 0;
|
||||||
mac->harq_ACK_SpatialBundlingPUCCH = false;
|
mac->harq_ACK_SpatialBundlingPUCCH = false;
|
||||||
mac->harq_ACK_SpatialBundlingPUSCH = false;
|
mac->harq_ACK_SpatialBundlingPUSCH = false;
|
||||||
|
mac->uecap_maxMIMO_PDSCH_layers = 0;
|
||||||
|
mac->uecap_maxMIMO_PUSCH_layers_cb = 0;
|
||||||
|
mac->uecap_maxMIMO_PUSCH_layers_nocb = 0;
|
||||||
|
|
||||||
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
||||||
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
||||||
@@ -220,6 +223,9 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac)
|
|||||||
for (int i = 0; i < mac->ul_BWPs.count; i++)
|
for (int i = 0; i < mac->ul_BWPs.count; i++)
|
||||||
release_ul_BWP(mac, i);
|
release_ul_BWP(mac, i);
|
||||||
|
|
||||||
|
asn1cFreeStruc(asn_DEF_NR_SearchSpace, mac->search_space_zero);
|
||||||
|
asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0);
|
||||||
|
|
||||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||||
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||||
asn_sequence_del(&mac->lc_ordered_list, i, 0);
|
asn_sequence_del(&mac->lc_ordered_list, i, 0);
|
||||||
|
|||||||
@@ -592,22 +592,14 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
|
|||||||
RA_config_t *ra = &mac->ra;
|
RA_config_t *ra = &mac->ra;
|
||||||
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
|
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
|
||||||
long mu = mac->current_UL_BWP->scs;
|
long mu = mac->current_UL_BWP->scs;
|
||||||
int subframes_per_slot = nr_slots_per_frame[mu]/10;
|
int subframes_per_slot = nr_slots_per_frame[mu] / 10;
|
||||||
|
|
||||||
// start contention resolution timer (cnt in slots)
|
// start contention resolution timer
|
||||||
int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1)<<3;
|
int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3;
|
||||||
|
// timer step 1 slot and timer target given by ra_ContentionResolutionTimer
|
||||||
|
nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_subframes * subframes_per_slot, 1);
|
||||||
|
nr_timer_start(&ra->contention_resolution_timer);
|
||||||
|
|
||||||
ra->RA_contention_resolution_target_frame = (frameP + (RA_contention_resolution_timer_subframes/10)) % MAX_FRAME_NUMBER;
|
|
||||||
ra->RA_contention_resolution_target_slot = (slotP + (RA_contention_resolution_timer_subframes * subframes_per_slot)) % nr_slots_per_frame[mu];
|
|
||||||
|
|
||||||
LOG_D(MAC,"[UE %d] CB-RA: contention resolution timer set in frame.slot %d.%d and expiring in %d.%d\n",
|
|
||||||
mac->ue_id,
|
|
||||||
frameP,
|
|
||||||
slotP,
|
|
||||||
ra->RA_contention_resolution_target_frame,
|
|
||||||
ra->RA_contention_resolution_target_slot);
|
|
||||||
|
|
||||||
ra->RA_contention_resolution_timer_active = 1;
|
|
||||||
ra->ra_state = WAIT_CONTENTION_RESOLUTION;
|
ra->ra_state = WAIT_CONTENTION_RESOLUTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,7 +762,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ra->RA_contention_resolution_timer_active) {
|
if (is_nr_timer_active(ra->contention_resolution_timer)) {
|
||||||
nr_ue_contention_resolution(mac, CC_id, frame, nr_slot_tx, prach_resources);
|
nr_ue_contention_resolution(mac, CC_id, frame, nr_slot_tx, prach_resources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -826,16 +818,12 @@ void nr_ue_contention_resolution(NR_UE_MAC_INST_t *mac, int cc_id, frame_t frame
|
|||||||
{
|
{
|
||||||
RA_config_t *ra = &mac->ra;
|
RA_config_t *ra = &mac->ra;
|
||||||
|
|
||||||
if (ra->RA_contention_resolution_timer_active == 1) {
|
if (nr_timer_expired(ra->contention_resolution_timer)) {
|
||||||
if (frame >= ra->RA_contention_resolution_target_frame &&
|
ra->t_crnti = 0;
|
||||||
slot >= ra->RA_contention_resolution_target_slot) {
|
nr_timer_stop(&ra->contention_resolution_timer);
|
||||||
ra->t_crnti = 0;
|
// Signal PHY to quit RA procedure
|
||||||
ra->RA_active = 0;
|
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
|
||||||
ra->RA_contention_resolution_timer_active = 0;
|
nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
|
||||||
// Signal PHY to quit RA procedure
|
|
||||||
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
|
|
||||||
nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,7 +840,7 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
|
|||||||
ra->RA_window_cnt = -1;
|
ra->RA_window_cnt = -1;
|
||||||
} else {
|
} else {
|
||||||
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mac->ue_id, frame, slot);
|
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mac->ue_id, frame, slot);
|
||||||
ra->RA_contention_resolution_timer_active = 0;
|
nr_timer_stop(&ra->contention_resolution_timer);
|
||||||
mac->crnti = ra->t_crnti;
|
mac->crnti = ra->t_crnti;
|
||||||
ra->t_crnti = 0;
|
ra->t_crnti = 0;
|
||||||
LOG_D(MAC, "[UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
|
LOG_D(MAC, "[UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
coreset = ue_get_coreset(pdcch_config, coreset_id);
|
coreset = ue_get_coreset(pdcch_config, coreset_id);
|
||||||
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
|
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
|
||||||
} else {
|
} else {
|
||||||
coreset = pdcch_config->coreset0;
|
coreset = mac->coreset0;
|
||||||
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
|
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,22 +483,22 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
|||||||
mac->mib_ssb,
|
mac->mib_ssb,
|
||||||
1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame
|
1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame
|
||||||
ssb_offset_point_a);
|
ssb_offset_point_a);
|
||||||
if (pdcch_config->search_space_zero == NULL)
|
if (mac->search_space_zero == NULL)
|
||||||
pdcch_config->search_space_zero = calloc(1, sizeof(*pdcch_config->search_space_zero));
|
mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero));
|
||||||
if (pdcch_config->coreset0 == NULL)
|
if (mac->coreset0 == NULL)
|
||||||
pdcch_config->coreset0 = calloc(1, sizeof(*pdcch_config->coreset0));
|
mac->coreset0 = calloc(1, sizeof(*mac->coreset0));
|
||||||
fill_coresetZero(pdcch_config->coreset0, &mac->type0_PDCCH_CSS_config);
|
fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config);
|
||||||
fill_searchSpaceZero(pdcch_config->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config);
|
fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config);
|
||||||
if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->search_space_zero)) {
|
if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero)) {
|
||||||
LOG_D(NR_MAC, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot);
|
LOG_D(NR_MAC, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot);
|
||||||
config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, pdcch_config->search_space_zero);
|
config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, mac->search_space_zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mac->get_otherSI) {
|
if (mac->get_otherSI) {
|
||||||
// If searchSpaceOtherSystemInformation is set to zero,
|
// If searchSpaceOtherSystemInformation is set to zero,
|
||||||
// PDCCH monitoring occasions for SI message reception in SI-window
|
// PDCCH monitoring occasions for SI message reception in SI-window
|
||||||
// are same as PDCCH monitoring occasions for SIB1
|
// are same as PDCCH monitoring occasions for SIB1
|
||||||
const NR_SearchSpace_t *ss = pdcch_config->otherSI_SS ? pdcch_config->otherSI_SS : pdcch_config->search_space_zero;
|
const NR_SearchSpace_t *ss = pdcch_config->otherSI_SS ? pdcch_config->otherSI_SS : mac->search_space_zero;
|
||||||
// TODO configure SI-window
|
// TODO configure SI-window
|
||||||
if (monitior_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) {
|
if (monitior_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) {
|
||||||
LOG_D(NR_MAC, "Monitoring DCI for other SIs in frame %d slot %d\n", frame, slot);
|
LOG_D(NR_MAC, "Monitoring DCI for other SIs in frame %d slot %d\n", frame, slot);
|
||||||
|
|||||||
@@ -1190,8 +1190,13 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
||||||
AssertFatal(sc_info->maxMIMO_Layers_PDSCH != NULL, "Option with max MIMO layers not configured is not supported\n");
|
int max_mimo_layers = 0;
|
||||||
int nl_tbslbrm = *sc_info->maxMIMO_Layers_PDSCH < 4 ? *sc_info->maxMIMO_Layers_PDSCH : 4;
|
if (sc_info->maxMIMO_Layers_PDSCH)
|
||||||
|
max_mimo_layers = *sc_info->maxMIMO_Layers_PDSCH;
|
||||||
|
else
|
||||||
|
max_mimo_layers = mac->uecap_maxMIMO_PDSCH_layers;
|
||||||
|
AssertFatal(max_mimo_layers > 0, "Invalid number of max MIMO layers for PDSCH\n");
|
||||||
|
int nl_tbslbrm = max_mimo_layers < 4 ? max_mimo_layers : 4;
|
||||||
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, sc_info->dl_bw_tbslbrm, nl_tbslbrm);
|
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, sc_info->dl_bw_tbslbrm, nl_tbslbrm);
|
||||||
/*PTRS configuration */
|
/*PTRS configuration */
|
||||||
dlsch_pdu->pduBitmap = 0;
|
dlsch_pdu->pduBitmap = 0;
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_
|
|||||||
return pdu;
|
return pdu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_mac_timers(NR_UE_MAC_INST_t *mac)
|
||||||
|
{
|
||||||
|
nr_timer_tick(&mac->ra.contention_resolution_timer);
|
||||||
|
}
|
||||||
|
|
||||||
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu)
|
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu)
|
||||||
{
|
{
|
||||||
pdu->privateNBpdus--;
|
pdu->privateNBpdus--;
|
||||||
@@ -698,16 +703,28 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
N_PRB_oh = 0;
|
N_PRB_oh = 0;
|
||||||
|
|
||||||
if (sc_info->rateMatching_PUSCH) {
|
if (sc_info->rateMatching_PUSCH) {
|
||||||
long *maxMIMO_Layers = sc_info->maxMIMO_Layers_PUSCH;
|
long maxMIMO_Layers = 0;
|
||||||
if (!maxMIMO_Layers)
|
if (sc_info->maxMIMO_Layers_PUSCH)
|
||||||
maxMIMO_Layers = pusch_Config ? pusch_Config->maxRank : NULL;
|
maxMIMO_Layers = *sc_info->maxMIMO_Layers_PUSCH;
|
||||||
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n");
|
else if (pusch_Config && pusch_Config->maxRank)
|
||||||
pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, sc_info->ul_bw_tbslbrm, *maxMIMO_Layers);
|
maxMIMO_Layers = *pusch_Config->maxRank;
|
||||||
|
else {
|
||||||
|
if (pusch_Config && pusch_Config->txConfig) {
|
||||||
|
if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)
|
||||||
|
maxMIMO_Layers = mac->uecap_maxMIMO_PUSCH_layers_cb;
|
||||||
|
else
|
||||||
|
maxMIMO_Layers = mac->uecap_maxMIMO_PUSCH_layers_nocb;
|
||||||
|
} else
|
||||||
|
maxMIMO_Layers = 1; // single antenna port
|
||||||
|
}
|
||||||
|
AssertFatal (maxMIMO_Layers > 0, "Invalid number of max MIMO layers for PUSCH\n");
|
||||||
|
pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, sc_info->ul_bw_tbslbrm, maxMIMO_Layers);
|
||||||
} else
|
} else
|
||||||
pusch_config_pdu->tbslbrm = 0;
|
pusch_config_pdu->tbslbrm = 0;
|
||||||
|
|
||||||
/* PTRS */
|
/* PTRS */
|
||||||
if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
|
if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB &&
|
||||||
|
pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
|
||||||
if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) {
|
if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) {
|
||||||
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
|
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
|
||||||
pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
|
pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
|
||||||
@@ -724,7 +741,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
if(valid_ptrs_setup == true) {
|
if(valid_ptrs_setup == true) {
|
||||||
pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
|
pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
|
||||||
}
|
}
|
||||||
LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
|
LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n",
|
||||||
|
pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1278,6 +1278,14 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info)
|
|||||||
return ret2;
|
return ret2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_ue_slot_indication(uint8_t mod_id)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mac_IF_mutex);
|
||||||
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||||
|
update_mac_timers(mac);
|
||||||
|
pthread_mutex_unlock(&mac_IF_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id)
|
nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id)
|
||||||
{
|
{
|
||||||
if (nr_ue_if_module_inst[module_id] == NULL) {
|
if (nr_ue_if_module_inst[module_id] == NULL) {
|
||||||
@@ -1295,6 +1303,7 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id)
|
|||||||
nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response;
|
nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response;
|
||||||
nr_ue_if_module_inst[module_id]->dl_indication = nr_ue_dl_indication;
|
nr_ue_if_module_inst[module_id]->dl_indication = nr_ue_dl_indication;
|
||||||
nr_ue_if_module_inst[module_id]->ul_indication = nr_ue_ul_indication;
|
nr_ue_if_module_inst[module_id]->ul_indication = nr_ue_ul_indication;
|
||||||
|
nr_ue_if_module_inst[module_id]->slot_indication = nr_ue_slot_indication;
|
||||||
}
|
}
|
||||||
pthread_mutex_init(&mac_IF_mutex, NULL);
|
pthread_mutex_init(&mac_IF_mutex, NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info);
|
|||||||
*/
|
*/
|
||||||
typedef int (nr_ue_ul_indication_f)(nr_uplink_indication_t *ul_info);
|
typedef int (nr_ue_ul_indication_f)(nr_uplink_indication_t *ul_info);
|
||||||
|
|
||||||
|
typedef void (nr_ue_slot_indication_f)(uint8_t mod_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic type of an application-defined callback to return various
|
* Generic type of an application-defined callback to return various
|
||||||
@@ -263,6 +264,7 @@ typedef struct nr_ue_if_module_s {
|
|||||||
nr_ue_dl_indication_f *dl_indication;
|
nr_ue_dl_indication_f *dl_indication;
|
||||||
nr_ue_ul_indication_f *ul_indication;
|
nr_ue_ul_indication_f *ul_indication;
|
||||||
nr_ue_sl_indication_f *sl_indication;
|
nr_ue_sl_indication_f *sl_indication;
|
||||||
|
nr_ue_slot_indication_f *slot_indication;
|
||||||
uint32_t cc_mask;
|
uint32_t cc_mask;
|
||||||
uint32_t current_frame;
|
uint32_t current_frame;
|
||||||
uint32_t current_slot;
|
uint32_t current_slot;
|
||||||
|
|||||||
+253
-286
@@ -133,12 +133,10 @@ static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = {
|
|||||||
0x11,
|
0x11,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
|
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
|
||||||
const NR_CellGroupConfig_t *cellGroupConfig,
|
const NR_CellGroupConfig_t *cellGroupConfig);
|
||||||
rrcPerNB_t *nb);
|
|
||||||
|
|
||||||
static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
||||||
rrcPerNB_t *rrcNB,
|
|
||||||
NR_RadioBearerConfig_t *const radioBearerConfig);
|
NR_RadioBearerConfig_t *const radioBearerConfig);
|
||||||
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment);
|
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment);
|
||||||
static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len);
|
static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len);
|
||||||
@@ -148,7 +146,6 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
|
|||||||
|
|
||||||
static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry);
|
static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry);
|
||||||
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||||
rrcPerNB_t *rrcNB,
|
|
||||||
OCTET_STRING_t *masterCellGroup,
|
OCTET_STRING_t *masterCellGroup,
|
||||||
long *fullConfig);
|
long *fullConfig);
|
||||||
|
|
||||||
@@ -166,7 +163,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
|
|||||||
|
|
||||||
if (ie->radioBearerConfig != NULL) {
|
if (ie->radioBearerConfig != NULL) {
|
||||||
LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
|
LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
|
||||||
nr_rrc_ue_process_RadioBearerConfig(rrc, rrcNB, ie->radioBearerConfig);
|
nr_rrc_ue_process_RadioBearerConfig(rrc, ie->radioBearerConfig);
|
||||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||||
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ie->radioBearerConfig);
|
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ie->radioBearerConfig);
|
||||||
}
|
}
|
||||||
@@ -174,7 +171,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
|
|||||||
if (ie->nonCriticalExtension) {
|
if (ie->nonCriticalExtension) {
|
||||||
NR_RRCReconfiguration_v1530_IEs_t *ext = ie->nonCriticalExtension;
|
NR_RRCReconfiguration_v1530_IEs_t *ext = ie->nonCriticalExtension;
|
||||||
if (ext->masterCellGroup)
|
if (ext->masterCellGroup)
|
||||||
nr_rrc_ue_process_masterCellGroup(rrc, rrcNB, ext->masterCellGroup, ext->fullConfig);
|
nr_rrc_ue_process_masterCellGroup(rrc, ext->masterCellGroup, ext->fullConfig);
|
||||||
/* Check if there is dedicated NAS information to forward to NAS */
|
/* Check if there is dedicated NAS information to forward to NAS */
|
||||||
if (ie->nonCriticalExtension->dedicatedNAS_MessageList) {
|
if (ie->nonCriticalExtension->dedicatedNAS_MessageList) {
|
||||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList;
|
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList;
|
||||||
@@ -212,11 +209,10 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
|
|||||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||||
|
|
||||||
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
|
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig);
|
||||||
|
|
||||||
AssertFatal(!get_softmodem_params()->sa, "secondaryCellGroup only used in NSA for now\n");
|
AssertFatal(!get_softmodem_params()->sa, "secondaryCellGroup only used in NSA for now\n");
|
||||||
nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig);
|
nr_rrc_mac_config_req_cg(0, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability);
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
||||||
}
|
}
|
||||||
if (ie->measConfig != NULL) {
|
if (ie->measConfig != NULL) {
|
||||||
@@ -240,52 +236,48 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
|
|||||||
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
|
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
|
||||||
{
|
{
|
||||||
switch (nsa_message_type) {
|
switch (nsa_message_type) {
|
||||||
case nr_SecondaryCellGroupConfig_r15:
|
case nr_SecondaryCellGroupConfig_r15: {
|
||||||
{
|
NR_RRCReconfiguration_t *RRCReconfiguration=NULL;
|
||||||
NR_RRCReconfiguration_t *RRCReconfiguration=NULL;
|
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
&asn_DEF_NR_RRCReconfiguration,
|
||||||
&asn_DEF_NR_RRCReconfiguration,
|
(void **)&RRCReconfiguration,
|
||||||
(void **)&RRCReconfiguration,
|
(uint8_t *)message,
|
||||||
(uint8_t *)message,
|
msg_len);
|
||||||
msg_len);
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
// free the memory
|
||||||
LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
|
SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
|
||||||
// free the memory
|
return;
|
||||||
SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nr_rrc_ue_process_rrcReconfiguration(rrc, 0, RRCReconfiguration);
|
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration);
|
|
||||||
}
|
}
|
||||||
break;
|
nr_rrc_ue_process_rrcReconfiguration(rrc, 0, RRCReconfiguration);
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nr_RadioBearerConfigX_r15:
|
case nr_RadioBearerConfigX_r15: {
|
||||||
{
|
NR_RadioBearerConfig_t *RadioBearerConfig=NULL;
|
||||||
NR_RadioBearerConfig_t *RadioBearerConfig=NULL;
|
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
&asn_DEF_NR_RadioBearerConfig,
|
||||||
&asn_DEF_NR_RadioBearerConfig,
|
(void **)&RadioBearerConfig,
|
||||||
(void **)&RadioBearerConfig,
|
(uint8_t *)message,
|
||||||
(uint8_t *)message,
|
msg_len);
|
||||||
msg_len);
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
// free the memory
|
||||||
LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
|
SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
|
||||||
// free the memory
|
return;
|
||||||
SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig()with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n",
|
|
||||||
RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity,
|
|
||||||
RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
|
|
||||||
RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm,
|
|
||||||
*RadioBearerConfig->securityConfig->keyToUse);
|
|
||||||
nr_rrc_ue_process_RadioBearerConfig(rrc, rrc->perNB + 0, RadioBearerConfig);
|
|
||||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
|
||||||
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig);
|
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
|
|
||||||
}
|
}
|
||||||
break;
|
LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig()with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n",
|
||||||
|
RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity,
|
||||||
|
RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
|
||||||
|
RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm,
|
||||||
|
*RadioBearerConfig->securityConfig->keyToUse);
|
||||||
|
nr_rrc_ue_process_RadioBearerConfig(rrc, RadioBearerConfig);
|
||||||
|
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||||
|
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig);
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
|
AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
|
||||||
@@ -308,21 +300,39 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
|
|||||||
rrc->ul_bwp_id = 0;
|
rrc->ul_bwp_id = 0;
|
||||||
rrc->as_security_activated = false;
|
rrc->as_security_activated = false;
|
||||||
rrc->ra_trigger = RA_NOT_RUNNING;
|
rrc->ra_trigger = RA_NOT_RUNNING;
|
||||||
rrc->uecap_file = uecap_file;
|
|
||||||
|
FILE *f = NULL;
|
||||||
|
if (uecap_file)
|
||||||
|
f = fopen(uecap_file, "r");
|
||||||
|
if(f) {
|
||||||
|
char UE_NR_Capability_xer[65536];
|
||||||
|
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
||||||
|
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
||||||
|
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
asn_dec_rval_t dec_rval =
|
||||||
|
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
|
||||||
|
assert(dec_rval.code == RC_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
|
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
|
||||||
set_default_timers_and_constants(&rrc->timers_and_constants);
|
set_default_timers_and_constants(&rrc->timers_and_constants);
|
||||||
|
|
||||||
|
for (int j = 0; j < NR_NUM_SRB; j++)
|
||||||
|
rrc->Srb[j] = RB_NOT_PRESENT;
|
||||||
|
for (int j = 0; j < MAX_DRBS_PER_UE; j++)
|
||||||
|
rrc->status_DRBs[j] = RB_NOT_PRESENT;
|
||||||
|
// SRB0 activated by default
|
||||||
|
rrc->Srb[0] = RB_ESTABLISHED;
|
||||||
|
for (int j = 0; j < NR_MAX_NUM_LCID; j++)
|
||||||
|
rrc->active_RLC_entity[j] = false;
|
||||||
|
|
||||||
for (int i = 0; i < NB_CNX_UE; i++) {
|
for (int i = 0; i < NB_CNX_UE; i++) {
|
||||||
rrcPerNB_t *ptr = &rrc->perNB[i];
|
rrcPerNB_t *ptr = &rrc->perNB[i];
|
||||||
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
|
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
|
||||||
init_SI_timers(&ptr->SInfo);
|
init_SI_timers(&ptr->SInfo);
|
||||||
for (int j = 0; j < NR_NUM_SRB; j++)
|
|
||||||
ptr->Srb[j] = RB_NOT_PRESENT;
|
|
||||||
for (int j = 0; j < MAX_DRBS_PER_UE; j++)
|
|
||||||
ptr->status_DRBs[j] = RB_NOT_PRESENT;
|
|
||||||
// SRB0 activated by default
|
|
||||||
ptr->Srb[0] = RB_ESTABLISHED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_sidelink(rrc);
|
init_sidelink(rrc);
|
||||||
@@ -696,9 +706,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
|
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
|
||||||
const NR_CellGroupConfig_t *cellGroupConfig,
|
const NR_CellGroupConfig_t *cellGroupConfig)
|
||||||
rrcPerNB_t *nb)
|
|
||||||
{
|
{
|
||||||
if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
|
if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
|
||||||
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
|
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
|
||||||
@@ -712,12 +721,12 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
|
|||||||
for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||||
NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
|
NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
|
||||||
NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
|
NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
|
||||||
if (nb->active_RLC_entity[lcid]) {
|
if (rrc->active_RLC_entity[lcid]) {
|
||||||
if (rlc_bearer->reestablishRLC)
|
if (rlc_bearer->reestablishRLC)
|
||||||
nr_rlc_reestablish_entity(rrc->ue_id, lcid);
|
nr_rlc_reestablish_entity(rrc->ue_id, lcid);
|
||||||
nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config);
|
nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config);
|
||||||
} else {
|
} else {
|
||||||
nb->active_RLC_entity[lcid] = true;
|
rrc->active_RLC_entity[lcid] = true;
|
||||||
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n");
|
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n");
|
||||||
AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
|
AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
|
||||||
"Invalid RB for RLC configuration\n");
|
"Invalid RB for RLC configuration\n");
|
||||||
@@ -733,7 +742,7 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig)
|
void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig)
|
||||||
{
|
{
|
||||||
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
|
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
|
||||||
|
|
||||||
@@ -754,12 +763,12 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
|
|||||||
rrc->rnti = reconfigurationWithSync->newUE_Identity;
|
rrc->rnti = reconfigurationWithSync->newUE_Identity;
|
||||||
// resume suspended radio bearers
|
// resume suspended radio bearers
|
||||||
for (int i = 0; i < NR_NUM_SRB; i++) {
|
for (int i = 0; i < NR_NUM_SRB; i++) {
|
||||||
if (rrcNB->Srb[i] == RB_SUSPENDED)
|
if (rrc->Srb[i] == RB_SUSPENDED)
|
||||||
rrcNB->Srb[i] = RB_ESTABLISHED;
|
rrc->Srb[i] = RB_ESTABLISHED;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
|
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
|
||||||
if (rrcNB->status_DRBs[i] == RB_SUSPENDED)
|
if (rrc->status_DRBs[i] == RB_SUSPENDED)
|
||||||
rrcNB->status_DRBs[i] = RB_ESTABLISHED;
|
rrc->status_DRBs[i] = RB_ESTABLISHED;
|
||||||
}
|
}
|
||||||
// TODO reset MAC
|
// TODO reset MAC
|
||||||
}
|
}
|
||||||
@@ -773,7 +782,7 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig, rrcNB);
|
nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig);
|
||||||
|
|
||||||
AssertFatal(cellGroupConfig->sCellToReleaseList == NULL,
|
AssertFatal(cellGroupConfig->sCellToReleaseList == NULL,
|
||||||
"Secondary serving cell release not implemented\n");
|
"Secondary serving cell release not implemented\n");
|
||||||
@@ -784,7 +793,6 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
|
|||||||
|
|
||||||
|
|
||||||
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||||
rrcPerNB_t *rrcNB,
|
|
||||||
OCTET_STRING_t *masterCellGroup,
|
OCTET_STRING_t *masterCellGroup,
|
||||||
long *fullConfig)
|
long *fullConfig)
|
||||||
{
|
{
|
||||||
@@ -800,11 +808,10 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
|||||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
|
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig);
|
||||||
|
|
||||||
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
|
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
|
||||||
nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig);
|
nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability);
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,7 +842,6 @@ static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
|
static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
|
||||||
const uint8_t gNB_index,
|
|
||||||
const NR_RRCSetup_t *rrcSetup)
|
const NR_RRCSetup_t *rrcSetup)
|
||||||
{
|
{
|
||||||
// if the RRCSetup is received in response to an RRCReestablishmentRequest
|
// if the RRCSetup is received in response to an RRCReestablishmentRequest
|
||||||
@@ -844,12 +850,10 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
|
|||||||
|
|
||||||
// perform the cell group configuration procedure in accordance with the received masterCellGroup
|
// perform the cell group configuration procedure in accordance with the received masterCellGroup
|
||||||
nr_rrc_ue_process_masterCellGroup(rrc,
|
nr_rrc_ue_process_masterCellGroup(rrc,
|
||||||
rrc->perNB + gNB_index,
|
|
||||||
&rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup,
|
&rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup,
|
||||||
NULL);
|
NULL);
|
||||||
// perform the radio bearer configuration procedure in accordance with the received radioBearerConfig
|
// perform the radio bearer configuration procedure in accordance with the received radioBearerConfig
|
||||||
nr_rrc_ue_process_RadioBearerConfig(rrc,
|
nr_rrc_ue_process_RadioBearerConfig(rrc,
|
||||||
rrc->perNB + gNB_index,
|
|
||||||
&rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
|
&rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
|
||||||
|
|
||||||
// TODO (not handled) if stored, discard the cell reselection priority information provided by
|
// TODO (not handled) if stored, discard the cell reselection priority information provided by
|
||||||
@@ -874,8 +878,7 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
|
static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
|
||||||
const NRRrcMacCcchDataInd *ind,
|
const NRRrcMacCcchDataInd *ind)
|
||||||
const uint8_t gNB_index)
|
|
||||||
{
|
{
|
||||||
NR_DL_CCCH_Message_t *dl_ccch_msg = NULL;
|
NR_DL_CCCH_Message_t *dl_ccch_msg = NULL;
|
||||||
asn_dec_rval_t dec_rval;
|
asn_dec_rval_t dec_rval;
|
||||||
@@ -908,7 +911,7 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
|
|||||||
|
|
||||||
case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
|
case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
|
||||||
LOG_I(NR_RRC, "[UE%ld][RAPROC] Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup\n", rrc->ue_id);
|
LOG_I(NR_RRC, "[UE%ld][RAPROC] Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup\n", rrc->ue_id);
|
||||||
nr_rrc_process_rrcsetup(rrc, gNB_index, dl_ccch_msg->message.choice.c1->choice.rrcSetup);
|
nr_rrc_process_rrcsetup(rrc, dl_ccch_msg->message.choice.c1->choice.rrcSetup);
|
||||||
rval = 0;
|
rval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -925,11 +928,10 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
|
static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
|
||||||
NR_SecurityModeCommand_t *const securityModeCommand,
|
NR_SecurityModeCommand_t *const securityModeCommand)
|
||||||
const uint8_t gNB_index)
|
|
||||||
{
|
{
|
||||||
int securityMode = 0;
|
int securityMode = 0;
|
||||||
LOG_I(NR_RRC, "Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", gNB_index);
|
LOG_I(NR_RRC, "Receiving from SRB1 (DL-DCCH), Processing securityModeCommand\n");
|
||||||
|
|
||||||
NR_SecurityConfigSMC_t *securityConfigSMC =
|
NR_SecurityConfigSMC_t *securityConfigSMC =
|
||||||
&securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC;
|
&securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC;
|
||||||
@@ -998,7 +1000,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
|
|||||||
uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4);
|
uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4);
|
||||||
// configure lower layers to apply SRB integrity protection and ciphering
|
// configure lower layers to apply SRB integrity protection and ciphering
|
||||||
for (int i = 1; i < NR_NUM_SRB; i++) {
|
for (int i = 1; i < NR_NUM_SRB; i++) {
|
||||||
if (ue_rrc->perNB[gNB_index].Srb[i] == RB_ESTABLISHED)
|
if (ue_rrc->Srb[i] == RB_ESTABLISHED)
|
||||||
nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, kRRCenc, kRRCint, kUPenc);
|
nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, kRRCenc, kRRCint, kUPenc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1012,8 +1014,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
|
|||||||
asn1cCalloc(modeComplete->criticalExtensions.choice.securityModeComplete, ext);
|
asn1cCalloc(modeComplete->criticalExtensions.choice.securityModeComplete, ext);
|
||||||
ext->nonCriticalExtension = NULL;
|
ext->nonCriticalExtension = NULL;
|
||||||
LOG_I(NR_RRC,
|
LOG_I(NR_RRC,
|
||||||
"Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n",
|
"Receiving from SRB1 (DL-DCCH), encoding securityModeComplete, rrc_TransactionIdentifier: %ld\n",
|
||||||
gNB_index,
|
|
||||||
securityModeCommand->rrc_TransactionIdentifier);
|
securityModeCommand->rrc_TransactionIdentifier);
|
||||||
uint8_t buffer[200];
|
uint8_t buffer[200];
|
||||||
asn_enc_rval_t enc_rval =
|
asn_enc_rval_t enc_rval =
|
||||||
@@ -1158,7 +1159,6 @@ void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
||||||
rrcPerNB_t *rrcNB,
|
|
||||||
NR_RadioBearerConfig_t *const radioBearerConfig)
|
NR_RadioBearerConfig_t *const radioBearerConfig)
|
||||||
{
|
{
|
||||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||||
@@ -1190,7 +1190,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
|||||||
if (radioBearerConfig->srb_ToAddModList != NULL) {
|
if (radioBearerConfig->srb_ToAddModList != NULL) {
|
||||||
for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
|
for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
|
||||||
struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt];
|
struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt];
|
||||||
if (rrcNB->Srb[srb->srb_Identity] == RB_NOT_PRESENT)
|
if (ue_rrc->Srb[srb->srb_Identity] == RB_NOT_PRESENT)
|
||||||
add_srb(false,
|
add_srb(false,
|
||||||
ue_rrc->ue_id,
|
ue_rrc->ue_id,
|
||||||
radioBearerConfig->srb_ToAddModList->list.array[cnt],
|
radioBearerConfig->srb_ToAddModList->list.array[cnt],
|
||||||
@@ -1204,7 +1204,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
|||||||
if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering)
|
if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering)
|
||||||
nr_pdcp_reconfigure_srb(ue_rrc->ue_id, srb->srb_Identity, *srb->pdcp_Config->t_Reordering);
|
nr_pdcp_reconfigure_srb(ue_rrc->ue_id, srb->srb_Identity, *srb->pdcp_Config->t_Reordering);
|
||||||
}
|
}
|
||||||
rrcNB->Srb[srb->srb_Identity] = RB_ESTABLISHED;
|
ue_rrc->Srb[srb->srb_Identity] = RB_ESTABLISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1221,7 +1221,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
|||||||
for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
|
for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
|
||||||
struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt];
|
struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt];
|
||||||
int DRB_id = drb->drb_Identity;
|
int DRB_id = drb->drb_Identity;
|
||||||
if (rrcNB->status_DRBs[DRB_id] == RB_ESTABLISHED) {
|
if (ue_rrc->status_DRBs[DRB_id] == RB_ESTABLISHED) {
|
||||||
AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
|
AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
|
||||||
AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n");
|
AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n");
|
||||||
NR_SDAP_Config_t *sdap_Config = drb->cnAssociation ? drb->cnAssociation->choice.sdap_Config : NULL;
|
NR_SDAP_Config_t *sdap_Config = drb->cnAssociation ? drb->cnAssociation->choice.sdap_Config : NULL;
|
||||||
@@ -1230,7 +1230,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
|
|||||||
if (drb->cnAssociation)
|
if (drb->cnAssociation)
|
||||||
AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n");
|
AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n");
|
||||||
} else {
|
} else {
|
||||||
rrcNB->status_DRBs[DRB_id] = RB_ESTABLISHED;
|
ue_rrc->status_DRBs[DRB_id] = RB_ESTABLISHED;
|
||||||
add_drb(false,
|
add_drb(false,
|
||||||
ue_rrc->ue_id,
|
ue_rrc->ue_id,
|
||||||
radioBearerConfig->drb_ToAddModList->list.array[cnt],
|
radioBearerConfig->drb_ToAddModList->list.array[cnt],
|
||||||
@@ -1348,7 +1348,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
|
|||||||
break;
|
break;
|
||||||
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
|
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
|
||||||
LOG_I(NR_RRC, "Received securityModeCommand (gNB %d)\n", gNB_indexP);
|
LOG_I(NR_RRC, "Received securityModeCommand (gNB %d)\n", gNB_indexP);
|
||||||
nr_rrc_ue_process_securityModeCommand(rrc, c1->choice.securityModeCommand, gNB_indexP);
|
nr_rrc_ue_process_securityModeCommand(rrc, c1->choice.securityModeCommand);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -1445,7 +1445,7 @@ void *rrc_nrue(void *notUsed)
|
|||||||
|
|
||||||
case NR_RRC_MAC_CCCH_DATA_IND: {
|
case NR_RRC_MAC_CCCH_DATA_IND: {
|
||||||
NRRrcMacCcchDataInd *ind = &NR_RRC_MAC_CCCH_DATA_IND(msg_p);
|
NRRrcMacCcchDataInd *ind = &NR_RRC_MAC_CCCH_DATA_IND(msg_p);
|
||||||
nr_rrc_ue_decode_ccch(rrc, ind, 0);
|
nr_rrc_ue_decode_ccch(rrc, ind);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NR_RRC_DCCH_DATA_IND:
|
case NR_RRC_DCCH_DATA_IND:
|
||||||
@@ -1477,7 +1477,7 @@ void *rrc_nrue(void *notUsed)
|
|||||||
/* Transfer data to PDCP */
|
/* Transfer data to PDCP */
|
||||||
// check if SRB2 is created, if yes request data_req on SRB2
|
// check if SRB2 is created, if yes request data_req on SRB2
|
||||||
// error: the remote gNB is hardcoded here
|
// error: the remote gNB is hardcoded here
|
||||||
rb_id_t srb_id = rrc->perNB[0].Srb[2] == RB_ESTABLISHED ? 2 : 1;
|
rb_id_t srb_id = rrc->Srb[2] == RB_ESTABLISHED ? 2 : 1;
|
||||||
nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, length, buffer, deliver_pdu_srb_rlc, NULL);
|
nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, length, buffer, deliver_pdu_srb_rlc, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1523,23 +1523,7 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
|
|||||||
info->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
|
info->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
|
||||||
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container = {.rat_Type = NR_RAT_Type_nr};
|
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container = {.rat_Type = NR_RAT_Type_nr};
|
||||||
|
|
||||||
char *file_path = rrc->uecap_file;
|
if (!rrc->UECap.UE_NR_Capability) {
|
||||||
|
|
||||||
FILE *f = NULL;
|
|
||||||
if (file_path)
|
|
||||||
f = fopen(file_path, "r");
|
|
||||||
if(f){
|
|
||||||
char UE_NR_Capability_xer[65536];
|
|
||||||
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
|
||||||
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
|
||||||
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", file_path, size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
asn_dec_rval_t dec_rval =
|
|
||||||
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
|
|
||||||
assert(dec_rval.code == RC_OK);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
|
rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
|
||||||
asn1cSequenceAdd(rrc->UECap.UE_NR_Capability->rf_Parameters.supportedBandListNR.list, NR_BandNR_t, nr_bandnr);
|
asn1cSequenceAdd(rrc->UECap.UE_NR_Capability->rf_Parameters.supportedBandListNR.list, NR_BandNR_t, nr_bandnr);
|
||||||
nr_bandnr->bandNR = 1;
|
nr_bandnr->bandNR = 1;
|
||||||
@@ -1594,41 +1578,36 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment)
|
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment)
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
{
|
{
|
||||||
uint8_t buffer[RRC_BUFFER_SIZE] = {0};
|
uint8_t buffer[RRC_BUFFER_SIZE] = {0};
|
||||||
int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE,
|
int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE,
|
||||||
rrcReestablishment->rrc_TransactionIdentifier);
|
rrcReestablishment->rrc_TransactionIdentifier);
|
||||||
LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size);
|
LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *recv_msgs_from_lte_ue(void *args_p)
|
void *recv_msgs_from_lte_ue(void *args_p)
|
||||||
{
|
{
|
||||||
itti_mark_task_ready (TASK_RRC_NSA_NRUE);
|
itti_mark_task_ready (TASK_RRC_NSA_NRUE);
|
||||||
int from_lte_ue_fd = get_from_lte_ue_fd();
|
int from_lte_ue_fd = get_from_lte_ue_fd();
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
nsa_msg_t msg;
|
||||||
nsa_msg_t msg;
|
int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg), MSG_WAITALL | MSG_TRUNC, NULL, NULL);
|
||||||
int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg),
|
if (recvLen == -1) {
|
||||||
MSG_WAITALL | MSG_TRUNC, NULL, NULL);
|
LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno));
|
||||||
if (recvLen == -1)
|
continue;
|
||||||
{
|
|
||||||
LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (recvLen > sizeof(msg))
|
|
||||||
{
|
|
||||||
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen);
|
|
||||||
}
|
}
|
||||||
return NULL;
|
if (recvLen > sizeof(msg)) {
|
||||||
|
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
|
static void nsa_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc)
|
||||||
{
|
{
|
||||||
NR_UE_NR_Capability_t *UE_Capability_nr = NR_UE_rrc_inst[0].UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
|
NR_UE_NR_Capability_t *UE_Capability_nr = rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
|
||||||
NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t));
|
NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t));
|
||||||
nr_bandnr->bandNR = 78;
|
nr_bandnr->bandNR = 78;
|
||||||
asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr);
|
asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr);
|
||||||
@@ -1650,8 +1629,8 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
|
|||||||
memset(&ue_CapabilityRAT_Container, 0, sizeof(NR_UE_CapabilityRAT_Container_t));
|
memset(&ue_CapabilityRAT_Container, 0, sizeof(NR_UE_CapabilityRAT_Container_t));
|
||||||
ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
|
ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
|
||||||
OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container,
|
OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container,
|
||||||
(const char *)NR_UE_rrc_inst[0].UECap.sdu,
|
(const char *)rrc->UECap.sdu,
|
||||||
NR_UE_rrc_inst[0].UECap.sdu_size);
|
rrc->UECap.sdu_size);
|
||||||
|
|
||||||
nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf,
|
nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf,
|
||||||
ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size,
|
ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size,
|
||||||
@@ -1660,139 +1639,127 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
|
|||||||
|
|
||||||
static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len)
|
static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len)
|
||||||
{
|
{
|
||||||
if (msg_len < sizeof(msg->msg_type))
|
if (msg_len < sizeof(msg->msg_type)) {
|
||||||
{
|
LOG_E(RRC, "Msg_len = %d\n", msg_len);
|
||||||
LOG_E(RRC, "Msg_len = %d\n", msg_len);
|
return;
|
||||||
return;
|
}
|
||||||
|
LOG_D(NR_RRC, "Processing an NSA message\n");
|
||||||
|
Rrc_Msg_Type_t msg_type = msg->msg_type;
|
||||||
|
uint8_t *const msg_buffer = msg->msg_buffer;
|
||||||
|
msg_len -= sizeof(msg->msg_type);
|
||||||
|
switch (msg_type) {
|
||||||
|
case UE_CAPABILITY_ENQUIRY: {
|
||||||
|
LOG_D(NR_RRC, "We are processing a %d message \n", msg_type);
|
||||||
|
NR_FreqBandList_t *nr_freq_band_list = NULL;
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||||
|
&asn_DEF_NR_FreqBandList,
|
||||||
|
(void **)&nr_freq_band_list,
|
||||||
|
msg_buffer,
|
||||||
|
msg_len);
|
||||||
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
|
||||||
|
LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < nr_freq_band_list->list.count; i++) {
|
||||||
|
LOG_D(NR_RRC, "Received NR band information: %ld.\n",
|
||||||
|
nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR);
|
||||||
|
}
|
||||||
|
int dummy_msg = 0;// whatever piece of data, it will never be used by sendee
|
||||||
|
LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n");
|
||||||
|
nsa_sendmsg_to_lte_ue(&dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY);
|
||||||
|
LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
LOG_D(NR_RRC, "Processing an NSA message\n");
|
|
||||||
Rrc_Msg_Type_t msg_type = msg->msg_type;
|
|
||||||
uint8_t *const msg_buffer = msg->msg_buffer;
|
|
||||||
msg_len -= sizeof(msg->msg_type);
|
|
||||||
switch (msg_type)
|
|
||||||
{
|
|
||||||
case UE_CAPABILITY_ENQUIRY:
|
|
||||||
{
|
|
||||||
LOG_D(NR_RRC, "We are processing a %d message \n", msg_type);
|
|
||||||
NR_FreqBandList_t *nr_freq_band_list = NULL;
|
|
||||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
|
||||||
&asn_DEF_NR_FreqBandList,
|
|
||||||
(void **)&nr_freq_band_list,
|
|
||||||
msg_buffer,
|
|
||||||
msg_len);
|
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
|
|
||||||
{
|
|
||||||
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
|
|
||||||
LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < nr_freq_band_list->list.count; i++)
|
|
||||||
{
|
|
||||||
LOG_D(NR_RRC, "Received NR band information: %ld.\n",
|
|
||||||
nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR);
|
|
||||||
}
|
|
||||||
int dummy_msg = 0;// whatever piece of data, it will never be used by sendee
|
|
||||||
LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n");
|
|
||||||
nsa_sendmsg_to_lte_ue(&dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY);
|
|
||||||
LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NRUE_CAPABILITY_ENQUIRY:
|
case NRUE_CAPABILITY_ENQUIRY: {
|
||||||
{
|
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
|
||||||
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
|
NR_FreqBandList_t *nr_freq_band_list = NULL;
|
||||||
NR_FreqBandList_t *nr_freq_band_list = NULL;
|
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
&asn_DEF_NR_FreqBandList,
|
||||||
&asn_DEF_NR_FreqBandList,
|
(void **)&nr_freq_band_list,
|
||||||
(void **)&nr_freq_band_list,
|
msg_buffer,
|
||||||
msg_buffer,
|
msg_len);
|
||||||
msg_len);
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
|
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
|
||||||
{
|
LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
|
||||||
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
|
break;
|
||||||
LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
|
}
|
||||||
break;
|
LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
|
||||||
}
|
nsa_rrc_ue_process_ueCapabilityEnquiry(rrc);
|
||||||
LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
|
break;
|
||||||
nsa_rrc_ue_process_ueCapabilityEnquiry();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RRC_MEASUREMENT_PROCEDURE:
|
|
||||||
{
|
|
||||||
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
|
|
||||||
|
|
||||||
LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL;
|
|
||||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
|
||||||
&asn_DEF_NR_MeasObjectToAddMod,
|
|
||||||
(void **)&nr_meas_obj,
|
|
||||||
msg_buffer,
|
|
||||||
msg_len);
|
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
|
|
||||||
{
|
|
||||||
SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING);
|
|
||||||
LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
|
|
||||||
nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15,
|
|
||||||
nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15);
|
|
||||||
start_oai_nrue_threads();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RRC_CONFIG_COMPLETE_REQ:
|
|
||||||
{
|
|
||||||
struct msg {
|
|
||||||
uint32_t RadioBearer_size;
|
|
||||||
uint32_t SecondaryCellGroup_size;
|
|
||||||
uint8_t trans_id;
|
|
||||||
uint8_t padding[3];
|
|
||||||
uint8_t buffer[];
|
|
||||||
} hdr;
|
|
||||||
AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n");
|
|
||||||
memcpy(&hdr, msg_buffer, sizeof(hdr));
|
|
||||||
LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n");
|
|
||||||
uint32_t nr_RadioBearer_size = hdr.RadioBearer_size;
|
|
||||||
uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size;
|
|
||||||
AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len,
|
|
||||||
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
|
|
||||||
nr_RadioBearer_size,
|
|
||||||
nr_SecondaryCellGroup_size,
|
|
||||||
sizeof(hdr), msg_len);
|
|
||||||
NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id;
|
|
||||||
LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
|
|
||||||
nr_RadioBearer_size,
|
|
||||||
nr_SecondaryCellGroup_size,
|
|
||||||
t_id);
|
|
||||||
|
|
||||||
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
|
|
||||||
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
|
|
||||||
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer,
|
|
||||||
nr_SecondaryCellGroup_size);
|
|
||||||
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
|
|
||||||
LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
|
|
||||||
uint8_t buffer[RRC_BUF_SIZE];
|
|
||||||
size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
|
|
||||||
nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OAI_TUN_IFACE_NSA:
|
|
||||||
{
|
|
||||||
LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n");
|
|
||||||
char cmd_line[RRC_BUF_SIZE];
|
|
||||||
memcpy(cmd_line, msg_buffer, sizeof(cmd_line));
|
|
||||||
LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
|
|
||||||
if (background_system(cmd_line) != 0)
|
|
||||||
{
|
|
||||||
LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOG_E(NR_RRC, "No NSA Message Found\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RRC_MEASUREMENT_PROCEDURE: {
|
||||||
|
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
|
||||||
|
|
||||||
|
LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL;
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||||
|
&asn_DEF_NR_MeasObjectToAddMod,
|
||||||
|
(void **)&nr_meas_obj,
|
||||||
|
msg_buffer,
|
||||||
|
msg_len);
|
||||||
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING);
|
||||||
|
LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
|
||||||
|
nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15,
|
||||||
|
nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15);
|
||||||
|
start_oai_nrue_threads();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RRC_CONFIG_COMPLETE_REQ: {
|
||||||
|
struct msg {
|
||||||
|
uint32_t RadioBearer_size;
|
||||||
|
uint32_t SecondaryCellGroup_size;
|
||||||
|
uint8_t trans_id;
|
||||||
|
uint8_t padding[3];
|
||||||
|
uint8_t buffer[];
|
||||||
|
} hdr;
|
||||||
|
AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n");
|
||||||
|
memcpy(&hdr, msg_buffer, sizeof(hdr));
|
||||||
|
LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n");
|
||||||
|
uint32_t nr_RadioBearer_size = hdr.RadioBearer_size;
|
||||||
|
uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size;
|
||||||
|
AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len,
|
||||||
|
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
|
||||||
|
nr_RadioBearer_size,
|
||||||
|
nr_SecondaryCellGroup_size,
|
||||||
|
sizeof(hdr),
|
||||||
|
msg_len);
|
||||||
|
NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id;
|
||||||
|
LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
|
||||||
|
nr_RadioBearer_size,
|
||||||
|
nr_SecondaryCellGroup_size,
|
||||||
|
t_id);
|
||||||
|
|
||||||
|
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
|
||||||
|
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
|
||||||
|
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
|
||||||
|
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
|
||||||
|
LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
|
||||||
|
uint8_t buffer[RRC_BUF_SIZE];
|
||||||
|
size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
|
||||||
|
nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OAI_TUN_IFACE_NSA: {
|
||||||
|
LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n");
|
||||||
|
char cmd_line[RRC_BUF_SIZE];
|
||||||
|
memcpy(cmd_line, msg_buffer, sizeof(cmd_line));
|
||||||
|
LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
|
||||||
|
if (background_system(cmd_line) != 0)
|
||||||
|
LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_E(NR_RRC, "No NSA Message Found\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
||||||
@@ -1860,25 +1827,22 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
|||||||
// release all radio resources, including release of the RLC entity,
|
// release all radio resources, including release of the RLC entity,
|
||||||
// the MAC configuration and the associated PDCP entity
|
// the MAC configuration and the associated PDCP entity
|
||||||
// and SDAP for all established RBs
|
// and SDAP for all established RBs
|
||||||
for (int j = 0; j < NB_CNX_UE; j++) {
|
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
|
||||||
rrcPerNB_t *nb = &rrc->perNB[j];
|
if (rrc->status_DRBs[i] != RB_NOT_PRESENT) {
|
||||||
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
|
rrc->status_DRBs[i] = RB_NOT_PRESENT;
|
||||||
if (nb->status_DRBs[i] != RB_NOT_PRESENT) {
|
nr_pdcp_release_drb(rrc->ue_id, i);
|
||||||
nb->status_DRBs[i] = RB_NOT_PRESENT;
|
|
||||||
nr_pdcp_release_drb(rrc->ue_id, i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 1; i < NR_NUM_SRB; i++) {
|
}
|
||||||
if (nb->Srb[i] != RB_NOT_PRESENT) {
|
for (int i = 1; i < NR_NUM_SRB; i++) {
|
||||||
nb->Srb[i] = RB_NOT_PRESENT;
|
if (rrc->Srb[i] != RB_NOT_PRESENT) {
|
||||||
nr_pdcp_release_srb(rrc->ue_id, i);
|
rrc->Srb[i] = RB_NOT_PRESENT;
|
||||||
}
|
nr_pdcp_release_srb(rrc->ue_id, i);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
}
|
||||||
if (nb->active_RLC_entity[i]) {
|
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
||||||
nb->active_RLC_entity[i] = false;
|
if (rrc->active_RLC_entity[i]) {
|
||||||
nr_rlc_release_entity(rrc->ue_id, i);
|
rrc->active_RLC_entity[i] = false;
|
||||||
}
|
nr_rlc_release_entity(rrc->ue_id, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1902,6 +1866,9 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
|||||||
asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SI_info->sib14);
|
asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SI_info->sib14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rrc->nrRrcState == RRC_STATE_DETACH_NR)
|
||||||
|
asn1cFreeStruc(asn_DEF_NR_UE_NR_Capability, rrc->UECap.UE_NR_Capability);
|
||||||
|
|
||||||
// reset MAC
|
// reset MAC
|
||||||
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
|
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
|
||||||
nr_rrc_mac_config_req_reset(rrc->ue_id, cause);
|
nr_rrc_mac_config_req_reset(rrc->ue_id, cause);
|
||||||
|
|||||||
@@ -178,9 +178,6 @@ typedef struct rrcPerNB {
|
|||||||
NR_QuantityConfig_t *QuantityConfig;
|
NR_QuantityConfig_t *QuantityConfig;
|
||||||
NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID];
|
NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID];
|
||||||
NR_MeasGapConfig_t *measGapConfig;
|
NR_MeasGapConfig_t *measGapConfig;
|
||||||
NR_RB_status_t Srb[NR_NUM_SRB];
|
|
||||||
NR_RB_status_t status_DRBs[MAX_DRBS_PER_UE];
|
|
||||||
bool active_RLC_entity[NR_MAX_NUM_LCID];
|
|
||||||
NR_UE_RRC_SI_INFO SInfo;
|
NR_UE_RRC_SI_INFO SInfo;
|
||||||
NR_RSRP_Range_t s_measure;
|
NR_RSRP_Range_t s_measure;
|
||||||
} rrcPerNB_t;
|
} rrcPerNB_t;
|
||||||
@@ -189,8 +186,7 @@ typedef struct NR_UE_RRC_INST_s {
|
|||||||
instance_t ue_id;
|
instance_t ue_id;
|
||||||
rrcPerNB_t perNB[NB_CNX_UE];
|
rrcPerNB_t perNB[NB_CNX_UE];
|
||||||
|
|
||||||
char *uecap_file;
|
rnti_t rnti;
|
||||||
rnti_t rnti;
|
|
||||||
|
|
||||||
OAI_NR_UECapability_t UECap;
|
OAI_NR_UECapability_t UECap;
|
||||||
NR_UE_Timers_Constants_t timers_and_constants;
|
NR_UE_Timers_Constants_t timers_and_constants;
|
||||||
@@ -200,6 +196,10 @@ typedef struct NR_UE_RRC_INST_s {
|
|||||||
NR_BWP_Id_t dl_bwp_id;
|
NR_BWP_Id_t dl_bwp_id;
|
||||||
NR_BWP_Id_t ul_bwp_id;
|
NR_BWP_Id_t ul_bwp_id;
|
||||||
|
|
||||||
|
NR_RB_status_t Srb[NR_NUM_SRB];
|
||||||
|
NR_RB_status_t status_DRBs[MAX_DRBS_PER_UE];
|
||||||
|
bool active_RLC_entity[NR_MAX_NUM_LCID];
|
||||||
|
|
||||||
/* KgNB as computed from parameters within USIM card */
|
/* KgNB as computed from parameters within USIM card */
|
||||||
uint8_t kgnb[32];
|
uint8_t kgnb[32];
|
||||||
/* Used integrity/ciphering algorithms */
|
/* Used integrity/ciphering algorithms */
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfi
|
|||||||
|
|
||||||
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
|
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
|
||||||
|
|
||||||
void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig);
|
void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig);
|
||||||
|
|
||||||
/**\brief interface between MAC and RRC thru SRB0 (RLC TM/no PDCP)
|
/**\brief interface between MAC and RRC thru SRB0 (RLC TM/no PDCP)
|
||||||
\param module_id module id
|
\param module_id module id
|
||||||
|
|||||||
Reference in New Issue
Block a user