Commit 08051056 authored by Robert Schmidt's avatar Robert Schmidt

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
parents c599e172 2f313c9a
...@@ -9,16 +9,14 @@ idefix: ...@@ -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
......
#!/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."
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
set -x
sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
111111 111111
100000 100000
010000 010010
030101 030101
010001 010001
000001 000001
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
070000 070000
070001 070001
010010 010010
010002
030201 030201
</TestCaseRequestedList> </TestCaseRequestedList>
...@@ -80,28 +79,16 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -30,7 +30,7 @@
111111 111111
100000 100000
010000 010010
030101 030101
010001 010001
000001 000001
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
070000 070000
070001 070001
010010 010010
010002
030201 030201
</TestCaseRequestedList> </TestCaseRequestedList>
...@@ -80,28 +79,16 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 ...@@ -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 ##
......
...@@ -533,20 +533,23 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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,%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avg[0], avgs); LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, 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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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, ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 @@ ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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,17 +818,13 @@ void nr_ue_contention_resolution(NR_UE_MAC_INST_t *mac, int cc_id, frame_t frame ...@@ -826,17 +818,13 @@ 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 &&
slot >= ra->RA_contention_resolution_target_slot) {
ra->t_crnti = 0; ra->t_crnti = 0;
ra->RA_active = 0; nr_timer_stop(&ra->contention_resolution_timer);
ra->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure // 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); 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); nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
} }
}
} }
// Handlig successful RA completion @ MAC layer // Handlig successful RA completion @ MAC layer
...@@ -852,7 +840,7 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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_ ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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 { ...@@ -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;
......
...@@ -133,12 +133,10 @@ static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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,15 +236,13 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, ...@@ -240,15 +236,13 @@ 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)) { if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n"); LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
// free the memory // free the memory
...@@ -260,15 +254,13 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, ...@@ -260,15 +254,13 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
} }
break; 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)) { if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n"); LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
// free the memory // free the memory
...@@ -280,7 +272,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, ...@@ -280,7 +272,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity, RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm, RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm,
*RadioBearerConfig->securityConfig->keyToUse); *RadioBearerConfig->securityConfig->keyToUse);
nr_rrc_ue_process_RadioBearerConfig(rrc, rrc->perNB + 0, RadioBearerConfig); nr_rrc_ue_process_RadioBearerConfig(rrc, RadioBearerConfig);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig); xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig);
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig); ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
...@@ -308,21 +300,39 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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,7 +1578,6 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa ...@@ -1594,7 +1578,6 @@ 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,
...@@ -1606,18 +1589,14 @@ void *recv_msgs_from_lte_ue(void *args_p) ...@@ -1606,18 +1589,14 @@ 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), int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg), MSG_WAITALL | MSG_TRUNC, NULL, NULL);
MSG_WAITALL | MSG_TRUNC, NULL, NULL); if (recvLen == -1) {
if (recvLen == -1)
{
LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno)); LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno));
continue; continue;
} }
if (recvLen > sizeof(msg)) if (recvLen > sizeof(msg)) {
{
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen); LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
continue; continue;
} }
...@@ -1626,9 +1605,9 @@ void *recv_msgs_from_lte_ue(void *args_p) ...@@ -1626,9 +1605,9 @@ void *recv_msgs_from_lte_ue(void *args_p)
return NULL; 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) ...@@ -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,8 +1639,7 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void) ...@@ -1660,8 +1639,7 @@ 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;
} }
...@@ -1669,10 +1647,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1669,10 +1647,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
Rrc_Msg_Type_t msg_type = msg->msg_type; Rrc_Msg_Type_t msg_type = msg->msg_type;
uint8_t *const msg_buffer = msg->msg_buffer; uint8_t *const msg_buffer = msg->msg_buffer;
msg_len -= sizeof(msg->msg_type); msg_len -= sizeof(msg->msg_type);
switch (msg_type) switch (msg_type) {
{ case UE_CAPABILITY_ENQUIRY: {
case UE_CAPABILITY_ENQUIRY:
{
LOG_D(NR_RRC, "We are processing a %d message \n", msg_type); LOG_D(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,
...@@ -1680,14 +1656,12 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1680,14 +1656,12 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
(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); 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); LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
break; break;
} }
for (int i = 0; i < nr_freq_band_list->list.count; i++) for (int i = 0; i < nr_freq_band_list->list.count; i++) {
{
LOG_D(NR_RRC, "Received NR band information: %ld.\n", LOG_D(NR_RRC, "Received NR band information: %ld.\n",
nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR); nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR);
} }
...@@ -1698,8 +1672,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1698,8 +1672,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
break; 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,
...@@ -1707,19 +1680,17 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1707,19 +1680,17 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
(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); 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); LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
break; break;
} }
LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n"); LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
nsa_rrc_ue_process_ueCapabilityEnquiry(); nsa_rrc_ue_process_ueCapabilityEnquiry(rrc);
break; break;
} }
case RRC_MEASUREMENT_PROCEDURE: case RRC_MEASUREMENT_PROCEDURE: {
{
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);
LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL; LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL;
...@@ -1728,8 +1699,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1728,8 +1699,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
(void **)&nr_meas_obj, (void **)&nr_meas_obj,
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_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING); 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); LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
break; break;
...@@ -1740,8 +1710,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1740,8 +1710,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
start_oai_nrue_threads(); start_oai_nrue_threads();
break; break;
} }
case RRC_CONFIG_COMPLETE_REQ:
{ case RRC_CONFIG_COMPLETE_REQ: {
struct msg { struct msg {
uint32_t RadioBearer_size; uint32_t RadioBearer_size;
uint32_t SecondaryCellGroup_size; uint32_t SecondaryCellGroup_size;
...@@ -1758,7 +1728,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1758,7 +1728,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n", "nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
nr_RadioBearer_size, nr_RadioBearer_size,
nr_SecondaryCellGroup_size, nr_SecondaryCellGroup_size,
sizeof(hdr), msg_len); sizeof(hdr),
msg_len);
NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id; 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", LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
nr_RadioBearer_size, nr_RadioBearer_size,
...@@ -1767,8 +1738,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1767,8 +1738,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer); uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size; uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
nr_SecondaryCellGroup_size);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_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); LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
uint8_t buffer[RRC_BUF_SIZE]; uint8_t buffer[RRC_BUF_SIZE];
...@@ -1777,16 +1747,13 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l ...@@ -1777,16 +1747,13 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
break; break;
} }
case OAI_TUN_IFACE_NSA: case OAI_TUN_IFACE_NSA: {
{
LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n"); LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n");
char cmd_line[RRC_BUF_SIZE]; char cmd_line[RRC_BUF_SIZE];
memcpy(cmd_line, msg_buffer, sizeof(cmd_line)); memcpy(cmd_line, msg_buffer, sizeof(cmd_line));
LOG_D(NR_RRC, "Command line: %s\n", cmd_line); LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
if (background_system(cmd_line) != 0) if (background_system(cmd_line) != 0)
{
LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line); LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
}
break; break;
} }
...@@ -1860,27 +1827,24 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, ...@@ -1860,27 +1827,24 @@ 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++) {
rrcPerNB_t *nb = &rrc->perNB[j];
for (int i = 0; i < MAX_DRBS_PER_UE; i++) { for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (nb->status_DRBs[i] != RB_NOT_PRESENT) { if (rrc->status_DRBs[i] != RB_NOT_PRESENT) {
nb->status_DRBs[i] = RB_NOT_PRESENT; rrc->status_DRBs[i] = RB_NOT_PRESENT;
nr_pdcp_release_drb(rrc->ue_id, i); nr_pdcp_release_drb(rrc->ue_id, i);
} }
} }
for (int i = 1; i < NR_NUM_SRB; i++) { for (int i = 1; i < NR_NUM_SRB; i++) {
if (nb->Srb[i] != RB_NOT_PRESENT) { if (rrc->Srb[i] != RB_NOT_PRESENT) {
nb->Srb[i] = RB_NOT_PRESENT; rrc->Srb[i] = RB_NOT_PRESENT;
nr_pdcp_release_srb(rrc->ue_id, i); nr_pdcp_release_srb(rrc->ue_id, i);
} }
} }
for (int i = 0; i < NR_MAX_NUM_LCID; i++) { for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
if (nb->active_RLC_entity[i]) { if (rrc->active_RLC_entity[i]) {
nb->active_RLC_entity[i] = false; rrc->active_RLC_entity[i] = false;
nr_rlc_release_entity(rrc->ue_id, i); nr_rlc_release_entity(rrc->ue_id, i);
} }
} }
}
for (int i = 0; i < NB_CNX_UE; i++) { for (int i = 0; i < NB_CNX_UE; i++) {
rrcPerNB_t *nb = &rrc->perNB[i]; rrcPerNB_t *nb = &rrc->perNB[i];
...@@ -1902,6 +1866,9 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, ...@@ -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 { ...@@ -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,7 +186,6 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -189,7 +186,6 @@ 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;
...@@ -200,6 +196,10 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -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 ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment