diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index f5aabf9167..deef3718ec 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -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 diff --git a/ci-scripts/mbim_scripts/mbim-set-ip.sh b/ci-scripts/mbim_scripts/mbim-set-ip.sh new file mode 100644 index 0000000000..572301540a --- /dev/null +++ b/ci-scripts/mbim_scripts/mbim-set-ip.sh @@ -0,0 +1,221 @@ +#!/bin/bash + +# Modified by Karim Boutiba (karim.boutiba@eurecom.fr) +# mbim-set-ip script version 1.1 +# Modified mbimcli IPv4 IPv6 parsing script based on parts of project https://github.com/grandcentrix/thinkpad-x260-modem-scripts +# Licensed under the Apache License, Version 2.0 +# Modified by Jörgen Storvist, Techship http://www.techship.com +# Further details in the Techship FAQ sections on using MBIM and setting correct modes in cellular modules: +# https://techship.com/faq/how-to-set-up-a-simple-data-connection-over-the-mbim-interface-using-libmbim-and-driver-cdc-mbim-in-linux/ +# +# Installation & Usage: +# +# Verify that the cellular module is exposing the MBIM interface over the USB interface. +# Use mbimcli to check status for the cellular connection and enter the PIN code if necessary. +# Configure mbim-network.conf and place in /etc/ (example file included in the archive, check link bellow for details). +# https://www.freedesktop.org/software/libmbim/man/latest/mbim-network.1.html +# Start the mbim data connection with command: +# mbim-network start +# Ensure execution of mbim-set-ip script with sufficient system priviledges +# ./mbim-set-ip +# +# 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." diff --git a/ci-scripts/mbim_scripts/start_quectel_mbim.sh b/ci-scripts/mbim_scripts/start_quectel_mbim.sh new file mode 100644 index 0000000000..7f784e6adc --- /dev/null +++ b/ci-scripts/mbim_scripts/start_quectel_mbim.sh @@ -0,0 +1,10 @@ +set -x + +sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off +sleep 1 +sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=on +sleep 2 +sudo mbimcli -p -d /dev/cdc-wdm0 --attach-packet-service + +sudo mbimcli -p -d /dev/cdc-wdm0 --connect=session-id=0,access-string=oai.ipv4,ip-type=ipv4 +sudo /opt/mbim/mbim-set-ip.sh /dev/cdc-wdm0 wwan0 0 diff --git a/ci-scripts/mbim_scripts/stop_quectel_mbim.sh b/ci-scripts/mbim_scripts/stop_quectel_mbim.sh new file mode 100644 index 0000000000..e7dbbaa43d --- /dev/null +++ b/ci-scripts/mbim_scripts/stop_quectel_mbim.sh @@ -0,0 +1,3 @@ +set -x + +sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml index 49cd79783a..7bec0f8a83 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml @@ -30,7 +30,7 @@ 111111 100000 -010000 +010010 030101 010001 000001 @@ -39,7 +39,6 @@ 070000 070001 010010 -010002 030201 @@ -80,28 +79,16 @@ 5 - - Initialize_UE - Initialize Quectel - nrmodule2_quectel - - - - Terminate_UE - Terminate Quectel - nrmodule2_quectel - - Attach_UE Attach UE - nrmodule2_quectel + up2 Ping Ping: 20 pings - nrmodule2_quectel + up2 -c 20 %cn_ip% 1 60 @@ -110,8 +97,8 @@ Ping Ping: 100 pings, size 1024 - nrmodule2_quectel - -c 100 -s 1024 -i 0,2 %cn_ip% + up2 + -c 100 -s 1024 -i 0.2 %cn_ip% 1 60 @@ -121,7 +108,7 @@ iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile) -u -b 26M -t 60 DL - nrmodule2_quectel + up2 5 95 single-ue @@ -132,7 +119,7 @@ iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) -u -b 7M -t 60 UL - nrmodule2_quectel + up2 5 95 single-ue @@ -141,7 +128,7 @@ Detach_UE Detach UE - nrmodule2_quectel + up2 diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml index a9ed0b2bea..f57b77648c 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml @@ -30,7 +30,7 @@ 111111 100000 -010000 +010010 030101 010001 000001 @@ -39,7 +39,6 @@ 070000 070001 010010 -010002 030201 @@ -80,28 +79,16 @@ 5 - - Initialize_UE - Initialize Quectel - nrmodule2_quectel - - - - Terminate_UE - Terminate Quectel - nrmodule2_quectel - - Attach_UE Attach UE - nrmodule2_quectel + up2 Ping Ping: 20 pings - nrmodule2_quectel + up2 -c 20 %cn_ip% 1 60 @@ -110,8 +97,8 @@ Ping Ping: 100 pings, size 1024 - nrmodule2_quectel - -c 100 -s 1024 -i 0,2 %cn_ip% + up2 + -c 100 -s 1024 -i 0.2 %cn_ip% 1 60 @@ -121,7 +108,7 @@ iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile) -u -b 1M -t 60 DL - nrmodule2_quectel + up2 5 95 single-ue @@ -132,7 +119,7 @@ iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) -u -b 7M -t 60 UL - nrmodule2_quectel + up2 5 95 single-ue @@ -141,7 +128,7 @@ Detach_UE Detach UE - nrmodule2_quectel + up2 diff --git a/ci-scripts/yaml_files/5g_rfsimulator/README.md b/ci-scripts/yaml_files/5g_rfsimulator/README.md index 5807081155..cb4a69aacb 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/README.md +++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md @@ -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 ## diff --git a/executables/nr-ue.c b/executables/nr-ue.c index a1490c104f..1ceb49e0d7 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -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 diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 4e5e14089c..24e5b53629 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -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); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 608db26921..1bea7b0a6d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -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>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop - - for (ii=0;ii 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(); } //============================================================================================== diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9cfe4941cd..bb0b8cbe6f 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -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); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 4662a7eab6..876d308889 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -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) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index f5ec77d8af..4bc3a6df16 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -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; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 512c6eb483..57883839d5 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -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, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 4e23a5a26d..f2f625b79c 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -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); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index fa4e07ca5e..738b8ff7c4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -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); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 85f577a51a..5eb895c52e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -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); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 1efd3f72bf..a5df641f4a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -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; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d135225c1e..073143b288 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -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); } } } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 668cc7d52b..7f9f5aa55e 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -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); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index c8648d4855..9acb4785fd 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -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; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 2e821e3034..8385236ff1 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -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; } - return NULL; + if (recvLen > sizeof(msg)) { + LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen); + continue; + } + process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen); + } + return NULL; } -static void nsa_rrc_ue_process_ueCapabilityEnquiry(void) +static void nsa_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc) { - NR_UE_NR_Capability_t *UE_Capability_nr = NR_UE_rrc_inst[0].UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t)); + NR_UE_NR_Capability_t *UE_Capability_nr = rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t)); NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t)); nr_bandnr->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 RRC_MEASUREMENT_PROCEDURE: - { - LOG_I(NR_RRC, "We are processing a %d message \n", msg_type); - - LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL; - asn_dec_rval_t dec_rval = uper_decode_complete(NULL, - &asn_DEF_NR_MeasObjectToAddMod, - (void **)&nr_meas_obj, - msg_buffer, - msg_len); - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) - { - SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING); - LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code); - break; - } - LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n", - nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15, - nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15); - start_oai_nrue_threads(); - break; - } - case RRC_CONFIG_COMPLETE_REQ: - { - struct msg { - uint32_t RadioBearer_size; - uint32_t SecondaryCellGroup_size; - uint8_t trans_id; - uint8_t padding[3]; - uint8_t buffer[]; - } hdr; - AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n"); - memcpy(&hdr, msg_buffer, sizeof(hdr)); - LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n"); - uint32_t nr_RadioBearer_size = hdr.RadioBearer_size; - uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size; - AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len, - "nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n", - nr_RadioBearer_size, - nr_SecondaryCellGroup_size, - sizeof(hdr), msg_len); - NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id; - LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n", - nr_RadioBearer_size, - nr_SecondaryCellGroup_size, - t_id); - - uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer); - uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size; - process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, - nr_SecondaryCellGroup_size); - process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size); - LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id); - uint8_t buffer[RRC_BUF_SIZE]; - size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id); - nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ); - break; - } - - case OAI_TUN_IFACE_NSA: - { - LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n"); - char cmd_line[RRC_BUF_SIZE]; - memcpy(cmd_line, msg_buffer, sizeof(cmd_line)); - LOG_D(NR_RRC, "Command line: %s\n", cmd_line); - if (background_system(cmd_line) != 0) - { - LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line); - } - break; - } - - default: - LOG_E(NR_RRC, "No NSA Message Found\n"); + case 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 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); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 3cd453197b..4ce65ef036 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -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 */ diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 4750c69ffe..1bb3fda06f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -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