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:
MTU: 1500
Trace: True
LogStore: /media/usb-drive/ci_qlogs
nrmodule2_quectel:
Host: nrmodule2
InitScript: sudo stdbuf -oL /home/nrmodule2/quectel-CM/quectel-CM -4 -s oai.ipv4 &> /tmp/quecel-cm.log &
TermScript: sudo -S killall --signal SIGKILL quectel-CM
AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
up2:
Host: up2
AttachScript: sudo /opt/mbim/start_quectel_mbim.sh
DetachScript: sudo /opt/mbim/stop_quectel_mbim.sh
NetworkScript: ip a show dev wwan0
IF: wwan0
MTU: 1500
LogStore: /media/ci_qlogs
adb_ue_1:
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 @@
111111
100000
010000
010010
030101
010001
000001
......@@ -39,7 +39,6 @@
070000
070001
010010
010002
030201
</TestCaseRequestedList>
......@@ -80,28 +79,16 @@
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</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">
<class>Attach_UE</class>
<desc>Attach UE</desc>
<id>nrmodule2_quectel</id>
<id>up2</id>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<id>up2</id>
<ping_args>-c 20 %cn_ip%</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
......@@ -110,8 +97,8 @@
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2 %cn_ip%</ping_args>
<id>up2</id>
<ping_args>-c 100 -s 1024 -i 0.2 %cn_ip%</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
......@@ -121,7 +108,7 @@
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 26M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<id>up2</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
......@@ -132,7 +119,7 @@
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<id>up2</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
......@@ -141,7 +128,7 @@
<testCase id="010010">
<class>Detach_UE</class>
<desc>Detach UE</desc>
<id>nrmodule2_quectel</id>
<id>up2</id>
</testCase>
<testCase id="030201">
......
......@@ -30,7 +30,7 @@
111111
100000
010000
010010
030101
010001
000001
......@@ -39,7 +39,6 @@
070000
070001
010010
010002
030201
</TestCaseRequestedList>
......@@ -80,28 +79,16 @@
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</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">
<class>Attach_UE</class>
<desc>Attach UE</desc>
<id>nrmodule2_quectel</id>
<id>up2</id>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<id>up2</id>
<ping_args>-c 20 %cn_ip%</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
......@@ -110,8 +97,8 @@
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2 %cn_ip%</ping_args>
<id>up2</id>
<ping_args>-c 100 -s 1024 -i 0.2 %cn_ip%</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
......@@ -121,7 +108,7 @@
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 1M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<id>up2</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
......@@ -132,7 +119,7 @@
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<id>up2</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
......@@ -141,7 +128,7 @@
<testCase id="010010">
<class>Detach_UE</class>
<desc>Detach UE</desc>
<id>nrmodule2_quectel</id>
<id>up2</id>
</testCase>
<testCase id="030201">
......
......@@ -65,7 +65,7 @@ $ docker logout
All the following commands **SHALL** be run from the `ci-scripts/yaml_files/5g_rfsimulator` folder for a deployment with monolithic gNB.
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 ##
......
......@@ -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;
const UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_tx_t phy_data = {0};
if (UE->if_inst)
UE->if_inst->slot_indication(UE->Mod_id);
LOG_D(PHY,
"SlotTx %d.%d => slot type %d, wait: %d \n",
proc->frame_tx,
proc->nr_slot_tx,
proc->tx_slot_type,
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)
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
......
......@@ -515,14 +515,11 @@ int main(int argc, char **argv)
uint16_t node_number = get_softmodem_params()->node_number;
ue_id_g = (node_number == 0) ? 0 : node_number - 2;
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) {
init_pdcp(0);
}
else {
init_pdcp(mode_offset + ue_id_g);
}
}
if(node_number == 0)
init_pdcp(0);
else
init_pdcp(mode_offset + ue_id_g);
init_NR_UE(NB_UE_INST, uecap_file, reconfig_file, rbconfig_file);
......
......@@ -156,7 +156,12 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
uint16_t dlDmrsSymbPos,
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
16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
......@@ -205,7 +210,7 @@ static void nr_dlsch_channel_level(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
int32_t *avg,
int32_t avg[MAX_ANT][MAX_ANT],
uint8_t symbol,
uint32_t len,
unsigned short nb_rb);
......@@ -271,7 +276,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const int nr_slot_rx = proc->nr_slot_rx;
const int gNB_id = proc->gNB_id;
int avg[16];
uint8_t slot = 0;
int32_t codeword_TB0 = -1;
......@@ -431,27 +435,28 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
if (meas_enabled)
start_meas(&meas);
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);
int avgs = 0;
int32_t median[16];
int32_t median[MAX_ANT][MAX_ANT];
for (int aatx = 0; aatx < nl; aatx++)
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]);
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);
median[(aatx * n_rx) + aarx] = avg[(aatx * n_rx) + aarx];
median[aatx][aarx] = avg[aatx][aarx];
}
if (nl > 1) {
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 aarx = 0; aarx < n_rx; aarx++) {
avgs = cmax(avgs, median[aatx*n_rx + aarx]);
if (nl > 1) {
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 aarx = 0; aarx < n_rx; aarx++) {
avgs = cmax(avgs, median[aatx][aarx]);
}
}
}
}
*log2_maxh = (log2_approx(avgs)/2) + 1;
//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);
*log2_maxh = (log2_approx(avgs) / 2) + 1;
// LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, log2_maxh);
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs);
}
if (meas_enabled) {
stop_meas(&meas);
......@@ -465,15 +470,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
meas.p_time / (cpuf * 1000.0));
}
#if T_TRACER
T(T_UE_PHY_PDSCH_ENERGY,
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]));
T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id), T_INT(0), T_INT(frame % 1024), T_INT(nr_slot_rx));
#endif
//----------------------------------------------------------
......@@ -1108,7 +1105,7 @@ void nr_dlsch_channel_level(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
int32_t *avg,
int32_t avg[MAX_ANT][MAX_ANT],
uint8_t symbol,
uint32_t len,
unsigned short nb_rb)
......@@ -1137,62 +1134,45 @@ void nr_dlsch_channel_level(uint32_t rx_size_symbol,
avg128D = simde_mm_add_epi32(avg128D,simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
dl_ch128+=3;
}
avg[(aatx*frame_parms->nb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] +
((int32_t*)&avg128D)[1] +
((int32_t*)&avg128D)[2] +
((int32_t*)&avg128D)[3])/y;
int32_t *tmp = (int32_t *)&avg128D;
avg[aatx][aarx] = ((int64_t)tmp[0] + tmp[1] + tmp[2] + tmp[3]) / y;
// 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;
int aatx,aarx;
int length2;
int max = 0, min=0;
int norm_pack;
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
for (int ii = 0; ii < length2; ii++) {
simde__m128i norm128D =
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]
int32_t *tmp = (int32_t *)&norm128D;
int64_t norm_pack = (int64_t)tmp[0] + tmp[1] + tmp[2] + tmp[3];
if (norm_pack > max)
max = norm_pack;//store values more than max
max = norm_pack;
if (norm_pack < min)
min = norm_pack;//store values less than min
min = norm_pack;
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);
}
}
}
simde_mm_empty();
simde_m_empty();
}
//==============================================================================================
......
......@@ -698,9 +698,8 @@ int main(int argc, char **argv)
validate_input_pmi(&gNB_mac->config[0], pdsch_AntennaPorts, g_nrOfLayers, g_pmi);
NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
prepare_sim_uecap(UE_Capability_nr,scc,mu,
N_RB_DL,g_mcsTableIdx,0);
NR_UE_NR_Capability_t *UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_DL, g_mcsTableIdx, 0);
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
......@@ -869,7 +868,7 @@ int main(int argc, char **argv)
//Configure UE
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_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);
......
......@@ -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->ra_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->coreset0);
}
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);
}
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_SearchSpaceId_t ss_id)
{
if (ss_id == 0)
return pdcch->search_space_zero;
return mac->search_space_zero;
NR_SearchSpace_t *css = NULL;
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
......@@ -462,12 +461,15 @@ static NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCom
return css;
}
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) {
asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
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_ConfigCommon->searchSpaceOtherSystemInformation);
......@@ -477,7 +479,7 @@ static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCo
pdcch->ra_SS = pdcch->otherSI_SS;
else
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);
......@@ -488,7 +490,7 @@ static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCo
pdcch->paging_SS = pdcch->ra_SS;
if (!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);
......@@ -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];
if (dl_common->pdcch_ConfigCommon) {
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)
release_common_ss_cset(pdcch);
}
......@@ -1905,9 +1907,64 @@ static void configure_BWPs(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd)
}
}
static void handle_mac_uecap_info(NR_UE_MAC_INST_t *mac, NR_UE_NR_Capability_t *ue_Capability)
{
if (!ue_Capability->featureSets)
return;
if (ue_Capability->featureSets->featureSetsDownlinkPerCC) {
struct NR_FeatureSets__featureSetsDownlinkPerCC *fs_dlcc_list = ue_Capability->featureSets->featureSetsDownlinkPerCC;
for (int i = 0; i < fs_dlcc_list->list.count; i++) {
NR_FeatureSetDownlinkPerCC_t *fs_dl_cc = fs_dlcc_list->list.array[i];
if (mac->current_DL_BWP->scs != fs_dl_cc->supportedSubcarrierSpacingDL)
continue;
int uecap_bw_index;
if (fs_dl_cc->supportedBandwidthDL.present == NR_SupportedBandwidth_PR_fr1) {
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr1;
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_dl_cc->channelBW_90mhz)
uecap_bw_index++;
}
else
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr2;
int dl_bw_mhz = mac->phy_config.config_req.carrier_config.dl_bandwidth;
if (dl_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
continue;
if (fs_dl_cc->maxNumberMIMO_LayersPDSCH)
mac->uecap_maxMIMO_PDSCH_layers = 2 << *fs_dl_cc->maxNumberMIMO_LayersPDSCH;
}
}
if (ue_Capability->featureSets->featureSetsUplinkPerCC) {
struct NR_FeatureSets__featureSetsUplinkPerCC *fs_ulcc_list = ue_Capability->featureSets->featureSetsUplinkPerCC;
for (int i = 0; i < fs_ulcc_list->list.count; i++) {
NR_FeatureSetUplinkPerCC_t *fs_ul_cc = fs_ulcc_list->list.array[i];
if (mac->current_UL_BWP->scs != fs_ul_cc->supportedSubcarrierSpacingUL)
continue;
int uecap_bw_index;
if (fs_ul_cc->supportedBandwidthUL.present == NR_SupportedBandwidth_PR_fr1) {
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr1;
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_ul_cc->channelBW_90mhz)
uecap_bw_index++;
}
else
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr2;
int ul_bw_mhz = mac->phy_config.config_req.carrier_config.uplink_bandwidth;
if (ul_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
continue;
if (fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH)
mac->uecap_maxMIMO_PUSCH_layers_nocb = 1 << *fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH;
if (fs_ul_cc->mimo_CB_PUSCH && fs_ul_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH)
mac->uecap_maxMIMO_PUSCH_layers_cb = 1 << *fs_ul_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH;
}
}
}
void nr_rrc_mac_config_req_cg(module_id_t module_id,
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");
AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
......@@ -1937,6 +1994,9 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
cell_group_config->rlc_BearerToAddModList,
cell_group_config->rlc_BearerToReleaseList);
if (ue_Capability)
handle_mac_uecap_info(mac, ue_Capability);
// Setup the SSB to Rach Occasions mapping according to the config
// Only if RACH is configured for current BWP
if (mac->current_UL_BWP->rach_ConfigCommon)
......
......@@ -322,10 +322,8 @@ typedef struct {
/// Msg3 buffer
uint8_t *Msg3_buffer;
/// Random-access Contention Resolution Timer active flag
uint8_t RA_contention_resolution_timer_active;
int RA_contention_resolution_target_frame;
int RA_contention_resolution_target_slot;
/// Random-access Contention Resolution Timer
NR_timer_t contention_resolution_timer;
/// Transmitted UE Contention Resolution Identifier
uint8_t cont_res_id[6];
......@@ -446,9 +444,7 @@ typedef struct {
NR_SearchSpace_t *otherSI_SS;
NR_SearchSpace_t *ra_SS;
NR_SearchSpace_t *paging_SS;
NR_ControlResourceSet_t *coreset0;
NR_ControlResourceSet_t *commonControlResourceSet;
NR_SearchSpace_t *search_space_zero;
A_SEQUENCE_OF(NR_ControlResourceSet_t) list_Coreset;
A_SEQUENCE_OF(NR_SearchSpace_t) list_SS;
} NR_BWP_PDCCH_t;
......@@ -472,12 +468,18 @@ typedef struct NR_UE_MAC_INST_s {
A_SEQUENCE_OF(NR_UE_DL_BWP_t) dl_BWPs;
A_SEQUENCE_OF(NR_UE_UL_BWP_t) ul_BWPs;
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_UL_BWP_t *current_UL_BWP;
bool harq_ACK_SpatialBundlingPUCCH;
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_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
......
......@@ -150,6 +150,7 @@
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac);
void 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
\param mac mac instance */
......@@ -179,7 +180,8 @@ void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long chan
void nr_rrc_mac_config_req_cg(module_id_t module_id,
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,
int cc_idP,
......
......@@ -66,6 +66,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
mac->servCellIndex = 0;
mac->harq_ACK_SpatialBundlingPUCCH = 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->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
......@@ -220,6 +223,9 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac)
for (int i = 0; i < mac->ul_BWPs.count; i++)
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++) {
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
asn_sequence_del(&mac->lc_ordered_list, i, 0);
......
......@@ -592,22 +592,14 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
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)
int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1)<<3;
// start contention resolution timer
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;
}
......@@ -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);
}
}
......@@ -826,16 +818,12 @@ void nr_ue_contention_resolution(NR_UE_MAC_INST_t *mac, int cc_id, frame_t frame
{
RA_config_t *ra = &mac->ra;
if (ra->RA_contention_resolution_timer_active == 1) {
if (frame >= ra->RA_contention_resolution_target_frame &&
slot >= ra->RA_contention_resolution_target_slot) {
ra->t_crnti = 0;
ra->RA_active = 0;
ra->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
}
if (nr_timer_expired(ra->contention_resolution_timer)) {
ra->t_crnti = 0;
nr_timer_stop(&ra->contention_resolution_timer);
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
}
}
......@@ -852,7 +840,7 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
ra->RA_window_cnt = -1;
} else {
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;
ra->t_crnti = 0;
LOG_D(MAC, "[UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
......
......@@ -121,7 +121,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
coreset = ue_get_coreset(pdcch_config, coreset_id);
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
} else {
coreset = pdcch_config->coreset0;
coreset = mac->coreset0;
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
}
......@@ -483,22 +483,22 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
mac->mib_ssb,
1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame
ssb_offset_point_a);
if (pdcch_config->search_space_zero == NULL)
pdcch_config->search_space_zero = calloc(1, sizeof(*pdcch_config->search_space_zero));
if (pdcch_config->coreset0 == NULL)
pdcch_config->coreset0 = calloc(1, sizeof(*pdcch_config->coreset0));
fill_coresetZero(pdcch_config->coreset0, &mac->type0_PDCCH_CSS_config);
fill_searchSpaceZero(pdcch_config->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 (mac->search_space_zero == NULL)
mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero));
if (mac->coreset0 == NULL)
mac->coreset0 = calloc(1, sizeof(*mac->coreset0));
fill_coresetZero(mac->coreset0, &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, mac->search_space_zero)) {
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 searchSpaceOtherSystemInformation is set to zero,
// PDCCH monitoring occasions for SI message reception in SI-window
// 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
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);
......
......@@ -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
AssertFatal(sc_info->maxMIMO_Layers_PDSCH != NULL, "Option with max MIMO layers not configured is not supported\n");
int nl_tbslbrm = *sc_info->maxMIMO_Layers_PDSCH < 4 ? *sc_info->maxMIMO_Layers_PDSCH : 4;
int max_mimo_layers = 0;
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);
/*PTRS configuration */
dlsch_pdu->pduBitmap = 0;
......
......@@ -90,6 +90,11 @@ fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_
return pdu;
}
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)
{
pdu->privateNBpdus--;
......@@ -698,16 +703,28 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
N_PRB_oh = 0;
if (sc_info->rateMatching_PUSCH) {
long *maxMIMO_Layers = sc_info->maxMIMO_Layers_PUSCH;
if (!maxMIMO_Layers)
maxMIMO_Layers = pusch_Config ? pusch_Config->maxRank : NULL;
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n");
pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, sc_info->ul_bw_tbslbrm, *maxMIMO_Layers);
long maxMIMO_Layers = 0;
if (sc_info->maxMIMO_Layers_PUSCH)
maxMIMO_Layers = *sc_info->maxMIMO_Layers_PUSCH;
else if (pusch_Config && pusch_Config->maxRank)
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
pusch_config_pdu->tbslbrm = 0;
/* 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) {
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
......@@ -724,7 +741,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
if(valid_ptrs_setup == true) {
pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
}
LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n",
pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
}
}
}
......
......@@ -1278,6 +1278,14 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info)
return ret2;
}
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)
{
if (nr_ue_if_module_inst[module_id] == NULL) {
......@@ -1295,6 +1303,7 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id)
nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response;
nr_ue_if_module_inst[module_id]->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]->slot_indication = nr_ue_slot_indication;
}
pthread_mutex_init(&mac_IF_mutex, NULL);
......
......@@ -245,6 +245,7 @@ typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info);
*/
typedef int (nr_ue_ul_indication_f)(nr_uplink_indication_t *ul_info);
typedef void (nr_ue_slot_indication_f)(uint8_t mod_id);
/*
* Generic type of an application-defined callback to return various
......@@ -263,6 +264,7 @@ typedef struct nr_ue_if_module_s {
nr_ue_dl_indication_f *dl_indication;
nr_ue_ul_indication_f *ul_indication;
nr_ue_sl_indication_f *sl_indication;
nr_ue_slot_indication_f *slot_indication;
uint32_t cc_mask;
uint32_t current_frame;
uint32_t current_slot;
......
......@@ -133,12 +133,10 @@ static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = {
0x11,
};
static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
const NR_CellGroupConfig_t *cellGroupConfig,
rrcPerNB_t *nb);
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
const NR_CellGroupConfig_t *cellGroupConfig);
static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
rrcPerNB_t *rrcNB,
NR_RadioBearerConfig_t *const radioBearerConfig);
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);
......@@ -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_masterCellGroup(NR_UE_RRC_INST_t *rrc,
rrcPerNB_t *rrcNB,
OCTET_STRING_t *masterCellGroup,
long *fullConfig);
......@@ -166,7 +163,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if (ie->radioBearerConfig != NULL) {
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))
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ie->radioBearerConfig);
}
......@@ -174,7 +171,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if (ie->nonCriticalExtension) {
NR_RRCReconfiguration_v1530_IEs_t *ext = ie->nonCriticalExtension;
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 */
if (ie->nonCriticalExtension->dedicatedNAS_MessageList) {
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList;
......@@ -212,11 +209,10 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if (LOG_DEBUGFLAG(DEBUG_ASN1))
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");
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);
}
if (ie->measConfig != NULL) {
......@@ -240,52 +236,48 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
{
switch (nsa_message_type) {
case nr_SecondaryCellGroupConfig_r15:
{
NR_RRCReconfiguration_t *RRCReconfiguration=NULL;
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_RRCReconfiguration,
(void **)&RRCReconfiguration,
(uint8_t *)message,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
return;
}
nr_rrc_ue_process_rrcReconfiguration(rrc, 0, RRCReconfiguration);
ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration);
case nr_SecondaryCellGroupConfig_r15: {
NR_RRCReconfiguration_t *RRCReconfiguration=NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_RRCReconfiguration,
(void **)&RRCReconfiguration,
(uint8_t *)message,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
return;
}
break;
nr_rrc_ue_process_rrcReconfiguration(rrc, 0, RRCReconfiguration);
ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration);
}
break;
case nr_RadioBearerConfigX_r15:
{
NR_RadioBearerConfig_t *RadioBearerConfig=NULL;
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_RadioBearerConfig,
(void **)&RadioBearerConfig,
(uint8_t *)message,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
return;
}
LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig()with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n",
RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity,
RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm,
*RadioBearerConfig->securityConfig->keyToUse);
nr_rrc_ue_process_RadioBearerConfig(rrc, rrc->perNB + 0, RadioBearerConfig);
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig);
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
case nr_RadioBearerConfigX_r15: {
NR_RadioBearerConfig_t *RadioBearerConfig=NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_RadioBearerConfig,
(void **)&RadioBearerConfig,
(uint8_t *)message,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
return;
}
break;
LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig()with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n",
RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity,
RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm,
*RadioBearerConfig->securityConfig->keyToUse);
nr_rrc_ue_process_RadioBearerConfig(rrc, RadioBearerConfig);
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig);
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
}
break;
default:
AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
......@@ -308,21 +300,39 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
rrc->ul_bwp_id = 0;
rrc->as_security_activated = false;
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));
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++) {
rrcPerNB_t *ptr = &rrc->perNB[i];
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
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);
......@@ -696,9 +706,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
return 0;
}
static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
const NR_CellGroupConfig_t *cellGroupConfig,
rrcPerNB_t *nb)
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
const NR_CellGroupConfig_t *cellGroupConfig)
{
if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
......@@ -712,12 +721,12 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
if (nb->active_RLC_entity[lcid]) {
if (rrc->active_RLC_entity[lcid]) {
if (rlc_bearer->reestablishRLC)
nr_rlc_reestablish_entity(rrc->ue_id, lcid);
nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config);
} 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->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
"Invalid RB for RLC configuration\n");
......@@ -733,7 +742,7 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
}
}
void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig)
void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig)
{
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
......@@ -754,12 +763,12 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
rrc->rnti = reconfigurationWithSync->newUE_Identity;
// resume suspended radio bearers
for (int i = 0; i < NR_NUM_SRB; i++) {
if (rrcNB->Srb[i] == RB_SUSPENDED)
rrcNB->Srb[i] = RB_ESTABLISHED;
if (rrc->Srb[i] == RB_SUSPENDED)
rrc->Srb[i] = RB_ESTABLISHED;
}
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (rrcNB->status_DRBs[i] == RB_SUSPENDED)
rrcNB->status_DRBs[i] = RB_ESTABLISHED;
if (rrc->status_DRBs[i] == RB_SUSPENDED)
rrc->status_DRBs[i] = RB_ESTABLISHED;
}
// TODO reset MAC
}
......@@ -773,7 +782,7 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
}
}
nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig, rrcNB);
nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig);
AssertFatal(cellGroupConfig->sCellToReleaseList == NULL,
"Secondary serving cell release not implemented\n");
......@@ -784,7 +793,6 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
rrcPerNB_t *rrcNB,
OCTET_STRING_t *masterCellGroup,
long *fullConfig)
{
......@@ -800,11 +808,10 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
}
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig);
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);
}
......@@ -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,
const uint8_t gNB_index,
const NR_RRCSetup_t *rrcSetup)
{
// if the RRCSetup is received in response to an RRCReestablishmentRequest
......@@ -844,12 +850,10 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
// perform the cell group configuration procedure in accordance with the received masterCellGroup
nr_rrc_ue_process_masterCellGroup(rrc,
rrc->perNB + gNB_index,
&rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup,
NULL);
// perform the radio bearer configuration procedure in accordance with the received radioBearerConfig
nr_rrc_ue_process_RadioBearerConfig(rrc,
rrc->perNB + gNB_index,
&rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
// TODO (not handled) if stored, discard the cell reselection priority information provided by
......@@ -874,8 +878,7 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
}
static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
const NRRrcMacCcchDataInd *ind,
const uint8_t gNB_index)
const NRRrcMacCcchDataInd *ind)
{
NR_DL_CCCH_Message_t *dl_ccch_msg = NULL;
asn_dec_rval_t dec_rval;
......@@ -908,7 +911,7 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
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;
break;
......@@ -925,11 +928,10 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
}
static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
NR_SecurityModeCommand_t *const securityModeCommand,
const uint8_t gNB_index)
NR_SecurityModeCommand_t *const securityModeCommand)
{
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 =
&securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC;
......@@ -998,7 +1000,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4);
// configure lower layers to apply SRB integrity protection and ciphering
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);
}
} else {
......@@ -1012,8 +1014,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
asn1cCalloc(modeComplete->criticalExtensions.choice.securityModeComplete, ext);
ext->nonCriticalExtension = NULL;
LOG_I(NR_RRC,
"Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n",
gNB_index,
"Receiving from SRB1 (DL-DCCH), encoding securityModeComplete, rrc_TransactionIdentifier: %ld\n",
securityModeCommand->rrc_TransactionIdentifier);
uint8_t buffer[200];
asn_enc_rval_t enc_rval =
......@@ -1158,7 +1159,6 @@ void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measCo
}
static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
rrcPerNB_t *rrcNB,
NR_RadioBearerConfig_t *const radioBearerConfig)
{
if (LOG_DEBUGFLAG(DEBUG_ASN1))
......@@ -1190,7 +1190,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (radioBearerConfig->srb_ToAddModList != NULL) {
for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; 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,
ue_rrc->ue_id,
radioBearerConfig->srb_ToAddModList->list.array[cnt],
......@@ -1204,7 +1204,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering)
nr_pdcp_reconfigure_srb(ue_rrc->ue_id, srb->srb_Identity, *srb->pdcp_Config->t_Reordering);
}
rrcNB->Srb[srb->srb_Identity] = RB_ESTABLISHED;
ue_rrc->Srb[srb->srb_Identity] = RB_ESTABLISHED;
}
}
......@@ -1221,7 +1221,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt];
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->recoverPDCP == NULL, "recoverPDCP not yet implemented\n");
NR_SDAP_Config_t *sdap_Config = drb->cnAssociation ? drb->cnAssociation->choice.sdap_Config : NULL;
......@@ -1230,7 +1230,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (drb->cnAssociation)
AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n");
} else {
rrcNB->status_DRBs[DRB_id] = RB_ESTABLISHED;
ue_rrc->status_DRBs[DRB_id] = RB_ESTABLISHED;
add_drb(false,
ue_rrc->ue_id,
radioBearerConfig->drb_ToAddModList->list.array[cnt],
......@@ -1348,7 +1348,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
break;
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
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;
......@@ -1445,7 +1445,7 @@ void *rrc_nrue(void *notUsed)
case NR_RRC_MAC_CCCH_DATA_IND: {
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;
case NR_RRC_DCCH_DATA_IND:
......@@ -1477,7 +1477,7 @@ void *rrc_nrue(void *notUsed)
/* Transfer data to PDCP */
// check if SRB2 is created, if yes request data_req on SRB2
// 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);
break;
}
......@@ -1523,23 +1523,7 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
info->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container = {.rat_Type = NR_RAT_Type_nr};
char *file_path = rrc->uecap_file;
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 {
if (!rrc->UECap.UE_NR_Capability) {
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);
nr_bandnr->bandNR = 1;
......@@ -1594,41 +1578,36 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
}
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment)
//-----------------------------------------------------------------------------
{
uint8_t buffer[RRC_BUFFER_SIZE] = {0};
int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE,
uint8_t buffer[RRC_BUFFER_SIZE] = {0};
int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE,
rrcReestablishment->rrc_TransactionIdentifier);
LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size);
LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size);
}
void *recv_msgs_from_lte_ue(void *args_p)
{
itti_mark_task_ready (TASK_RRC_NSA_NRUE);
int from_lte_ue_fd = get_from_lte_ue_fd();
for (;;)
{
nsa_msg_t msg;
int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg),
MSG_WAITALL | MSG_TRUNC, NULL, NULL);
if (recvLen == -1)
{
LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno));
continue;
}
if (recvLen > sizeof(msg))
{
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
continue;
}
process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen);
itti_mark_task_ready (TASK_RRC_NSA_NRUE);
int from_lte_ue_fd = get_from_lte_ue_fd();
for (;;) {
nsa_msg_t msg;
int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg), MSG_WAITALL | MSG_TRUNC, NULL, NULL);
if (recvLen == -1) {
LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno));
continue;
}
if (recvLen > sizeof(msg)) {
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
continue;
}
return NULL;
process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen);
}
return NULL;
}
static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
static void nsa_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc)
{
NR_UE_NR_Capability_t *UE_Capability_nr = NR_UE_rrc_inst[0].UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
NR_UE_NR_Capability_t *UE_Capability_nr = rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t));
nr_bandnr->bandNR = 78;
asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr);
......@@ -1650,8 +1629,8 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
memset(&ue_CapabilityRAT_Container, 0, sizeof(NR_UE_CapabilityRAT_Container_t));
ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container,
(const char *)NR_UE_rrc_inst[0].UECap.sdu,
NR_UE_rrc_inst[0].UECap.sdu_size);
(const char *)rrc->UECap.sdu,
rrc->UECap.sdu_size);
nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf,
ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size,
......@@ -1660,139 +1639,127 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len)
{
if (msg_len < sizeof(msg->msg_type))
{
LOG_E(RRC, "Msg_len = %d\n", msg_len);
return;
if (msg_len < sizeof(msg->msg_type)) {
LOG_E(RRC, "Msg_len = %d\n", msg_len);
return;
}
LOG_D(NR_RRC, "Processing an NSA message\n");
Rrc_Msg_Type_t msg_type = msg->msg_type;
uint8_t *const msg_buffer = msg->msg_buffer;
msg_len -= sizeof(msg->msg_type);
switch (msg_type) {
case UE_CAPABILITY_ENQUIRY: {
LOG_D(NR_RRC, "We are processing a %d message \n", msg_type);
NR_FreqBandList_t *nr_freq_band_list = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_FreqBandList,
(void **)&nr_freq_band_list,
msg_buffer,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
break;
}
for (int i = 0; i < nr_freq_band_list->list.count; i++) {
LOG_D(NR_RRC, "Received NR band information: %ld.\n",
nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR);
}
int dummy_msg = 0;// whatever piece of data, it will never be used by sendee
LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n");
nsa_sendmsg_to_lte_ue(&dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY);
LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n");
break;
}
LOG_D(NR_RRC, "Processing an NSA message\n");
Rrc_Msg_Type_t msg_type = msg->msg_type;
uint8_t *const msg_buffer = msg->msg_buffer;
msg_len -= sizeof(msg->msg_type);
switch (msg_type)
{
case UE_CAPABILITY_ENQUIRY:
{
LOG_D(NR_RRC, "We are processing a %d message \n", msg_type);
NR_FreqBandList_t *nr_freq_band_list = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_FreqBandList,
(void **)&nr_freq_band_list,
msg_buffer,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
{
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
break;
}
for (int i = 0; i < nr_freq_band_list->list.count; i++)
{
LOG_D(NR_RRC, "Received NR band information: %ld.\n",
nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR);
}
int dummy_msg = 0;// whatever piece of data, it will never be used by sendee
LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n");
nsa_sendmsg_to_lte_ue(&dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY);
LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n");
break;
}
case NRUE_CAPABILITY_ENQUIRY:
{
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
NR_FreqBandList_t *nr_freq_band_list = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_FreqBandList,
(void **)&nr_freq_band_list,
msg_buffer,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
{
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
break;
}
LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
nsa_rrc_ue_process_ueCapabilityEnquiry();
break;
}
case NRUE_CAPABILITY_ENQUIRY: {
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
NR_FreqBandList_t *nr_freq_band_list = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_FreqBandList,
(void **)&nr_freq_band_list,
msg_buffer,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
break;
}
LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
nsa_rrc_ue_process_ueCapabilityEnquiry(rrc);
break;
}
case RRC_MEASUREMENT_PROCEDURE:
{
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_MeasObjectToAddMod,
(void **)&nr_meas_obj,
msg_buffer,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
{
SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING);
LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
break;
}
LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15,
nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15);
start_oai_nrue_threads();
break;
}
case RRC_CONFIG_COMPLETE_REQ:
{
struct msg {
uint32_t RadioBearer_size;
uint32_t SecondaryCellGroup_size;
uint8_t trans_id;
uint8_t padding[3];
uint8_t buffer[];
} hdr;
AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n");
memcpy(&hdr, msg_buffer, sizeof(hdr));
LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n");
uint32_t nr_RadioBearer_size = hdr.RadioBearer_size;
uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size;
AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len,
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
nr_RadioBearer_size,
nr_SecondaryCellGroup_size,
sizeof(hdr), msg_len);
NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id;
LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
nr_RadioBearer_size,
nr_SecondaryCellGroup_size,
t_id);
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer,
nr_SecondaryCellGroup_size);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
uint8_t buffer[RRC_BUF_SIZE];
size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ);
break;
}
case RRC_MEASUREMENT_PROCEDURE: {
LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_MeasObjectToAddMod,
(void **)&nr_meas_obj,
msg_buffer,
msg_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING);
LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
break;
}
LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15,
nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15);
start_oai_nrue_threads();
break;
}
case OAI_TUN_IFACE_NSA:
{
LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n");
char cmd_line[RRC_BUF_SIZE];
memcpy(cmd_line, msg_buffer, sizeof(cmd_line));
LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
if (background_system(cmd_line) != 0)
{
LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
}
break;
}
case RRC_CONFIG_COMPLETE_REQ: {
struct msg {
uint32_t RadioBearer_size;
uint32_t SecondaryCellGroup_size;
uint8_t trans_id;
uint8_t padding[3];
uint8_t buffer[];
} hdr;
AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n");
memcpy(&hdr, msg_buffer, sizeof(hdr));
LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n");
uint32_t nr_RadioBearer_size = hdr.RadioBearer_size;
uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size;
AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len,
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
nr_RadioBearer_size,
nr_SecondaryCellGroup_size,
sizeof(hdr),
msg_len);
NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id;
LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
nr_RadioBearer_size,
nr_SecondaryCellGroup_size,
t_id);
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
uint8_t buffer[RRC_BUF_SIZE];
size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ);
break;
}
default:
LOG_E(NR_RRC, "No NSA Message Found\n");
case OAI_TUN_IFACE_NSA: {
LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n");
char cmd_line[RRC_BUF_SIZE];
memcpy(cmd_line, msg_buffer, sizeof(cmd_line));
LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
if (background_system(cmd_line) != 0)
LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
break;
}
default:
LOG_E(NR_RRC, "No NSA Message Found\n");
}
}
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
......@@ -1860,25 +1827,22 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
// release all radio resources, including release of the RLC entity,
// the MAC configuration and the associated PDCP entity
// 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++) {
if (nb->status_DRBs[i] != RB_NOT_PRESENT) {
nb->status_DRBs[i] = RB_NOT_PRESENT;
nr_pdcp_release_drb(rrc->ue_id, i);
}
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (rrc->status_DRBs[i] != RB_NOT_PRESENT) {
rrc->status_DRBs[i] = RB_NOT_PRESENT;
nr_pdcp_release_drb(rrc->ue_id, i);
}
for (int i = 1; i < NR_NUM_SRB; i++) {
if (nb->Srb[i] != RB_NOT_PRESENT) {
nb->Srb[i] = RB_NOT_PRESENT;
nr_pdcp_release_srb(rrc->ue_id, i);
}
}
for (int i = 1; i < NR_NUM_SRB; i++) {
if (rrc->Srb[i] != RB_NOT_PRESENT) {
rrc->Srb[i] = RB_NOT_PRESENT;
nr_pdcp_release_srb(rrc->ue_id, i);
}
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
if (nb->active_RLC_entity[i]) {
nb->active_RLC_entity[i] = false;
nr_rlc_release_entity(rrc->ue_id, i);
}
}
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
if (rrc->active_RLC_entity[i]) {
rrc->active_RLC_entity[i] = false;
nr_rlc_release_entity(rrc->ue_id, i);
}
}
......@@ -1902,6 +1866,9 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SI_info->sib14);
}
if (rrc->nrRrcState == RRC_STATE_DETACH_NR)
asn1cFreeStruc(asn_DEF_NR_UE_NR_Capability, rrc->UECap.UE_NR_Capability);
// reset MAC
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);
......
......@@ -178,9 +178,6 @@ typedef struct rrcPerNB {
NR_QuantityConfig_t *QuantityConfig;
NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID];
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_RSRP_Range_t s_measure;
} rrcPerNB_t;
......@@ -189,8 +186,7 @@ typedef struct NR_UE_RRC_INST_s {
instance_t ue_id;
rrcPerNB_t perNB[NB_CNX_UE];
char *uecap_file;
rnti_t rnti;
rnti_t rnti;
OAI_NR_UECapability_t UECap;
NR_UE_Timers_Constants_t timers_and_constants;
......@@ -200,6 +196,10 @@ typedef struct NR_UE_RRC_INST_s {
NR_BWP_Id_t dl_bwp_id;
NR_BWP_Id_t 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 */
uint8_t kgnb[32];
/* Used integrity/ciphering algorithms */
......
......@@ -58,7 +58,7 @@ void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfi
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
void 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)
\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