diff --git a/ci-scripts/cls_oai_html.py b/ci-scripts/cls_oai_html.py
index 478cbd1860..c90b01a338 100644
--- a/ci-scripts/cls_oai_html.py
+++ b/ci-scripts/cls_oai_html.py
@@ -224,7 +224,6 @@ class HTMLManagement():
self.htmlFile.write(' \n')
self.htmlFile.write(' \n')
self.htmlFile.close()
- time.sleep(1)
if passStatus:
cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html"
subprocess.run(cmd, shell=True)
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index 4d7cf0a6fd..53bdacaacc 100644
--- a/ci-scripts/cls_oaicitest.py
+++ b/ci-scripts/cls_oaicitest.py
@@ -213,7 +213,7 @@ def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetlos
pal_msg += f' (too high! >{iperf_packetloss_threshold}%)'
return (result, f'{req_msg}\n{bir_msg}\n{brl_msg}\n{jit_msg}\n{pal_msg}')
-def Custom_Command(HTML, node, command, command_fail):
+def Custom_Command(HTML, node, command):
logging.info(f"Executing custom command on {node}")
cmd = cls_cmd.getConnection(node)
ret = cmd.run(command)
@@ -221,26 +221,20 @@ def Custom_Command(HTML, node, command, command_fail):
logging.debug(f"Custom_Command: {command} on node: {node} - {'OK, command succeeded' if ret.returncode == 0 else f'Error, return code: {ret.returncode}'}")
status = 'OK'
message = []
- if ret.returncode != 0 and not command_fail:
- message = [ret.stdout]
- logging.warning(f'Custom_Command output: {message}')
- status = 'Warning'
- if ret.returncode != 0 and command_fail:
+ if ret.returncode != 0:
message = [ret.stdout]
logging.error(f'Custom_Command failed: output: {message}')
status = 'KO'
HTML.CreateHtmlTestRowQueue(command, status, message)
return status == 'OK' or status == 'Warning'
-def Custom_Script(HTML, node, script, command_fail):
+def Custom_Script(HTML, node, script):
logging.info(f"Executing custom script on {node}")
ret = cls_cmd.runScript(node, script, 90)
logging.debug(f"Custom_Script: {script} on node: {node} - return code {ret.returncode}, output:\n{ret.stdout}")
status = 'OK'
message = [ret.stdout]
- if ret.returncode != 0 and not command_fail:
- status = 'Warning'
- if ret.returncode != 0 and command_fail:
+ if ret.returncode != 0:
status = 'KO'
HTML.CreateHtmlTestRowQueue(script, status, message)
return status == 'OK' or status == 'Warning'
diff --git a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf
index 3e7dd08474..fa1bcc20c8 100644
--- a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf
+++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf
@@ -149,6 +149,8 @@ gNBs =
#ext2
#ntn_Config_r17
+ # This can be of values {s5, s10, s15, s20, s25, s30, s35, s40, s45, s50, s55, s60, s120, s180, s240, s900}
+ ntn-UlSyncValidityDuration-r17 = 240;
cellSpecificKoffset_r17 = 478;
ta-Common-r17 = 58629666; # 238.74 ms
positionX-r17 = 0;
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 333d515858..18956ae28f 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -376,14 +376,12 @@ def ExecuteActionWithParam(action):
# Change all execution targets to localhost
node = 'localhost'
command = test.findtext('command')
- command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes']
- success = cls_oaicitest.Custom_Command(HTML, node, command, command_fail)
+ success = cls_oaicitest.Custom_Command(HTML, node, command)
elif action == 'Custom_Script':
node = test.findtext('node')
script = test.findtext('script')
- command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes']
- success = cls_oaicitest.Custom_Script(HTML, node, script, command_fail)
+ success = cls_oaicitest.Custom_Script(HTML, node, script)
elif action == 'Pull_Cluster_Image':
tag_prefix = test.findtext('tag_prefix') or ""
@@ -626,6 +624,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
HTML.testCase_id=CiTestObj.testCase_id
CiTestObj.desc = test.findtext('desc')
always_exec = test.findtext('always_exec') in ['True', 'true', 'Yes', 'yes']
+ may_fail = test.findtext('may_fail') in ['True', 'true', 'Yes', 'yes']
HTML.desc=CiTestObj.desc
action = test.findtext('class')
if (CheckClassValidity(xml_class_list, action, id) == False):
@@ -639,7 +638,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
break
try:
test_succeeded = ExecuteActionWithParam(action)
- if not test_succeeded:
+ if not test_succeeded and may_fail:
+ logging.warning(f"test ID {test_case_id} action {action} may or may not fail, proceeding despite error")
+ elif not test_succeeded:
logging.error(f"test ID {test_case_id} action {action} failed ({test_succeeded}), skipping next tests")
task_set_succeeded = False
except Exception as e:
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 6f58478476..f0f790ba2c 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -95,7 +95,6 @@ class RANManagement():
self.cmd_prefix = '' # prefix before {lte,nr}-softmodem
self.node = ''
self.command = ''
- self.command_fail = False
#-----------------------------------------------------------
diff --git a/ci-scripts/tests/test-runner/test.xml b/ci-scripts/tests/test-runner/test.xml
index d5efacfdae..cb54989301 100644
--- a/ci-scripts/tests/test-runner/test.xml
+++ b/ci-scripts/tests/test-runner/test.xml
@@ -27,6 +27,8 @@
wrench
000001
+ 000011
+ 000012
000002
000003
000004
@@ -38,7 +40,21 @@
This should succeed
localhost
true
- yes
+
+
+
+ Custom_Command
+ This may fail
+ true
+ localhost
+ false
+
+
+
+ Custom_Command
+ This is still executed
+ localhost
+ true
@@ -46,7 +62,6 @@
This should fail
localhost
false
- yes
@@ -54,7 +69,6 @@
This should be skipped
localhost
true
- yes
@@ -63,6 +77,5 @@
true
localhost
true
- yes
diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml
index b27b0b5701..3b783a9215 100644
--- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml
+++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml
@@ -134,7 +134,6 @@
Simulate a DL radio channel with noise (3 dB)
cacofonix
echo channelmod modify 0 noise_power_dB 3 | nc --send-only 192.168.71.181 8091
- yes
@@ -166,7 +165,6 @@
Trigger Reestablishment
cacofonix
echo ci force_reestab | nc 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
- yes
@@ -185,7 +183,6 @@
Verify Reestablishment
cacofonix
echo ci get_reestab_count | nc 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
- yes
@@ -193,7 +190,6 @@
Simulate a disruption of DL radio channel (ploss 55)
cacofonix
echo channelmod modify 0 ploss 55 | nc 192.168.71.181 8091
- yes
@@ -201,7 +197,6 @@
Get UE sync state (UE ID 0)
cacofonix
echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_NOT_SYNC
- yes
@@ -209,7 +204,6 @@
Restoration of the original DL channel conditions (ploss 20)
cacofonix
echo channelmod modify 0 ploss 20 | nc 192.168.71.181 8091
- yes
@@ -217,7 +211,6 @@
Get UE sync state (UE ID 0)
cacofonix
echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_CONNECTED
- yes
@@ -225,7 +218,6 @@
Trigger Handover
cacofonix
echo ci trigger_f1_ho | nc 192.168.71.150 9090
- yes
@@ -233,7 +225,6 @@
UE (1) connected to DU-PCI 0?
cacofonix
echo ci fetch_du_by_ue_id 1 | nc 192.168.71.150 9090 | grep "3584"
- yes
@@ -241,7 +232,6 @@
UE (1) connected to DU-PCI 1?
cacofonix
echo ci fetch_du_by_ue_id 1 | nc 192.168.71.150 9090 | grep "3585"
- yes
diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml
index f20820629b..80e4d189ff 100644
--- a/ci-scripts/xml_files/container_5g_rfsim.xml
+++ b/ci-scripts/xml_files/container_5g_rfsim.xml
@@ -242,7 +242,7 @@
Detach_UE
- Detach OAI UE 2 to 10
+ Detach OAI UE 3 to 10
rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10
cacofonix cacofonix cacofonix cacofonix cacofonix cacofonix cacofonix cacofonix
diff --git a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml
index 5a59880b2f..91275a5f10 100644
--- a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml
+++ b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml
@@ -151,7 +151,6 @@
Force Msg3 C-RNTI RA
cacofonix
echo ciUE force_crnti_ra | nc 192.168.71.150 8091
- yes
@@ -159,7 +158,6 @@
Force RRC_IDLE (UE ID 0)
cacofonix
echo ciUE force_RRC_IDLE | nc 192.168.71.150 8091
- yes
diff --git a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml
index 133d960c3a..ac7e28f003 100644
--- a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml
+++ b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml
@@ -79,7 +79,6 @@
Check that UE synched
cacofonix
docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK"
- yes
diff --git a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml
index bf71fc98ab..34d46cc87d 100644
--- a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml
+++ b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml
@@ -108,14 +108,6 @@
0
-
- Custom_Command
- true
- Clean-Up any residual volume
- cacofonix
- docker volume rm 5g_rfsimulator_tdd_dora_rrc.config
-
-
Clean_Test_Server_Images
true
diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
index 035163f3db..17c8a9b14f 100644
--- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
@@ -70,9 +70,9 @@
Custom_Command
- Reset USRP
+ Reset USRP on nepes
nepes
- sudo -S /usr/lib/uhd/utils/b2xx_fx3_utils --reset-device
+ sudo -S /usr/local/lib/uhd/utils/b2xx_fx3_utils --reset-device
diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml
index 7eb6411827..88ab941e31 100644
--- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml
+++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml
@@ -182,7 +182,7 @@
Iperf
- iperf (DL/3Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (DL/3Mbps/UDP)(30 sec)
-u -b 45M -t 30 -R
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
25
@@ -193,7 +193,7 @@
Iperf
- iperf (DL/TCP)(30 sec)(multi-ue profile)
+ iperf (DL/TCP)(30 sec)
-t 30 -R
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
2
@@ -202,7 +202,7 @@
Iperf
- iperf (UL/1Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (UL/1Mbps/UDP)(30 sec)
-u -b 15M -t 30
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
25
@@ -213,7 +213,7 @@
Iperf
- iperf (UL/TCP)(30 sec)(multi-ue profile)
+ iperf (UL/TCP)(30 sec)
-t 30
oc-cn5g
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml
index 739534be21..ed4a219f55 100644
--- a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml
+++ b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml
@@ -179,7 +179,7 @@
Iperf
- iperf (DL/4Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (DL/4Mbps/UDP)(30 sec)
-u -b 60M -t 30 -R
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
25
@@ -190,7 +190,7 @@
Iperf
- iperf (DL/TCP)(30 sec)(multi-ue profile)
+ iperf (DL/TCP)(30 sec)
-t 30 -R
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
3.9
@@ -199,7 +199,7 @@
Iperf
- iperf (UL/1.5Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (UL/1.5Mbps/UDP)(30 sec)
-u -b 22.5M -t 30
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
25
@@ -210,7 +210,7 @@
Iperf
- iperf (UL/TCP)(30 sec)(multi-ue profile)
+ iperf (UL/TCP)(30 sec)
-t 30
oc-cn5g
amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15
diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml
index 9f3559aff1..dacee9692f 100644
--- a/ci-scripts/xml_files/container_sa_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml
@@ -200,14 +200,12 @@
Trigger Reestablishment
ofqot
echo ci force_reestab | nc -N 127.0.0.1 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
- yes
Custom_Command
Verify Reestablishment
ofqot
echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
- yes
diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml
index dcbcb9a45f..b9535e6ea4 100644
--- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml
@@ -188,14 +188,12 @@
Trigger Reestablishment (on DU)
ofqot
echo ci force_reestab | nc -N 127.0.0.1 9091 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
- yes
Custom_Command
Verify Reestablishment (on CU)
ofqot
echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
- yes
diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml
index 9622b2cf13..fd935be551 100644
--- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml
@@ -233,14 +233,12 @@
Trigger Reestablishment (on DU)
ofqot
echo ci force_reestab | nc -N 127.0.0.1 9091 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
- yes
Custom_Command
Verify Reestablishment (on CU)
ofqot
echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
- yes
diff --git a/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml b/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml
index e71ec3e37c..742b09e3d8 100644
--- a/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml
+++ b/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml
@@ -49,7 +49,6 @@
Setup sriov and network interfaces Metanoia
cacofonix
- yes
@@ -92,7 +91,7 @@
Iperf
- iperf (DL/570Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (DL/570Mbps/UDP)(30 sec)
-u -b 570M -t 30 -R
up2-fhi72
20
@@ -103,7 +102,7 @@
Iperf
- iperf (DL/TCP)(30 sec)(multi-ue profile)
+ iperf (DL/TCP)(30 sec)
-t 30 -R
up2-fhi72
80
@@ -112,7 +111,7 @@
Iperf
- iperf (UL/100Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (UL/100Mbps/UDP)(30 sec)
-u -b 100M -t 30
up2-fhi72
20
@@ -123,7 +122,7 @@
Iperf
- iperf (UL/TCP)(30 sec)(multi-ue profile)
+ iperf (UL/TCP)(30 sec)
-t 30
up2-fhi72
80
@@ -166,7 +165,6 @@
Set CPU to idle state, set kernel parameters to default values
cacofonix
- yes
diff --git a/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml b/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml
index 4afe8f1b12..1d7cd323e4 100644
--- a/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml
+++ b/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml
@@ -36,6 +36,7 @@
100020
100030
100040
+ 100011
103000
100002
130000
@@ -49,7 +50,6 @@
Setup sriov and network interfaces VVDN
cacofonix
- yes
@@ -90,7 +90,7 @@
Iperf
- iperf (DL/600Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (DL/600Mbps/UDP)(30 sec)
-u -b 600M -t 30 -R
up2-fhi72
20
@@ -99,9 +99,20 @@
oc-cn5g-20897
+
+ Iperf
+ Optional iperf (DL/700Mbps/UDP)(30 sec)
+ true
+ -u -b 700M -t 30 -R
+ up2-fhi72
+ 10
+ 95
+ oc-cn5g-20897
+
+
Iperf
- iperf (DL/TCP)(30 sec)(multi-ue profile)
+ iperf (DL/TCP)(30 sec)
-t 30 -R
up2-fhi72
40
@@ -110,7 +121,7 @@
Iperf
- iperf (UL/80Mbps/UDP)(30 sec)(multi-ue profile)
+ iperf (UL/80Mbps/UDP)(30 sec)
-u -b 80M -t 30
up2-fhi72
20
@@ -121,7 +132,7 @@
Iperf
- iperf (UL/TCP)(30 sec)(multi-ue profile)
+ iperf (UL/TCP)(30 sec)
-t 30
up2-fhi72
10
@@ -164,7 +175,6 @@
Set CPU to idle state, set kernel parameters to default values
cacofonix
- yes
diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml
index 69201ebcc8..f116e97e24 100644
--- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml
@@ -194,14 +194,12 @@
Trigger Reestablishment
ofqot
echo ci force_reestab | nc -N 127.0.0.1 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
- yes
Custom_Command
Verify Reestablishment
ofqot
echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
- yes
diff --git a/common/platform_types.h b/common/platform_types.h
index 8cbd502fda..e345288061 100644
--- a/common/platform_types.h
+++ b/common/platform_types.h
@@ -207,6 +207,16 @@ typedef struct nsa_msg_t {
uint8_t msg_buffer[MAX_MESSAGE_SIZE];
} nsa_msg_t;
+typedef enum nr_lcid_rb_type { NR_LCID_NONE = 0, NR_LCID_SRB = 1, NR_LCID_DRB = 2 } nr_lcid_rb_type;
+
+typedef struct nr_lcid_rb_t {
+ nr_lcid_rb_type type;
+ union {
+ int srb_id;
+ int drb_id;
+ } choice;
+} nr_lcid_rb_t;
+
typedef struct transport_layer_addr_s {
/**
* Transport Layer Address as a bitstring:
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index f2e71390c7..ba2d48be28 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -231,6 +231,9 @@ Or by providing this the the command line parameters:
The main parameters to cope with the large NTN propagation delay are cellSpecificKoffset, ta-Common, ta-CommonDrift and the ephemeris data (satellite position and velocity vectors).
+The parameter `ntn-UlSyncValidityDuration-r17` indicates the maximum time duration from epochtime during which the UE can apply assistance information without having acquired new assistance information. i.e this enables UE to re-read SIB19 before timer with value ulSyncValidityDuration expires. The unit of the field is in seconds. Example values for GEO: 240s, MEO: 20s, LEO: 5s.
+As epochtime is not implemented yet, UE starts the timer from the TTI where SIB19 is received with ntn-UlSyncValidityDuration-r17 IE.
+
The parameter `cellSpecificKoffset_r17` is the scheduling offset used for the timing relationships that are modified for NTN (see TS 38.213).
The unit of the field Koffset is number of slots for a given subcarrier spacing of 15 kHz.
diff --git a/docker/Dockerfile.base.ubuntu22 b/docker/Dockerfile.base.ubuntu22
index 60e2aad8ab..ba8707d4db 100644
--- a/docker/Dockerfile.base.ubuntu22
+++ b/docker/Dockerfile.base.ubuntu22
@@ -40,6 +40,7 @@ RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
#gcc needed for build_oai
build-essential \
+ ccache \
psmisc \
git \
#use gcc-12 to avoid problems of default gcc-11 in FlexRIC
@@ -52,15 +53,15 @@ RUN apt-get update && \
flex \
m4 \
# python3-pip for conf template generation
- python3-pip && \
+ python3-pip \
+ wget && \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 --slave /usr/bin/g++ g++ /usr/bin/g++-12 && \
pip3 install --ignore-installed pyyaml
# Add "Tini - A tiny but valid init for containers", https://github.com/krallin/tini
# it will be copied into target containers, to print exit numbers and handle signals properly
ENV TINI_VERSION=v0.19.0
-ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} /tini
-RUN chmod +x /tini
+RUN wget https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} -O /tini && chmod +x /tini
# In some network environments, GIT proxy is required
RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi"
diff --git a/docker/Dockerfile.build.ubuntu22 b/docker/Dockerfile.build.ubuntu22
index a3c2417b33..c11946ecdb 100644
--- a/docker/Dockerfile.build.ubuntu22
+++ b/docker/Dockerfile.build.ubuntu22
@@ -36,7 +36,12 @@ WORKDIR /oai-ran
COPY . .
# build all targets so final targets can be created afterwards
-RUN /bin/sh oaienv && \
+RUN \
+ # Mount CCache cache direrctory
+ --mount=type=cache,target=/root/.cache/ccache/ \
+ # Mount CPM package cache
+ --mount=type=cache,target=/root/.cache/cpm/ \
+ /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai -c --ninja \
@@ -54,7 +59,10 @@ RUN /bin/sh oaienv && \
ldd ran_build/build/*.so
## Build FlexRIC for SM Models
-RUN mkdir -p openair2/E2AP/flexric/build && \
+RUN \
+ # Mount CCache cache direrctory
+ --mount=type=cache,target=/root/.cache/ccache/ \
+ mkdir -p openair2/E2AP/flexric/build && \
cd openair2/E2AP/flexric/build && \
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
-DKPM_VERSION=$KPM_VERSION \
diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi.h
index e8e645b8cf..ee405792d2 100644
--- a/nfapi/open-nFAPI/fapi/inc/nr_fapi.h
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi.h
@@ -35,6 +35,9 @@
#include "debug.h"
#define INDENTED_PRINTF(format, ...) printf("%*s" format, depth * 2, "", ##__VA_ARGS__)
+#define INDENTED_GENERIC_PRINT(string, format, ...) INDENTED_PRINTF(string " = " format "\n", ##__VA_ARGS__)
+#define INDENTED_TLV_PRINT(tlv_name, tlv) INDENTED_GENERIC_PRINT("(0x%04x) " tlv_name, "0x%02x", tlv.tl.tag, tlv.value)
+#define INDENTED_TLV_FORMAT_PRINT(tlv_name, format, tlv) INDENTED_GENERIC_PRINT("(0x%04x) " tlv_name, format, tlv.tl.tag, tlv.value)
#define EQ_TLV(_tlv_a, _tlv_b) \
do { \
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
index 281043b6d3..6bf2ff37ea 100644
--- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
@@ -724,6 +724,53 @@ uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *
&pNfapiMsg->vendor_extension));
}
+static uint8_t pack_dbt_table_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_dbt_tlv_ve_t *dbt_ve = (nfapi_nr_dbt_tlv_ve_t *)tlv;
+ nfapi_nr_dbt_pdu_t *dbt_config = &dbt_ve->value;
+ if (!( push16(dbt_config->num_dig_beams, ppWritePackedMsg, end) && push16(dbt_config->num_txrus, ppWritePackedMsg, end) )) {
+ return 0;
+ }
+ for (int i = 0; i< dbt_config->num_dig_beams; i++) {
+ const nfapi_nr_dig_beam_t *dig_beam = &dbt_config->dig_beam_list[i];
+ if (!(push16(dig_beam->beam_idx, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int k = 0; k< dbt_config->num_txrus; k++) {
+ const nfapi_nr_txru_t *tx_ru = &dig_beam->txru_list[k];
+ if (!(push16(tx_ru->dig_beam_weight_Re, ppWritePackedMsg, end) && push16(tx_ru->dig_beam_weight_Im, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+static uint8_t pack_pm_table_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_pm_tlv_ve_t *pm_ve = (nfapi_nr_pm_tlv_ve_t *)tlv;
+ nfapi_nr_pm_list_t *pmi_list = &pm_ve->value;
+ if (!( push16(pmi_list->num_pm_idx, ppWritePackedMsg, end) )) {
+ return 0;
+ }
+ for (int i = 0; i< pmi_list->num_pm_idx; i++) {
+ const nfapi_nr_pm_pdu_t *pm_pdu = &pmi_list->pmi_pdu[i];
+ if (!(push16(pm_pdu->pm_idx, ppWritePackedMsg, end) && push16(pm_pdu->numLayers, ppWritePackedMsg, end)
+ && push16(pm_pdu->num_ant_ports, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int k = 0; k < pm_pdu->numLayers; k++) {
+ for (int j = 0; j < pm_pdu->num_ant_ports; j++) {
+ const nfapi_nr_pm_weights_t *pm_weight = &pm_pdu->weights[k][j];
+ if (!(push16(pm_weight->precoder_weight_Re, ppWritePackedMsg, end) && push16(pm_weight->precoder_weight_Im, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
{
uint8_t *pNumTLVFields = (uint8_t *)*ppWritePackedMsg;
@@ -1044,11 +1091,19 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
// END Measurement Config
// START Digital Beam Table (DBT) PDU
- // Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_dbt_pdu_t, currently unused
+ if (pNfapiMsg->dbt_config.num_dig_beams != 0) {
+ nfapi_nr_dbt_tlv_ve_t dbt_tlv = {.tl.tag = NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, .value = pNfapiMsg->dbt_config};
+ pack_nr_tlv(NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, &dbt_tlv, ppWritePackedMsg, end, &pack_dbt_table_tlv_value);
+ numTLVs++;
+ }
// END Digital Beam Table (DBT) PDU
// START Precoding Matrix (PM) PDU
- // Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL
+ if (pNfapiMsg->pmi_list.num_pm_idx != 0) {
+ nfapi_nr_pm_tlv_ve_t pm_tlv = {.tl.tag = NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, .value = pNfapiMsg->pmi_list};
+ pack_nr_tlv(NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, &pm_tlv, ppWritePackedMsg, end, &pack_pm_table_tlv_value);
+ numTLVs++;
+ }
// is 0xA011 END Precoding Matrix (PM) PDU
#ifndef ENABLE_AERIAL
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
@@ -1156,6 +1211,62 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
return retval;
}
+static uint8_t unpack_dbt_table_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_dbt_pdu_t *dbt_config = (nfapi_nr_dbt_pdu_t *)tlv;
+ if (!(pull16(ppReadPackedMsg, &dbt_config->num_dig_beams, end) && pull16(ppReadPackedMsg, &dbt_config->num_txrus, end))) {
+ return 0;
+ }
+ if (dbt_config->num_dig_beams > 0) {
+ dbt_config->dig_beam_list = calloc(dbt_config->num_dig_beams, sizeof(*dbt_config->dig_beam_list));
+ }
+ for (int i = 0; i < dbt_config->num_dig_beams; i++) {
+ nfapi_nr_dig_beam_t *dig_beam = &dbt_config->dig_beam_list[i];
+ if (!(pull16(ppReadPackedMsg, &dig_beam->beam_idx, end))) {
+ return 0;
+ }
+ if (dbt_config->num_txrus > 0) {
+ dig_beam->txru_list = calloc(dbt_config->num_txrus, sizeof(*dig_beam->txru_list));
+ }
+ for (int k = 0; k < dbt_config->num_txrus; k++) {
+ nfapi_nr_txru_t *tx_ru = &dig_beam->txru_list[k];
+ if (!(pull16(ppReadPackedMsg, &tx_ru->dig_beam_weight_Re, end) && pull16(ppReadPackedMsg, &tx_ru->dig_beam_weight_Im, end))) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+static uint8_t unpack_pm_table_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_pm_list_t *pm_list = (nfapi_nr_pm_list_t *)tlv;
+ if (!(pull16(ppReadPackedMsg, &pm_list->num_pm_idx, end))) {
+ return 0;
+ }
+ if (pm_list->num_pm_idx > 0) {
+ pm_list->pmi_pdu = calloc(pm_list->num_pm_idx, sizeof(*pm_list->pmi_pdu));
+ }
+ for (int i = 0; i < pm_list->num_pm_idx; i++) {
+ nfapi_nr_pm_pdu_t *pm_pdu = &pm_list->pmi_pdu[i];
+ if (!(pull16(ppReadPackedMsg, &pm_pdu->pm_idx, end) && pull16(ppReadPackedMsg, &pm_pdu->numLayers, end)
+ && pull16(ppReadPackedMsg, &pm_pdu->num_ant_ports, end))) {
+ return 0;
+ }
+ AssertFatal(pm_pdu->numLayers <= 4 && pm_pdu->num_ant_ports <= 4, "Precoding matrix size limited to 4X4 for the time being\n");
+ for (int k = 0; k < pm_pdu->numLayers; k++) {
+ for (int j = 0; j < pm_pdu->num_ant_ports; j++) {
+ nfapi_nr_pm_weights_t *pm_weight = &pm_pdu->weights[k][j];
+ if (!(pulls16(ppReadPackedMsg, &pm_weight->precoder_weight_Re, end)
+ && pulls16(ppReadPackedMsg, &pm_weight->precoder_weight_Im, end))) {
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
{
// Helper vars for indexed TLVs
@@ -1221,6 +1332,8 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
{NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG, &(pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext), &unpack_uint8_tlv_value},
{NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG, NULL, &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, &(pNfapiMsg->measurement_config.rssi_measurement), &unpack_uint8_tlv_value},
+ {NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, NULL, &unpack_dbt_table_tlv_value},
+ {NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, NULL, &unpack_pm_table_tlv_value},
{NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), &unpack_ipv4_address_value},
{NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), &unpack_ipv6_address_value},
{NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), &unpack_uint16_tlv_value},
@@ -1268,6 +1381,14 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam_ve_idx], ppReadPackedMsg, end);
beam_ve_idx ++;
break;
+ case NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG:
+ unpack_fns[idx].tlv = &generic_tl;
+ result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->dbt_config, ppReadPackedMsg, end);
+ break;
+ case NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG:
+ unpack_fns[idx].tlv = &generic_tl;
+ result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->pmi_list, ppReadPackedMsg, end);
+ break;
case NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG:
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.tag = generic_tl.tag;
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.length = generic_tl.length;
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
index 1b5e3f0ad8..4c3f32ef27 100644
--- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
@@ -259,6 +259,40 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const
EQ_TLV(unpacked_req->measurement_config.rssi_measurement, req->measurement_config.rssi_measurement);
+ EQ(unpacked_req->dbt_config.num_dig_beams, req->dbt_config.num_dig_beams);
+
+ EQ(unpacked_req->dbt_config.num_txrus, req->dbt_config.num_txrus);
+
+ for (int i = 0; i < req->dbt_config.num_dig_beams; i++) {
+ const nfapi_nr_dig_beam_t *unpacked_dig_beam = &unpacked_req->dbt_config.dig_beam_list[i];
+ const nfapi_nr_dig_beam_t *req_dig_beam = &req->dbt_config.dig_beam_list[i];
+ EQ(unpacked_dig_beam->beam_idx, req_dig_beam->beam_idx);
+ for (int k = 0; k < req->dbt_config.num_txrus; ++k) {
+ const nfapi_nr_txru_t *unpacked_tx_ru = &unpacked_dig_beam->txru_list[k];
+ const nfapi_nr_txru_t *req_tx_ru = &req_dig_beam->txru_list[k];
+ EQ(unpacked_tx_ru->dig_beam_weight_Re, req_tx_ru->dig_beam_weight_Re);
+ EQ(unpacked_tx_ru->dig_beam_weight_Im, req_tx_ru->dig_beam_weight_Im);
+ }
+ }
+
+ EQ(unpacked_req->pmi_list.num_pm_idx, req->pmi_list.num_pm_idx);
+
+ for (int i = 0; i < req->pmi_list.num_pm_idx; i++) {
+ const nfapi_nr_pm_pdu_t *req_pmi_pdu = &req->pmi_list.pmi_pdu[i];
+ const nfapi_nr_pm_pdu_t *unpacked_pmi_pdu = &unpacked_req->pmi_list.pmi_pdu[i];
+ EQ(unpacked_pmi_pdu->pm_idx, req_pmi_pdu->pm_idx);
+ EQ(unpacked_pmi_pdu->numLayers, req_pmi_pdu->numLayers);
+ EQ(unpacked_pmi_pdu->num_ant_ports, req_pmi_pdu->num_ant_ports);
+ for (int j = 0; j < req_pmi_pdu->num_ant_ports; ++j) {
+ for (int k = 0; k < req_pmi_pdu->num_ant_ports; ++k) {
+ const nfapi_nr_pm_weights_t* req_pm_weight = &req_pmi_pdu->weights[j][k];
+ const nfapi_nr_pm_weights_t* unpacked_pm_weight = &unpacked_pmi_pdu->weights[j][k];
+ EQ(unpacked_pm_weight->precoder_weight_Re, req_pm_weight->precoder_weight_Re);
+ EQ(unpacked_pm_weight->precoder_weight_Im, req_pm_weight->precoder_weight_Im);
+ }
+ }
+ }
+
EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv4.tl.tag, req->nfapi_config.p7_vnf_address_ipv4.tl.tag);
for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv4.address[i], req->nfapi_config.p7_vnf_address_ipv4.address[i]);
@@ -391,27 +425,20 @@ bool eq_error_indication(const nfapi_nr_error_indication_scf_t *unpacked_req, co
void free_param_request(nfapi_nr_param_request_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void free_param_response(nfapi_nr_param_response_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
+
+ free(msg->cell_param.config_tlvs_to_report_list);
- if (msg->cell_param.config_tlvs_to_report_list) {
- free(msg->cell_param.config_tlvs_to_report_list);
- }
}
void free_config_request(nfapi_nr_config_request_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
if (msg->prach_config.num_prach_fd_occasions_list) {
for (int i = 0; i < msg->prach_config.num_prach_fd_occasions.value; i++) {
@@ -430,10 +457,14 @@ void free_config_request(nfapi_nr_config_request_scf_t *msg)
free(msg->tdd_table.max_tdd_periodicity_list);
}
- if (msg->pmi_list.pmi_pdu) {
- free(msg->pmi_list.pmi_pdu);
+ for (int i = 0; i < msg->dbt_config.num_dig_beams; i++) {
+ free(msg->dbt_config.dig_beam_list[i].txru_list);
}
+ free(msg->dbt_config.dig_beam_list);
+
+ free(msg->pmi_list.pmi_pdu);
+
if (msg->analog_beamforming_ve.analog_beam_list) {
free(msg->analog_beamforming_ve.analog_beam_list);
}
@@ -441,60 +472,40 @@ void free_config_request(nfapi_nr_config_request_scf_t *msg)
void free_config_response(nfapi_nr_config_response_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
- if (msg->invalid_tlvs_list) {
- free(msg->invalid_tlvs_list);
- }
+ free(msg->invalid_tlvs_list);
- if (msg->invalid_tlvs_configured_in_idle_list) {
- free(msg->invalid_tlvs_configured_in_idle_list);
- }
+ free(msg->invalid_tlvs_configured_in_idle_list);
- if (msg->invalid_tlvs_configured_in_running_list) {
- free(msg->invalid_tlvs_configured_in_running_list);
- }
+ free(msg->invalid_tlvs_configured_in_running_list);
- if (msg->missing_tlvs_list) {
- free(msg->missing_tlvs_list);
- }
+ free(msg->missing_tlvs_list);
}
void free_start_request(nfapi_nr_start_request_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void free_start_response(nfapi_nr_start_response_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void free_stop_request(nfapi_nr_stop_request_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void free_stop_indication(nfapi_nr_stop_indication_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void free_error_indication(nfapi_nr_error_indication_scf_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void copy_param_request(const nfapi_nr_param_request_scf_t *src, nfapi_nr_param_request_scf_t *dst)
@@ -810,6 +821,42 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf
COPY_TLV(dst->measurement_config.rssi_measurement, src->measurement_config.rssi_measurement);
+ dst->dbt_config.num_dig_beams = src->dbt_config.num_dig_beams;
+ dst->dbt_config.num_txrus = src->dbt_config.num_txrus;
+ dst->dbt_config.dig_beam_list = calloc(dst->dbt_config.num_dig_beams, sizeof(*dst->dbt_config.dig_beam_list));
+ for (int i = 0; i < dst->dbt_config.num_dig_beams; i++) {
+ nfapi_nr_dig_beam_t *dst_dig_beam = &dst->dbt_config.dig_beam_list[i];
+ const nfapi_nr_dig_beam_t *src_dig_beam = &src->dbt_config.dig_beam_list[i];
+ dst_dig_beam->beam_idx = src_dig_beam->beam_idx;
+ dst_dig_beam->txru_list = calloc(dst->dbt_config.num_txrus , sizeof(*dst_dig_beam->txru_list ));
+ for (int k = 0; k < dst->dbt_config.num_txrus; ++k) {
+ nfapi_nr_txru_t *dst_tx_ru = &dst_dig_beam->txru_list[k];
+ const nfapi_nr_txru_t *src_tx_ru = &src_dig_beam->txru_list[k];
+ dst_tx_ru->dig_beam_weight_Re = src_tx_ru->dig_beam_weight_Re;
+ dst_tx_ru->dig_beam_weight_Im = src_tx_ru->dig_beam_weight_Im;
+ }
+ }
+
+ dst->pmi_list.num_pm_idx = src->pmi_list.num_pm_idx;
+ if (dst->pmi_list.num_pm_idx > 0) {
+ dst->pmi_list.pmi_pdu = calloc(dst->pmi_list.num_pm_idx , sizeof(*dst->pmi_list.pmi_pdu));
+ for (int i = 0; i < dst->pmi_list.num_pm_idx; i++) {
+ nfapi_nr_pm_pdu_t * dst_pmi_pdu = &dst->pmi_list.pmi_pdu[i];
+ const nfapi_nr_pm_pdu_t * src_pmi_pdu = &src->pmi_list.pmi_pdu[i];
+ dst_pmi_pdu->pm_idx = src_pmi_pdu->pm_idx;
+ dst_pmi_pdu->numLayers = src_pmi_pdu->numLayers;
+ dst_pmi_pdu->num_ant_ports = src_pmi_pdu->num_ant_ports;
+ for (int j = 0; j < dst_pmi_pdu->numLayers; ++j) {
+ for (int k = 0; k < dst_pmi_pdu->num_ant_ports; ++k) {
+ nfapi_nr_pm_weights_t* dst_pm_weight = &dst_pmi_pdu->weights[j][k];
+ const nfapi_nr_pm_weights_t* src_pm_weight = &src_pmi_pdu->weights[j][k];
+ dst_pm_weight->precoder_weight_Re = src_pm_weight->precoder_weight_Re;
+ dst_pm_weight->precoder_weight_Im = src_pm_weight->precoder_weight_Im;
+ }
+ }
+ }
+ }
+
COPY_TL(dst->nfapi_config.p7_vnf_address_ipv4.tl, src->nfapi_config.p7_vnf_address_ipv4.tl);
memcpy(dst->nfapi_config.p7_vnf_address_ipv4.address,
src->nfapi_config.p7_vnf_address_ipv4.address,
@@ -986,22 +1033,382 @@ void dump_param_request(const nfapi_nr_param_request_scf_t *msg)
void dump_param_response(const nfapi_nr_param_response_scf_t *msg)
{
int depth = 0;
- dump_p5_message_header(&msg->header,depth);
+ dump_p5_message_header(&msg->header, depth);
depth++;
INDENTED_PRINTF("Error Code = 0x%02x\n", msg->error_code);
INDENTED_PRINTF("Number of TLVs = 0x%02x\n", msg->num_tlv);
/* dump all TLVs from each table */
+ /* Cell Param */
+ const nfapi_nr_cell_param_t *cell_param = &msg->cell_param;
+ depth++;
+ INDENTED_TLV_PRINT("Release Capability", cell_param->release_capability);
+ INDENTED_TLV_PRINT("PHY State", cell_param->phy_state);
+ INDENTED_TLV_PRINT("Skip Blank Dl Config", cell_param->skip_blank_dl_config);
+ INDENTED_TLV_PRINT("Skip Blank UL Config", cell_param->skip_blank_ul_config);
+ INDENTED_TLV_PRINT("NumConfigTLVsToReport", cell_param->num_config_tlvs_to_report);
+ depth++;
+ for (int i = 0; i < cell_param->num_config_tlvs_to_report.value; i++) {
+ const nfapi_uint8_tlv_t *reportedTLV = &cell_param->config_tlvs_to_report_list[i];
+ INDENTED_PRINTF("(0x%04x) Reported CONFIG TLV #%d = 0x%02x\n", reportedTLV->tl.tag, i + 1, reportedTLV->value);
+ }
+ depth--;
+ /* Carrier Param */
+ const nfapi_nr_carrier_param_t *carrier_param = &msg->carrier_param;
+ INDENTED_TLV_PRINT("Cyclic Prefix", carrier_param->cyclic_prefix);
+ INDENTED_TLV_PRINT("Supported SCS DL", carrier_param->supported_subcarrier_spacings_dl);
+ INDENTED_TLV_PRINT("Supported BW DL", carrier_param->supported_bandwidth_dl);
+ INDENTED_TLV_PRINT("Supported SCS UL", carrier_param->supported_subcarrier_spacings_ul);
+ INDENTED_TLV_PRINT("Supported BW UL", carrier_param->supported_bandwidth_ul);
+ /* PDCCH Param */
+ const nfapi_nr_pdcch_param_t *pdcch_param = &msg->pdcch_param;
+ INDENTED_TLV_PRINT("CCE Mapping Type", pdcch_param->cce_mapping_type);
+ INDENTED_TLV_PRINT("CSet Outside First 3 OFDM Symbols of Slot", pdcch_param->coreset_outside_first_3_of_ofdm_syms_of_slot);
+ INDENTED_TLV_PRINT("Precoder Granularity Coreset", pdcch_param->coreset_precoder_granularity_coreset);
+ INDENTED_TLV_PRINT("PDCCH Mu MIMO", pdcch_param->pdcch_mu_mimo);
+ INDENTED_TLV_PRINT("PDCCH Precoder Cycling", pdcch_param->pdcch_precoder_cycling);
+ INDENTED_TLV_PRINT("Max PDCCH per Slot", pdcch_param->max_pdcch_per_slot);
+ /* PUCHH Params */
+ const nfapi_nr_pucch_param_t *pucch_param = &msg->pucch_param;
+ INDENTED_TLV_PRINT("PUCCH Formats", pucch_param->pucch_formats);
+ INDENTED_TLV_PRINT("Max PUCCH per Slot", pucch_param->max_pucchs_per_slot);
+ /* PDSCH Params */
+ const nfapi_nr_pdsch_param_t *pdsch_param = &msg->pdsch_param;
+ INDENTED_TLV_PRINT("PDSCH Mapping Type", pdsch_param->pdsch_mapping_type);
+ INDENTED_TLV_PRINT("PDSCH Allocation Types", pdsch_param->pdsch_allocation_types);
+ INDENTED_TLV_PRINT("PDSCH VRB to PRB Mapping", pdsch_param->pdsch_vrb_to_prb_mapping);
+ INDENTED_TLV_PRINT("PDSCH CBG", pdsch_param->pdsch_cbg);
+ INDENTED_TLV_PRINT("PDSCH DMRS Config Types", pdsch_param->pdsch_dmrs_config_types);
+ INDENTED_TLV_PRINT("PDSCH DMRS Max Length", pdsch_param->pdsch_dmrs_max_length);
+ INDENTED_TLV_PRINT("PDSCH DMRS Additional Position", pdsch_param->pdsch_dmrs_additional_pos);
+ INDENTED_TLV_PRINT("Max PDSCH TBs per Slot", pdsch_param->max_pdsch_tbs_per_slot);
+ INDENTED_TLV_PRINT("Max number MIMO Layers PDSCH", pdsch_param->max_number_mimo_layers_pdsch);
+ INDENTED_TLV_PRINT("Supported Max Modulation Order DL", pdsch_param->supported_max_modulation_order_dl);
+ INDENTED_TLV_PRINT("Max Mu MIMO Users DL", pdsch_param->max_mu_mimo_users_dl);
+ INDENTED_TLV_PRINT("PDSCH Data in DMRS Symbols", pdsch_param->pdsch_data_in_dmrs_symbols);
+ INDENTED_TLV_PRINT("Preemption Support", pdsch_param->premption_support);
+ INDENTED_TLV_PRINT("PDSCH Non Slot Support", pdsch_param->pdsch_non_slot_support);
+ /* PUSCH Params */
+ const nfapi_nr_pusch_param_t *pusch_param = &msg->pusch_param;
+ INDENTED_TLV_PRINT("UCI Mux ULSCH in PUSCH", pusch_param->uci_mux_ulsch_in_pusch);
+ INDENTED_TLV_PRINT("UCI Only PUSCH", pusch_param->uci_only_pusch);
+ INDENTED_TLV_PRINT("PUSCH Frequency Hopping", pusch_param->pusch_frequency_hopping);
+ INDENTED_TLV_PRINT("PUSCH DMRS Config Types", pusch_param->pusch_dmrs_config_types);
+ INDENTED_TLV_PRINT("PUSCH DMRS Max Len", pusch_param->pusch_dmrs_max_len);
+ INDENTED_TLV_PRINT("PUSCH DMRS Additional Pos", pusch_param->pusch_dmrs_additional_pos);
+ INDENTED_TLV_PRINT("PUSCH CBG", pusch_param->pusch_cbg);
+ INDENTED_TLV_PRINT("PUSCH Mapping Type", pusch_param->pusch_mapping_type);
+ INDENTED_TLV_PRINT("PUSCH Allocation Types", pusch_param->pusch_allocation_types);
+ INDENTED_TLV_PRINT("PUSCH VRB to PRB Mapping", pusch_param->pusch_vrb_to_prb_mapping);
+ INDENTED_TLV_PRINT("PUSCH Max PTRS Ports", pusch_param->pusch_max_ptrs_ports);
+ INDENTED_TLV_PRINT("Max PUSCH TBs per Slot", pusch_param->max_pduschs_tbs_per_slot);
+ INDENTED_TLV_PRINT("Max Number MIMO Layers non CB PUSCH", pusch_param->max_number_mimo_layers_non_cb_pusch);
+ INDENTED_TLV_PRINT("Supported Modulation Order UL", pusch_param->supported_modulation_order_ul);
+ INDENTED_TLV_PRINT("Max MU MIMO Users UL", pusch_param->max_mu_mimo_users_ul);
+ INDENTED_TLV_PRINT("DTFS OFDM Support", pusch_param->dfts_ofdm_support);
+ INDENTED_TLV_PRINT("PUSCH Aggregation Factor", pusch_param->pusch_aggregation_factor);
+ /* PRACH Params */
+ const nfapi_nr_prach_param_t *prach_param = &msg->prach_param;
+ INDENTED_TLV_PRINT("PRACH Long Formats", prach_param->prach_long_formats);
+ INDENTED_TLV_PRINT("PRACH Short Formats", prach_param->prach_short_formats);
+ INDENTED_TLV_PRINT("PRACH Restricted Sets", prach_param->prach_restricted_sets);
+ INDENTED_TLV_PRINT("Max PRACH Occasions in a Slot", prach_param->max_prach_fd_occasions_in_a_slot);
+ /* Measurement Params */
+ const nfapi_nr_measurement_param_t *measurement_param = &msg->measurement_param;
+ INDENTED_TLV_PRINT("RSSI Measurement Support", measurement_param->rssi_measurement_support);
+ /* nFAPI Config */
+ const nfapi_nr_nfapi_t *nfapi_config = &msg->nfapi_config;
+ if (nfapi_config->p7_vnf_address_ipv4.tl.tag) {
+ char ip_str[INET_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv4",
+ "%s",
+ nfapi_config->p7_vnf_address_ipv4.tl.tag,
+ inet_ntop(AF_INET, nfapi_config->p7_vnf_address_ipv4.address, ip_str, sizeof(ip_str)));
+ }
+ if (nfapi_config->p7_vnf_address_ipv6.tl.tag) {
+ char addr6[INET6_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv6",
+ "%s",
+ nfapi_config->p7_vnf_address_ipv6.tl.tag,
+ inet_ntop(AF_INET6, nfapi_config->p7_vnf_address_ipv6.address, addr6, sizeof(addr6)));
+ }
+ INDENTED_TLV_FORMAT_PRINT("P7 VNF Port", "%d", nfapi_config->p7_vnf_port);
+
+ if (nfapi_config->p7_pnf_address_ipv4.tl.tag) {
+ char ip_str[INET_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv4",
+ "%s",
+ nfapi_config->p7_pnf_address_ipv4.tl.tag,
+ inet_ntop(AF_INET, nfapi_config->p7_pnf_address_ipv4.address, ip_str, sizeof(ip_str)));
+ }
+ if (nfapi_config->p7_pnf_address_ipv6.tl.tag) {
+ char addr6[INET6_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv6",
+ "%s",
+ nfapi_config->p7_pnf_address_ipv6.tl.tag,
+ inet_ntop(AF_INET6, nfapi_config->p7_pnf_address_ipv6.address, addr6, sizeof(addr6)));
+ }
+ INDENTED_TLV_FORMAT_PRINT("P7 PNF Port", "%d", nfapi_config->p7_pnf_port);
+ INDENTED_TLV_FORMAT_PRINT("Timing Window", "%d", nfapi_config->timing_window);
+ INDENTED_TLV_FORMAT_PRINT("Timing Info Mode", "%d", nfapi_config->timing_info_mode);
+ INDENTED_TLV_FORMAT_PRINT("Timing Info Period", "%d", nfapi_config->timing_info_period);
+ INDENTED_TLV_FORMAT_PRINT("DL_TTI Timing Offset", "%d", nfapi_config->dl_tti_timing_offset);
+ INDENTED_TLV_FORMAT_PRINT("UL_TTI Timing Offset", "%d", nfapi_config->ul_tti_timing_offset);
+ INDENTED_TLV_FORMAT_PRINT("UL_DCI Timing Offset", "%d", nfapi_config->ul_dci_timing_offset);
+ INDENTED_TLV_FORMAT_PRINT("TX_DATA Timing Offset", "%d", nfapi_config->tx_data_timing_offset);
depth--;
}
void dump_config_request(const nfapi_nr_config_request_scf_t *msg)
{
int depth = 0;
- dump_p5_message_header(&msg->header,depth);
+ dump_p5_message_header(&msg->header, depth);
depth++;
INDENTED_PRINTF("Number of TLVs = 0x%02x\n", msg->num_tlv);
/* dump all TLVs from each table */
+ /* Carrier Config */
+ const nfapi_nr_carrier_config_t *carrier_config = &msg->carrier_config;
+ INDENTED_TLV_PRINT("DL Bandwidth", carrier_config->dl_bandwidth);
+ INDENTED_TLV_PRINT("DL Frequency", carrier_config->dl_frequency);
+ INDENTED_PRINTF("(0x%04x) DL K0 = ", NFAPI_NR_CONFIG_DL_K0_TAG);
+ for (int i = 0; i < 5; i++) {
+ printf("%d ", carrier_config->dl_k0[i].value);
+ }
+ printf("\n");
+ INDENTED_PRINTF("(0x%04x) DL Grid Size = ", NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG);
+ for (int i = 0; i < 5; i++) {
+ printf("%d ", carrier_config->dl_grid_size[i].value);
+ }
+ printf("\n");
+ INDENTED_TLV_PRINT("Num TX Antennas", carrier_config->num_tx_ant);
+ INDENTED_TLV_PRINT("UL Bandwidth", carrier_config->uplink_bandwidth);
+ INDENTED_TLV_PRINT("UL Frequency", carrier_config->uplink_frequency);
+ INDENTED_PRINTF("(0x%04x) UL K0 = ", NFAPI_NR_CONFIG_UL_K0_TAG);
+ for (int i = 0; i < 5; i++) {
+ printf("%d ", carrier_config->ul_k0[i].value);
+ }
+ printf("\n");
+ INDENTED_PRINTF("(0x%04x) UL Grid Size = ", NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG);
+ for (int i = 0; i < 5; i++) {
+ printf("%d ", carrier_config->ul_grid_size[i].value);
+ }
+ printf("\n");
+ INDENTED_TLV_PRINT("Num RX Antennas", carrier_config->num_rx_ant);
+ INDENTED_TLV_PRINT("Frequency Shift 7p5KHz", carrier_config->frequency_shift_7p5khz);
+ /* Cell Config */
+ const nfapi_nr_cell_config_t *cell_config = &msg->cell_config;
+ INDENTED_TLV_PRINT("Physical Cell ID", cell_config->phy_cell_id);
+ INDENTED_TLV_PRINT("Frame Duplex Type", cell_config->frame_duplex_type);
+ /* SSB Config */
+ const nfapi_nr_ssb_config_t *ssb_config = &msg->ssb_config;
+ INDENTED_TLV_PRINT("SSB Block Power", ssb_config->ss_pbch_power);
+ INDENTED_TLV_PRINT("BCH Payload", ssb_config->bch_payload);
+ INDENTED_TLV_PRINT("SCS Common", ssb_config->scs_common);
+ /* PRACH Config */
+ const nfapi_nr_prach_config_t *prach_config = &msg->prach_config;
+ INDENTED_TLV_PRINT("PRACH Sequence Length", prach_config->prach_sequence_length);
+ INDENTED_TLV_PRINT("PRACH Subcarrier Spacing", prach_config->prach_sub_c_spacing);
+ INDENTED_TLV_PRINT("Restricted Set Config", prach_config->restricted_set_config);
+ INDENTED_TLV_PRINT("Num PRACH FD Occasions", prach_config->num_prach_fd_occasions);
+ INDENTED_TLV_PRINT("PRACH Config Index", prach_config->prach_ConfigurationIndex);
+ depth++;
+ for (int i = 0; i < prach_config->num_prach_fd_occasions.value; i++) {
+ const nfapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &(prach_config->num_prach_fd_occasions_list[i]);
+ INDENTED_TLV_PRINT("PRACH Root Sequence Index", prach_fd_occasion->prach_root_sequence_index);
+ INDENTED_TLV_PRINT("Num Root Sequences", prach_fd_occasion->num_root_sequences);
+ INDENTED_TLV_PRINT("K1", prach_fd_occasion->k1);
+ INDENTED_TLV_PRINT("PRACH Zero CorrelationZone Config", prach_fd_occasion->prach_zero_corr_conf);
+ INDENTED_TLV_PRINT("Num Unused Root Sequences", prach_fd_occasion->num_unused_root_sequences);
+ depth++;
+ for (int k = 0; k < prach_fd_occasion->num_unused_root_sequences.value; k++) {
+ INDENTED_TLV_PRINT("Unused Root Sequence", prach_fd_occasion->unused_root_sequences_list[k]);
+ }
+ depth--;
+ }
depth--;
+ INDENTED_TLV_PRINT("SSB Per RACH", prach_config->ssb_per_rach);
+ INDENTED_TLV_PRINT("PRACH Multiple Carriers in a Band", prach_config->prach_multiple_carriers_in_a_band);
+ /* SSB Table */
+ const nfapi_nr_ssb_table_t *ssb_table = &msg->ssb_table;
+ INDENTED_TLV_PRINT("SSB Offset PointA", ssb_table->ssb_offset_point_a);
+ INDENTED_TLV_PRINT("Beta PSS", ssb_table->beta_pss);
+ INDENTED_TLV_PRINT("SSB Period", ssb_table->ssb_period);
+ INDENTED_TLV_PRINT("SSB Subcarrier Offset", ssb_table->ssb_subcarrier_offset);
+ INDENTED_TLV_PRINT("MIB", ssb_table->MIB);
+
+ INDENTED_PRINTF("SSB Mask:\n");
+ depth++;
+ for (int i = 0; i < 2; i++) {
+ INDENTED_TLV_PRINT("SSB Mask", ssb_table->ssb_mask_list[i].ssb_mask);
+ }
+ depth--;
+ INDENTED_PRINTF("Beam ID:\n");
+ depth++;
+ for (int i = 0; i < 64; i++) {
+ INDENTED_TLV_PRINT("Beam ID", ssb_table->ssb_beam_id_list[i].beam_id);
+ }
+ depth--;
+ INDENTED_TLV_PRINT("ssPBCH Multiple Carriers in a Band", ssb_table->ss_pbch_multiple_carriers_in_a_band);
+ INDENTED_TLV_PRINT("Multiple Cells ssPBCH in a Carrier", ssb_table->multiple_cells_ss_pbch_in_a_carrier);
+ /* TDD Table */
+ const nfapi_nr_tdd_table_t *tdd_table = &msg->tdd_table;
+ if (cell_config->frame_duplex_type.value == 1 /* TDD */) {
+ INDENTED_TLV_PRINT("TDD Period", tdd_table->tdd_period);
+ const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+ // Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
+ uint8_t cyclicprefix = 1;
+ // 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
+ uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
+ INDENTED_PRINTF("Slot Config:\n");
+ depth++;
+ for (int i = 0; i < slotsperframe[ssb_config->scs_common.value]; i++) {
+ for (int k = 0; k < number_of_symbols_per_slot; k++) {
+ const uint8_t slot_type = tdd_table->max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config.value;
+ const char *slot_dir = slot_type == 0 ? "DL" : slot_type == 1 ? "UL" : "S";
+ INDENTED_GENERIC_PRINT("(0x%04x) Slot Config",
+ "%d (%s)",
+ tdd_table->max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config.tl.tag,
+ slot_type,
+ slot_dir);
+ }
+ }
+ depth--;
+ }
+ /* Measurement Config */
+ const nfapi_nr_measurement_config_t *measurement_config = &msg->measurement_config;
+ INDENTED_TLV_PRINT("RSSI Measurement", measurement_config->rssi_measurement);
+ /* Beamforming Table */
+ const nfapi_nr_dbt_pdu_t *dbt_config = &msg->dbt_config;
+ INDENTED_PRINTF("Digital Beam Table\n");
+ depth++;
+ INDENTED_GENERIC_PRINT("Num Digital Beams", "%d", dbt_config->num_dig_beams);
+ INDENTED_GENERIC_PRINT("Num TX RUs", "%d", dbt_config->num_txrus);
+ depth++;
+ for (int i = 0; i < dbt_config->num_dig_beams; i++) {
+ const nfapi_nr_dig_beam_t *dig_beam = &dbt_config->dig_beam_list[i];
+ INDENTED_GENERIC_PRINT("Beam IDX", "%d", dig_beam->beam_idx);
+ depth++;
+ for (int k = 0; k < dbt_config->num_txrus; k++) {
+ const nfapi_nr_txru_t *tx_ru = &dig_beam->txru_list[k];
+ INDENTED_GENERIC_PRINT("Dig Beam Weight Real", "0x%02x", tx_ru->dig_beam_weight_Re);
+ INDENTED_GENERIC_PRINT("Dig Beam Weight Imaginary", "0x%02x", tx_ru->dig_beam_weight_Im);
+ }
+ depth--;
+ }
+ depth--;
+ depth--;
+
+ /* Precoding Table */
+ const nfapi_nr_pm_list_t *pmi_list = &msg->pmi_list;
+ INDENTED_PRINTF("Precoding Matrix Table\n");
+ depth++;
+ INDENTED_GENERIC_PRINT("Num Precoding Tables", "%d", pmi_list->num_pm_idx);
+ depth++;
+ for (int i = 0; i < pmi_list->num_pm_idx; i++) {
+ const nfapi_nr_pm_pdu_t *pm_pdu = &pmi_list->pmi_pdu[i];
+
+ INDENTED_GENERIC_PRINT("Precoding Matrix IDX", "0x%02x", pm_pdu->pm_idx);
+ INDENTED_GENERIC_PRINT("Number of Layers", "%d", pm_pdu->numLayers);
+ INDENTED_GENERIC_PRINT("Number of Antenna Ports", "%d", pm_pdu->num_ant_ports);
+ depth++;
+ for (int k = 0; k < pm_pdu->numLayers; k++) {
+ for (int l = 0; l < pm_pdu->num_ant_ports; l++) {
+ const nfapi_nr_pm_weights_t *pm_weights = &pm_pdu->weights[k][l];
+ INDENTED_GENERIC_PRINT("Dig Beam Weight Real", "0x%02x", pm_weights->precoder_weight_Re);
+ INDENTED_GENERIC_PRINT("Dig Beam Weight Imaginary", "0x%02x", pm_weights->precoder_weight_Im);
+ }
+ }
+ depth--;
+ }
+ depth--;
+ depth--;
+ /* nFAPI Config */
+ const nfapi_nr_nfapi_t *nfapi_config = &msg->nfapi_config;
+ if (nfapi_config->p7_vnf_address_ipv4.tl.tag) {
+ char ip_str[INET_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv4",
+ "%s",
+ nfapi_config->p7_vnf_address_ipv4.tl.tag,
+ inet_ntop(AF_INET, nfapi_config->p7_vnf_address_ipv4.address, ip_str, sizeof(ip_str)));
+ }
+ if (nfapi_config->p7_vnf_address_ipv6.tl.tag) {
+ char addr6[INET6_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv6",
+ "%s",
+ nfapi_config->p7_vnf_address_ipv6.tl.tag,
+ inet_ntop(AF_INET6, nfapi_config->p7_vnf_address_ipv6.address, addr6, sizeof(addr6)));
+ }
+ INDENTED_TLV_FORMAT_PRINT("P7 VNF Port", "%d", nfapi_config->p7_vnf_port);
+
+ if (nfapi_config->p7_pnf_address_ipv4.tl.tag) {
+ char ip_str[INET_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv4",
+ "%s",
+ nfapi_config->p7_pnf_address_ipv4.tl.tag,
+ inet_ntop(AF_INET, nfapi_config->p7_pnf_address_ipv4.address, ip_str, sizeof(ip_str)));
+ }
+ if (nfapi_config->p7_pnf_address_ipv6.tl.tag) {
+ char addr6[INET6_ADDRSTRLEN];
+ INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv6",
+ "%s",
+ nfapi_config->p7_pnf_address_ipv6.tl.tag,
+ inet_ntop(AF_INET6, nfapi_config->p7_pnf_address_ipv6.address, addr6, sizeof(addr6)));
+ }
+ INDENTED_TLV_FORMAT_PRINT("P7 PNF Port", "%d", nfapi_config->p7_pnf_port);
+ INDENTED_TLV_FORMAT_PRINT("Timing Window", "%d", nfapi_config->timing_window);
+ INDENTED_TLV_FORMAT_PRINT("Timing Info Mode", "%d", nfapi_config->timing_info_mode);
+ INDENTED_TLV_FORMAT_PRINT("Timing Info Period", "%d", nfapi_config->timing_info_period);
+ INDENTED_TLV_FORMAT_PRINT("DL_TTI Timing Offset", "%d", nfapi_config->dl_tti_timing_offset);
+ INDENTED_TLV_FORMAT_PRINT("UL_TTI Timing Offset", "%d", nfapi_config->ul_tti_timing_offset);
+ INDENTED_TLV_FORMAT_PRINT("UL_DCI Timing Offset", "%d", nfapi_config->ul_dci_timing_offset);
+ INDENTED_TLV_FORMAT_PRINT("TX_DATA Timing Offset", "%d", nfapi_config->tx_data_timing_offset);
+ /* Beamforming VE */
+ const nfapi_nr_analog_beamforming_ve_t *analog_beamforming_ve = &msg->analog_beamforming_ve;
+ INDENTED_TLV_FORMAT_PRINT("Num Beams per Period", "%d", analog_beamforming_ve->num_beams_period_vendor_ext);
+ INDENTED_TLV_PRINT("Analog Beamforming VE", analog_beamforming_ve->analog_bf_vendor_ext);
+ /* Vendor Extension */
+ if (msg->vendor_extension) {
+ const nfapi_tl_t *vendor_extension = (nfapi_tl_t *)&msg->vendor_extension;
+ switch (vendor_extension->tag) {
+ case VENDOR_EXT_TLV_1_TAG: {
+ vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)vendor_extension;
+ INDENTED_PRINTF("(0x%04x) Vendor extension = %d 0x%02x\n", ve->tl.tag, ve->tl.length, ve->dummy);
+ } break;
+ case VENDOR_EXT_TLV_2_TAG: {
+ vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)vendor_extension;
+ INDENTED_PRINTF("(0x%04x) Vendor extension = %d 0x%02x\n", ve->tl.tag, ve->tl.length, ve->dummy);
+ } break;
+ default:
+ break;
+ }
+ }
+
+ depth--;
+}
+
+static void dump_generic_tlv(const nfapi_nr_generic_tlv_scf_t* tlv, int depth)
+{
+ INDENTED_PRINTF("TLV tag 0x%02x , Length 0x%02x , Value ", tlv->tl.tag, tlv->tl.length);
+ switch (tlv->tl.length) {
+ case UINT_8:
+ printf("0x%x\n", tlv->value.u8);
+ break;
+ case UINT_16:
+ printf("0x%02x\n", tlv->value.u16);
+ break;
+ case UINT_32:
+ printf("0x%04x\n", tlv->value.u32);
+ break;
+ case ARRAY_UINT_16:
+ for (int i = 0; i< 5 ; i++) {
+ printf("0x%04x ", tlv->value.array_u16[i]);
+ }
+ printf("\n");
+ break;
+ default:
+ printf("unknown length %d\n", tlv->tl.length);
+ DevAssert(1 == 0);
+ break;
+ }
}
void dump_config_response(const nfapi_nr_config_response_scf_t *msg)
@@ -1016,6 +1423,25 @@ void dump_config_response(const nfapi_nr_config_response_scf_t *msg)
msg->num_invalid_tlvs_configured_in_running);
INDENTED_PRINTF("Number of Missing TLVs = 0x%02x\n", msg->num_missing_tlvs);
/* dump all TLVs from each table */
+ INDENTED_PRINTF("Invalid or Unsupported TLVs (%d) :\n",msg->num_invalid_tlvs);
+ for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
+ dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
+ }
+
+ INDENTED_PRINTF("TLVs that can only be configured in IDLE (%d):\n", msg->num_invalid_tlvs_configured_in_idle);
+ for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
+ dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
+ }
+
+ INDENTED_PRINTF("TLVs that can only be configured in RUNNING (%d):\n",msg->num_invalid_tlvs_configured_in_running);
+ for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
+ dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
+ }
+
+ INDENTED_PRINTF("Missing TLVs (%d):\n",msg->num_missing_tlvs);
+ for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
+ dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
+ }
depth--;
}
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
index 9939a6f535..fb645707ad 100644
--- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
@@ -859,9 +859,7 @@ bool eq_rach_indication(const nfapi_nr_rach_indication_t *a, const nfapi_nr_rach
void free_dl_tti_request(nfapi_nr_dl_tti_request_t *msg)
{
- if (msg->vendor_extension) {
- free(msg->vendor_extension);
- }
+ free(msg->vendor_extension);
}
void free_ul_tti_request(nfapi_nr_ul_tti_request_t *msg)
@@ -907,9 +905,7 @@ void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg)
if (msg->number_of_pdus > 0) {
for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
nfapi_nr_rx_data_pdu_t *rx_pdu = &msg->pdu_list[pdu_idx];
- if (rx_pdu->pdu) {
- free(rx_pdu->pdu);
- }
+ free(rx_pdu->pdu);
}
free(msg->pdu_list);
}
@@ -917,99 +913,75 @@ void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg)
void free_crc_indication(nfapi_nr_crc_indication_t *msg)
{
- if (msg->crc_list) {
- for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
- nfapi_nr_crc_t *crc = &msg->crc_list[crc_idx];
- if (crc->cb_crc_status) {
- free(crc->cb_crc_status);
- }
- }
- free(msg->crc_list);
+ for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
+ nfapi_nr_crc_t *crc = &msg->crc_list[crc_idx];
+ free(crc->cb_crc_status);
}
+ free(msg->crc_list);
}
void free_uci_indication(nfapi_nr_uci_indication_t *msg)
{
- if (msg->uci_list) {
- for (int pdu_idx = 0; pdu_idx < msg->num_ucis; ++pdu_idx) {
- nfapi_nr_uci_t *uci_pdu = &msg->uci_list[pdu_idx];
- switch (uci_pdu->pdu_type) {
- case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
- nfapi_nr_uci_pusch_pdu_t *pdu = &uci_pdu->pusch_pdu;
- // Bit 0 not used in PUSCH PDU
- // HARQ
- if ((pdu->pduBitmap >> 1) & 0x01) {
- if (pdu->harq.harq_payload) {
- free(pdu->harq.harq_payload);
- }
- }
- // CSI Part 1
- if ((pdu->pduBitmap >> 2) & 0x01) {
- if (pdu->csi_part1.csi_part1_payload) {
- free(pdu->csi_part1.csi_part1_payload);
- }
- }
- // CSI Part 2
- if ((pdu->pduBitmap >> 3) & 0x01) {
- if (pdu->csi_part2.csi_part2_payload) {
- free(pdu->csi_part2.csi_part2_payload);
- }
- }
- break;
+ for (int pdu_idx = 0; pdu_idx < msg->num_ucis; ++pdu_idx) {
+ nfapi_nr_uci_t *uci_pdu = &msg->uci_list[pdu_idx];
+ switch (uci_pdu->pdu_type) {
+ case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
+ nfapi_nr_uci_pusch_pdu_t *pdu = &uci_pdu->pusch_pdu;
+ // Bit 0 not used in PUSCH PDU
+ // HARQ
+ if ((pdu->pduBitmap >> 1) & 0x01) {
+ free(pdu->harq.harq_payload);
}
- case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
- // Nothing to free
- break;
+ // CSI Part 1
+ if ((pdu->pduBitmap >> 2) & 0x01) {
+ free(pdu->csi_part1.csi_part1_payload);
}
- case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
- nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu = &uci_pdu->pucch_pdu_format_2_3_4;
- // SR
- if (pdu->pduBitmap & 0x01) {
- if (pdu->sr.sr_payload) {
- free(pdu->sr.sr_payload);
- }
- }
- // HARQ
- if ((pdu->pduBitmap >> 1) & 0x01) {
- if (pdu->harq.harq_payload) {
- free(pdu->harq.harq_payload);
- }
- }
- // CSI Part 1
- if ((pdu->pduBitmap >> 2) & 0x01) {
- if (pdu->csi_part1.csi_part1_payload) {
- free(pdu->csi_part1.csi_part1_payload);
- }
- }
- // CSI Part 2
- if ((pdu->pduBitmap >> 3) & 0x01) {
- if (pdu->csi_part2.csi_part2_payload) {
- free(pdu->csi_part2.csi_part2_payload);
- }
- }
- break;
+ // CSI Part 2
+ if ((pdu->pduBitmap >> 3) & 0x01) {
+ free(pdu->csi_part2.csi_part2_payload);
}
- default:
- AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci_pdu->pdu_type);
- break;
+ break;
}
+ case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
+ // Nothing to free
+ break;
+ }
+ case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
+ nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu = &uci_pdu->pucch_pdu_format_2_3_4;
+ // SR
+ if (pdu->pduBitmap & 0x01) {
+ free(pdu->sr.sr_payload);
+ }
+ // HARQ
+ if ((pdu->pduBitmap >> 1) & 0x01) {
+ free(pdu->harq.harq_payload);
+ }
+ // CSI Part 1
+ if ((pdu->pduBitmap >> 2) & 0x01) {
+ free(pdu->csi_part1.csi_part1_payload);
+ }
+ // CSI Part 2
+ if ((pdu->pduBitmap >> 3) & 0x01) {
+ free(pdu->csi_part2.csi_part2_payload);
+ }
+ break;
+ }
+ default:
+ AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci_pdu->pdu_type);
+ break;
}
- free(msg->uci_list);
}
+ free(msg->uci_list);
}
void free_srs_indication(nfapi_nr_srs_indication_t *msg)
{
- if (msg->pdu_list) {
- free(msg->pdu_list);
- }
+ free(msg->pdu_list);
}
void free_rach_indication(nfapi_nr_rach_indication_t *msg)
{
- if (msg->pdu_list) {
- free(msg->pdu_list);
- }
+ free(msg->pdu_list);
}
static void copy_dl_tti_beamforming(const nfapi_nr_tx_precoding_and_beamforming_t *src,
@@ -2586,6 +2558,27 @@ void dump_ul_dci_request(const nfapi_nr_ul_dci_request_t *msg)
}
}
+static void dump_tx_data_request_tlv(const nfapi_nr_tx_data_request_tlv_t *tlv, int depth)
+{
+ INDENTED_PRINTF("Tag = %d\n", tlv->tag);
+ INDENTED_PRINTF("Length = %d\n", tlv->length);
+ INDENTED_PRINTF("Value = ");
+ switch (tlv->tag) {
+ case 0:
+ for (int i = 0; i < tlv->length; i++) {
+ printf("0x%02x ", ((uint8_t*)tlv->value.direct)[i]);
+ }
+ break;
+ case 1:
+ printf("%p", tlv->value.ptr);
+ break;
+ default:
+ printf( " Unknown tag value %d",tlv->tag);
+ break;
+ }
+ printf("\n");
+}
+
void dump_tx_data_request(const nfapi_nr_tx_data_request_t *msg)
{
int depth = 0;
@@ -2594,15 +2587,18 @@ void dump_tx_data_request(const nfapi_nr_tx_data_request_t *msg)
INDENTED_PRINTF("SFN = %d\n", msg->SFN);
INDENTED_PRINTF("Slot = %d\n", msg->Slot);
INDENTED_PRINTF("Number of PDUs = %d\n", msg->Number_of_PDUs);
+ depth++;
for (int i = 0; i < msg->Number_of_PDUs; i++) {
- depth++;
INDENTED_PRINTF("PDU #%d\n", i);
const nfapi_nr_pdu_t *pdu = &msg->pdu_list[i];
INDENTED_PRINTF("PDU Length = 0x%02x\n", pdu->PDU_length);
INDENTED_PRINTF("PDU Index = 0x%02x\n", pdu->PDU_index);
INDENTED_PRINTF("numTLV = 0x%02x\n", pdu->num_TLV);
+ for (int tlv_idx = 0; tlv_idx < pdu->num_TLV; tlv_idx++) {
+ const nfapi_nr_tx_data_request_tlv_t *tlv = &pdu->TLVs[tlv_idx];
/* call to dump_tx_data_request_tlv */
- depth--;
+ dump_tx_data_request_tlv(tlv, depth + 1);
+ }
}
}
@@ -2664,6 +2660,134 @@ void dump_crc_indication(const nfapi_nr_crc_indication_t *msg)
}
}
+static void dump_harq_2_3_4(const nfapi_nr_harq_pdu_2_3_4_t *harq, int depth)
+{
+ INDENTED_PRINTF("HARQ CRC = %01x\n", harq->harq_crc);
+ INDENTED_PRINTF("HARQ Bit Length = %d\n", harq->harq_bit_len);
+ INDENTED_PRINTF("HARQ Payload = ");
+ for (int i = 0; i < harq->harq_bit_len / 8 + 1; i++) {
+ printf("%x ", harq->harq_payload[i]);
+ }
+ printf("\n");
+}
+
+static void dump_csi_part_1(const nfapi_nr_csi_part1_pdu_t *csi, int depth)
+{
+ INDENTED_PRINTF("CSI Part 1 CRC = %01x\n", csi->csi_part1_crc);
+ INDENTED_PRINTF("CSI Part 1 Bit Length = %d\n", csi->csi_part1_bit_len);
+ INDENTED_PRINTF("CSI Part 1 Payload = ");
+ for (int i = 0; i < csi->csi_part1_bit_len / 8 + 1; i++) {
+ printf("%x ", csi->csi_part1_payload[i]);
+ }
+ printf("\n");
+}
+
+static void dump_csi_part_2(const nfapi_nr_csi_part2_pdu_t *csi, int depth)
+{
+ INDENTED_PRINTF("CSI Part 1 CRC = %01x\n", csi->csi_part2_crc);
+ INDENTED_PRINTF("CSI Part 1 Bit Length = %d\n", csi->csi_part2_bit_len);
+ INDENTED_PRINTF("CSI Part 1 Payload = ");
+ for (int i = 0; i < csi->csi_part2_bit_len / 8 + 1; i++) {
+ printf("%x ", csi->csi_part2_payload[i]);
+ }
+ printf("\n");
+}
+
+static void dump_uci_PUSCH_PDU(const nfapi_nr_uci_pusch_pdu_t *pdu, int depth)
+{
+ INDENTED_PRINTF("PDU Bitmap = 0x%01x\n", pdu->pduBitmap);
+ INDENTED_PRINTF("Handle = 0x%04x\n", pdu->handle);
+ INDENTED_PRINTF("RNTI = 0x%02x\n", pdu->rnti);
+ INDENTED_PRINTF("UL_CQI = 0x%02x\n", pdu->ul_cqi);
+ INDENTED_PRINTF("Timing Advance = 0x%02x\n", pdu->timing_advance);
+ INDENTED_PRINTF("RSSI = 0x%02x\n", pdu->rssi);
+ // HARQ payload, CSI Part 1 and 2 are conditionally allocated
+ if ((pdu->pduBitmap >> 1) & 0x01) {
+ INDENTED_PRINTF("HARQ Information\n");
+ dump_harq_2_3_4(&pdu->harq, depth + 1);
+ }
+ if ((pdu->pduBitmap >> 2) & 0x01) {
+ INDENTED_PRINTF("CSI Part 1\n");
+ dump_csi_part_1(&pdu->csi_part1, depth + 1);
+ }
+ if ((pdu->pduBitmap >> 3) & 0x01) {
+ INDENTED_PRINTF("CSI Part 1\n");
+ dump_csi_part_2(&pdu->csi_part2, depth + 1);
+ }
+}
+
+static void dump_sr_0_1(const nfapi_nr_sr_pdu_0_1_t *sr, int depth)
+{
+ INDENTED_PRINTF("SR Indication = 0x%02x\n", sr->sr_indication);
+ INDENTED_PRINTF("SR Confidence Level = 0x%02x\n", sr->sr_confidence_level);
+}
+
+static void dump_harq_0_1(const nfapi_nr_harq_pdu_0_1_t *harq, int depth)
+{
+ INDENTED_PRINTF("Num HARQ = 0x%02x\n", harq->num_harq);
+ INDENTED_PRINTF("HARQ Confidence Level = 0x%02x\n", harq->harq_confidence_level);
+ depth++;
+ for (int i = 0; i < harq->num_harq; i++) {
+ INDENTED_PRINTF("HARQ Value[%d] : 0x%02x \n", i, harq->harq_list[i].harq_value);
+ }
+}
+
+static void dump_uci_PUCCH_0_1(const nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu, int depth)
+{
+ INDENTED_PRINTF("PDU Bitmap = 0x%01x\n", pdu->pduBitmap);
+ INDENTED_PRINTF("Handle = 0x%04x\n", pdu->handle);
+ INDENTED_PRINTF("RNTI = 0x%02x\n", pdu->rnti);
+ INDENTED_PRINTF("PUCCH Format = 0x%02x\n", pdu->pucch_format);
+ INDENTED_PRINTF("UL_CQI = 0x%02x\n", pdu->ul_cqi);
+ INDENTED_PRINTF("Timing Advance = 0x%02x\n", pdu->timing_advance);
+ INDENTED_PRINTF("RSSI = 0x%02x\n", pdu->rssi);
+ if ((pdu->pduBitmap) & 0x01) {
+ INDENTED_PRINTF("SR Information\n");
+ dump_sr_0_1(&pdu->sr, depth + 1);
+ }
+ if ((pdu->pduBitmap >> 1) & 0x01) {
+ INDENTED_PRINTF("HARQ Information\n");
+ dump_harq_0_1(&pdu->harq, depth + 1);
+ }
+}
+
+static void dump_sr_2_3_4(const nfapi_nr_sr_pdu_2_3_4_t *sr, int depth)
+{
+ INDENTED_PRINTF("SR Bit Length = %d\n", sr->sr_bit_len);
+ INDENTED_PRINTF("SR Payload ");
+ for (int i = 0; i < sr->sr_bit_len / 8 + 1; i++) {
+ printf("%x ", sr->sr_payload[i]);
+ }
+ printf("\n");
+}
+
+static void dump_uci_PUCCH_2_3_4(const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu, int depth)
+{
+ INDENTED_PRINTF("PDU Bitmap = 0x%01x\n", pdu->pduBitmap);
+ INDENTED_PRINTF("Handle = 0x%04x\n", pdu->handle);
+ INDENTED_PRINTF("RNTI = 0x%02x\n", pdu->rnti);
+ INDENTED_PRINTF("PUCCH Format = 0x%02x\n", pdu->pucch_format);
+ INDENTED_PRINTF("UL_CQI = 0x%02x\n", pdu->ul_cqi);
+ INDENTED_PRINTF("Timing Advance = 0x%02x\n", pdu->timing_advance);
+ INDENTED_PRINTF("RSSI = 0x%02x\n", pdu->rssi);
+ // SR
+ if (pdu->pduBitmap & 0x01) {
+ dump_sr_2_3_4(&pdu->sr, depth + 1);
+ }
+ // HARQ
+ if ((pdu->pduBitmap >> 1) & 0x01) {
+ dump_harq_2_3_4(&pdu->harq, depth + 1);
+ }
+ // CSI Part 1
+ if ((pdu->pduBitmap >> 2) & 0x01) {
+ dump_csi_part_1(&pdu->csi_part1, depth + 1);
+ }
+ // CSI Part 2
+ if ((pdu->pduBitmap >> 3) & 0x01) {
+ dump_csi_part_2(&pdu->csi_part2, depth + 1);
+ }
+}
+
void dump_uci_indication(const nfapi_nr_uci_indication_t *msg)
{
int depth = 0;
@@ -2680,6 +2804,20 @@ void dump_uci_indication(const nfapi_nr_uci_indication_t *msg)
INDENTED_PRINTF("PDUType = 0x%02x\n", uci->pdu_type);
INDENTED_PRINTF("PDUSize = 0x%02x\n", uci->pdu_size);
/* call to dump_uci_indication__pdu */
+ switch (uci->pdu_type) {
+ case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+ dump_uci_PUSCH_PDU(&uci->pusch_pdu, depth + 1);
+ break;
+ case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+ dump_uci_PUCCH_0_1(&uci->pucch_pdu_format_0_1, depth + 1);
+ break;
+ case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+ dump_uci_PUCCH_2_3_4(&uci->pucch_pdu_format_2_3_4, depth + 1);
+ break;
+ default:
+ INDENTED_PRINTF("Unknown PDU type 0x%02x\n", uci->pdu_type);
+ break;
+ }
depth--;
}
}
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index b7e6577fa2..eb668f3e73 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -34,6 +34,7 @@
#define NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG 0xA002
#define NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG 0xA003
+
typedef struct {
uint16_t phy_id;
uint16_t message_id;
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 0533a76c6d..f213868328 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -328,6 +328,8 @@ typedef struct
#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028
#define NFAPI_NR_CONFIG_TDD_TABLE 0x1035
+#define NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG 0x1043 // This tag was added in version 5 of the SCF222 standard ( Table 3-50 of SCF222.10.05 )
+#define NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG 0x104B // This tag was added in version 6 of the SCF222 standard ( Table 3-52 of SCF222.10.06 )
//table 3-21
typedef struct
@@ -473,6 +475,11 @@ typedef struct {
nfapi_nr_dig_beam_t *dig_beam_list;
} nfapi_nr_dbt_pdu_t;
+typedef struct {
+ nfapi_tl_t tl;
+ nfapi_nr_dbt_pdu_t value;
+} nfapi_nr_dbt_tlv_ve_t;
+
// Table 3–62 Precoding matrix (PM) PDU (v.222.10.04)
typedef struct {
int16_t precoder_weight_Re;
@@ -491,7 +498,12 @@ typedef struct {
typedef struct {
uint16_t num_pm_idx;
nfapi_nr_pm_pdu_t *pmi_pdu;
-} nfapi_nr_pm_list_t;
+} nfapi_nr_pm_list_t; // This corresponds to Table 3-69 of SCF222.10.06, which introduces the num_pm_idx parameter
+
+typedef struct {
+ nfapi_tl_t tl;
+ nfapi_nr_pm_list_t value;
+} nfapi_nr_pm_tlv_ve_t;
typedef struct {
nfapi_uint8_tlv_t num_beams_period_vendor_ext;
diff --git a/nfapi/tests/p5/nr_fapi_config_request_test.c b/nfapi/tests/p5/nr_fapi_config_request_test.c
index 93ff5b5f3a..82ce60ca3b 100644
--- a/nfapi/tests/p5/nr_fapi_config_request_test.c
+++ b/nfapi/tests/p5/nr_fapi_config_request_test.c
@@ -206,6 +206,47 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap
FILL_TLV(nfapi_resp->measurement_config.rssi_measurement, NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, rand8());
nfapi_resp->num_tlv++;
+ uint16_t nb_beams = rand16_range(1, 15);
+ uint16_t nb_tx = rand16_range(1, 15);
+ nfapi_resp->dbt_config.num_dig_beams = nb_beams;
+ if (nfapi_resp->dbt_config.num_dig_beams > 0) {
+ nfapi_resp->dbt_config.num_txrus = nb_tx;
+ nfapi_resp->dbt_config.dig_beam_list = calloc(nb_beams , sizeof(*nfapi_resp->dbt_config.dig_beam_list));
+ for (int i = 0; i < nb_beams; i++) {
+ nfapi_nr_dig_beam_t *beam = &nfapi_resp->dbt_config.dig_beam_list[i];
+ beam->beam_idx = i;
+ beam->txru_list = calloc(nb_tx , sizeof(*beam->txru_list));
+ for (int j = 0; j < nb_tx; j++) {
+ nfapi_nr_txru_t *txru = &beam->txru_list[j];
+ txru->dig_beam_weight_Re = rand16_range(1, 0xffff);
+ txru->dig_beam_weight_Im = rand16_range(1, 0xffff);
+ }
+ }
+ nfapi_resp->num_tlv++;
+ }
+
+ nfapi_nr_pm_list_t *pm_list = &nfapi_resp->pmi_list;
+ const uint16_t num_layers = rand16_range(1, 4);
+ const uint16_t num_ant_ports = rand16_range(1, 4);
+ pm_list->num_pm_idx = rand16_range(1, 4);
+ if (nfapi_resp->pmi_list.num_pm_idx > 0) {
+ pm_list->pmi_pdu = calloc(pm_list->num_pm_idx, sizeof(*pm_list->pmi_pdu));
+ for (int i = 0; i < pm_list->num_pm_idx; i++) {
+ nfapi_nr_pm_pdu_t *pmi_pdu = &pm_list->pmi_pdu[i];
+ pmi_pdu->pm_idx = i+1;
+ pmi_pdu->numLayers = num_layers;
+ pmi_pdu->num_ant_ports = num_ant_ports;
+ for (int j = 0; j < num_layers; j++) {
+ for (int k = 0; k < num_ant_ports; k++) {
+ nfapi_nr_pm_weights_t* pm_weight = &pmi_pdu->weights[j][k];
+ pm_weight->precoder_weight_Re = (int16_t)rand16_range(1, 0xffff);
+ pm_weight->precoder_weight_Im = (int16_t)rand16_range(1, 0xffff);
+ }
+ }
+ }
+ nfapi_resp->num_tlv++;
+ }
+
nfapi_resp->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
nfapi_resp->nfapi_config.p7_vnf_address_ipv4.address[i] = rand8();
@@ -221,6 +262,21 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap
FILL_TLV(nfapi_resp->nfapi_config.p7_vnf_port, NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, rand16());
nfapi_resp->num_tlv++;
+ nfapi_resp->nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG;
+ for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
+ nfapi_resp->nfapi_config.p7_pnf_address_ipv4.address[i] = rand8();
+ }
+ nfapi_resp->num_tlv++;
+
+ nfapi_resp->nfapi_config.p7_pnf_address_ipv6.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG;
+ for (int i = 0; i < NFAPI_IPV6_ADDRESS_LENGTH; ++i) {
+ nfapi_resp->nfapi_config.p7_pnf_address_ipv6.address[i] = rand8();
+ }
+ nfapi_resp->num_tlv++;
+
+ FILL_TLV(nfapi_resp->nfapi_config.p7_pnf_port, NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, rand16());
+ nfapi_resp->num_tlv++;
+
FILL_TLV(nfapi_resp->nfapi_config.timing_window, NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, rand8());
nfapi_resp->num_tlv++;
diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h
index 67aadb2869..df295e2011 100644
--- a/openair2/COMMON/rrc_messages_def.h
+++ b/openair2/COMMON/rrc_messages_def.h
@@ -88,6 +88,7 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr
// UE: RRC -> MAC messages
MESSAGE_DEF(NR_MAC_RRC_CONFIG_RESET, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_reset_t, nr_mac_rrc_config_reset)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_CG, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_cg_t, nr_mac_rrc_config_cg)
+MESSAGE_DEF(NR_MAC_RRC_RESUME_RB, MESSAGE_PRIORITY_MED, nr_mac_rrc_resume_rb_t, nr_mac_rrc_resume_rb)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_MIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_mib_t, nr_mac_rrc_config_mib)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_SIB1, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_sib1_t, nr_mac_rrc_config_sib1)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_OTHER_SIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_other_sib_t, nr_mac_rrc_config_other_sib)
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index a3db7ebba6..094fd0fa40 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -107,6 +107,7 @@
#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req
#define NR_MAC_RRC_CONFIG_RESET(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_reset
#define NR_MAC_RRC_CONFIG_CG(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_cg
+#define NR_MAC_RRC_RESUME_RB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_resume_rb
#define NR_MAC_RRC_CONFIG_MIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_mib
#define NR_MAC_RRC_CONFIG_SIB1(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_sib1
#define NR_MAC_RRC_CONFIG_OTHER_SIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_other_sib
@@ -470,6 +471,11 @@ typedef struct {
int ue_id;
} RlcMaxRtxIndication;
+typedef struct {
+ bool is_srb;
+ int rb_id;
+} nr_mac_rrc_resume_rb_t;
+
typedef struct {
NR_ReestablishmentCause_t cause;
} nr_mac_rrc_config_reset_t;
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index c7b74be8b0..44774342e5 100644
--- a/openair2/GNB_APP/RRC_nr_paramsvalues.h
+++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h
@@ -124,6 +124,7 @@
#define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2 "nrofUplinkSymbols2"
#define GNB_CONFIG_STRING_SSPBCHBLOCKPOWER "ssPBCH_BlockPower"
+#define GNB_CONFIG_STRING_ULSYNCVALIDITYDURATION "ntn-UlSyncValidityDuration-r17"
#define GNB_CONFIG_STRING_CELLSPECIFICKOFFSET "cellSpecificKoffset_r17"
#define GNB_CONFIG_STRING_EPHEMERIS_POSITION_X "positionX-r17"
#define GNB_CONFIG_STRING_EPHEMERIS_POSITION_Y "positionY-r17"
@@ -250,6 +251,7 @@
{GNB_CONFIG_STRING_NROFUPLINKSLOTS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,.defint64val=2,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols,.defint64val=4,TYPE_INT64,0},\
{GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,.i64ptr=&scc->ss_PBCH_BlockPower,.defint64val=20,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULSYNCVALIDITYDURATION,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17,.defint64val=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_CELLSPECIFICKOFFSET,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17,.defint64val=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_EPHEMERIS_POSITION_X,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_EPHEMERIS_POSITION_Y,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionY_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 0ddd097ca6..36ac8b6b1f 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -216,6 +216,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc)
scc->ext2 = calloc_or_fail(1, sizeof(*scc->ext2));
scc->ext2->ntn_Config_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17));
+ scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17 = calloc_or_fail(1, sizeof(long));
scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17));
scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17));
@@ -465,6 +466,40 @@ static void fix_tdd_pattern(NR_ServingCellConfigCommon_t *scc)
}
}
+static int get_ulsyncvalidityduration_enum_value(int val)
+{
+ int retval = -1;
+
+ switch (val) {
+ case 5:
+ case 10:
+ case 15:
+ case 20:
+ case 25:
+ case 30:
+ case 35:
+ case 40:
+ case 45:
+ case 50:
+ case 55:
+ retval = val / 5 - 1;
+ break;
+ case 60:
+ case 120:
+ case 180:
+ case 240:
+ retval = 10 + val / 60;
+ break;
+ case 900:
+ retval = 15;
+ break;
+ default:
+ AssertFatal(1 == 0, "ulsyncvalidityDuration in SIB19 set to invalid value in Conf file\n");
+ break;
+ }
+ return retval;
+}
+
void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
{
scc->ssb_PositionsInBurst->present = get_ssb_len(scc);
@@ -572,6 +607,13 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
AssertFatal(*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon < 2,
"pucch_ResourceConfig should be 0 or 1 for now\n");
+ if (*scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17 == 0) {
+ free(scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17);
+ scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17 = NULL;
+ } else {
+ int val = get_ulsyncvalidityduration_enum_value(*scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17);
+ *scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17 = val;
+ }
if (*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 == 0) {
free(scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17);
scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = NULL;
@@ -596,8 +638,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = NULL;
}
- if (!scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 && !scc->ext2->ntn_Config_r17->ta_Info_r17
- && !scc->ext2->ntn_Config_r17->ephemerisInfo_r17) {
+ if (!scc->ext2->ntn_Config_r17->ntn_UlSyncValidityDuration_r17 &&
+ !scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 &&
+ !scc->ext2->ntn_Config_r17->ta_Info_r17 &&
+ !scc->ext2->ntn_Config_r17->ephemerisInfo_r17) {
free(scc->ext2->ntn_Config_r17);
free(scc->ext2);
scc->ext2 = NULL;
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index 3a5d5e5640..bfea78d540 100644
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -811,7 +811,7 @@ static uint32_t get_lc_bucket_size(long prioritisedBitRate, long bucketSizeDurat
}
// default configuration as per 38.331 section 9.2.1
-static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, NR_SRB_Identity_t srb_id)
+static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, int srb_id)
{
lc_info->lcid = srb_id;
lc_info->priority = srb_id == 2 ? 3 : 1;
@@ -822,12 +822,14 @@ static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, NR_SR
static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
nr_lcordered_info_t *lc_info,
NR_LogicalChannelConfig_t *mac_lc_config,
- NR_SRB_Identity_t srb_id)
+ nr_lcid_rb_t rb)
{
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info->lcid);
- if (srb_id > 0 && !mac_lc_config->ul_SpecificParameters) {
+ lc_info->rb = rb;
+ lc_info->rb_suspended = false;
+ if (rb.type == NR_LCID_SRB && !mac_lc_config->ul_SpecificParameters) {
// release configuration and reset to default
- set_default_logicalchannelconfig(lc_info, srb_id);
+ set_default_logicalchannelconfig(lc_info, rb.choice.srb_id);
// invalid LCGID to signal it is absent in the configuration
lc_sched_info->LCGID = NR_INVALID_LCGID;
return;
@@ -848,6 +850,25 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
nr_timer_start(bjt);
}
+static nr_lcid_rb_t configure_lcid_rb(NR_RLC_BearerConfig_t *rlc_bearer)
+{
+ nr_lcid_rb_t rb;
+ if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
+ rb.type = NR_LCID_SRB;
+ rb.choice.srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
+ return rb;
+ }
+
+ if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity) {
+ rb.type = NR_LCID_DRB;
+ rb.choice.drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
+ return rb;
+ }
+ LOG_E(NR_MAC, "Error. RLC should be linked to either DRB or SRB.\n");
+ rb.type = NR_LCID_NONE;
+ return rb;
+}
+
static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list)
@@ -870,6 +891,9 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
if (rlc_toadd_list) {
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
+ nr_lcid_rb_t rb = configure_lcid_rb(rlc_bearer);
+ if (rb.type == NR_LCID_NONE)
+ continue;
int lc_identity = rlc_bearer->logicalChannelIdentity;
NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
int j;
@@ -879,14 +903,9 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
}
if (j < mac->lc_ordered_list.count) {
LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity);
- if (mac_lc_config != NULL) {
- NR_SRB_Identity_t srb_id = 0;
- if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity)
- srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
- nr_configure_lc_config(mac, mac->lc_ordered_list.array[j], mac_lc_config, srb_id);
- }
- }
- else {
+ if (mac_lc_config != NULL)
+ nr_configure_lc_config(mac, mac->lc_ordered_list.array[j], mac_lc_config, rb);
+ } else {
/* setup of new LCID*/
nr_lcordered_info_t *lc_info = calloc(1, sizeof(*lc_info));
lc_info->lcid = lc_identity;
@@ -895,12 +914,12 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
if (mac_lc_config != NULL)
- nr_configure_lc_config(mac, lc_info, mac_lc_config, srb_id);
+ nr_configure_lc_config(mac, lc_info, mac_lc_config, rb);
else
set_default_logicalchannelconfig(lc_info, srb_id);
} else { /* DRB */
AssertFatal(mac_lc_config, "When establishing a DRB, LogicalChannelConfig should be mandatorily present\n");
- nr_configure_lc_config(mac, lc_info, mac_lc_config, 0);
+ nr_configure_lc_config(mac, lc_info, mac_lc_config, rb);
}
ASN_SEQUENCE_ADD(&mac->lc_ordered_list, lc_info);
}
@@ -1711,6 +1730,13 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
nr_ue_mac_default_configs(mac);
nr_ue_reset_sync_state(mac);
release_mac_configuration(mac, cause);
+ // suspend all RBs except SRB0
+ for (int j = 0; j < mac->lc_ordered_list.count; j++) {
+ nr_lcordered_info_t *lc = mac->lc_ordered_list.array[j];
+ if (lc->rb.type == NR_LCID_SRB && lc->rb.choice.srb_id == 0)
+ continue;
+ lc->rb_suspended = true;
+ }
// apply the timeAlignmentTimerCommon included in SIB1
configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->timeAlignmentTimerCommon, mac->current_UL_BWP->scs);
// new sync with old cell ID (re-establishment on the same cell)
@@ -1718,6 +1744,15 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
sync_req.ssb_bw_scan = false;
nr_ue_send_synch_request(mac, module_id, 0, &sync_req);
break;
+ case RRC_SETUP_REESTAB_RESUME:
+ release_mac_configuration(mac, cause);
+ nr_ue_mac_default_configs(mac);
+ break;
+ case UL_SYNC_LOST_T430_EXPIRED:
+ // TS 38.331 Section 5.2.2.6, TS 38.321 Section 5.2a
+ // Flush all HARQ buffers and Stop UL transmissions
+ handle_ulsync_loss(mac);
+ break;
default:
AssertFatal(false, "Invalid MAC reset cause %d\n", cause);
}
@@ -1725,6 +1760,29 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
AssertFatal(!ret, "mutex failed %d\n", ret);
}
+bool is_lcid_suspended(NR_UE_MAC_INST_t *mac, int lcid)
+{
+ for (int j = 0; j < mac->lc_ordered_list.count; j++) {
+ nr_lcordered_info_t *lc = mac->lc_ordered_list.array[j];
+ if (lc->lcid == lcid)
+ return lc->rb_suspended;
+ }
+ LOG_E(NR_MAC, "LCID %d not found in the MAC list\n", lcid);
+ return false;
+}
+
+void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id)
+{
+ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+ for (int j = 0; j < mac->lc_ordered_list.count; j++) {
+ nr_lcordered_info_t *lc = mac->lc_ordered_list.array[j];
+ if (is_srb && lc->rb.type == NR_LCID_SRB && lc->rb.choice.srb_id == rb_id)
+ lc->rb_suspended = false;
+ if (!is_srb && lc->rb.type == NR_LCID_DRB && lc->rb.choice.drb_id == rb_id)
+ lc->rb_suspended = false;
+ }
+}
+
static void configure_si_schedulingInfo(NR_UE_MAC_INST_t *mac,
NR_SI_SchedulingInfo_t *si_SchedulingInfo,
NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700)
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index b3ca280f86..dee2a30c08 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -196,7 +196,9 @@ typedef enum {
GO_TO_IDLE,
DETACH,
T300_EXPIRY,
- RE_ESTABLISHMENT
+ RE_ESTABLISHMENT,
+ RRC_SETUP_REESTAB_RESUME,
+ UL_SYNC_LOST_T430_EXPIRED,
} NR_UE_MAC_reset_cause_t;
typedef struct {
@@ -450,6 +452,8 @@ typedef struct nr_lcordered_info_s {
uint32_t bucket_size;
bool sr_DelayTimerApplied;
bool lc_SRMask;
+ nr_lcid_rb_t rb;
+ bool rb_suspended;
} nr_lcordered_info_t;
typedef struct {
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index b058f6e681..c8eab85462 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -67,13 +67,16 @@ void release_common_ss_cset(NR_BWP_PDCCH_t *pdcch);
\param gNB_index gNB index
\param sibs_mask sibs mask
\param pduP pointer to pdu
- \param pdu_length length of pdu */
+ \param pdu_length length of pdu
+ \param frame,slot Received TTI*/
void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac,
int cc_id,
unsigned int gNB_index,
uint8_t ack_nack,
uint8_t *pduP,
- uint32_t pdu_len);
+ uint32_t pdu_len,
+ int frame,
+ int slot);
void release_dl_BWP(NR_UE_MAC_INST_t *mac, int index);
void release_ul_BWP(NR_UE_MAC_INST_t *mac, int index);
@@ -93,7 +96,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si
struct position; /* forward declaration */
void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17, bool can_start_ra);
-
+void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id);
void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause);
/**\brief initialization NR UE MAC instance(s)*/
@@ -293,7 +296,7 @@ void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_c
uint32_t bwp_size,
uint32_t bwp_start);
-
+bool is_lcid_suspended(NR_UE_MAC_INST_t *mac, int lcid);
void nr_ra_contention_resolution_failed(NR_UE_MAC_INST_t *mac);
void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot);
void nr_ra_backoff_setting(RA_config_t *ra);
@@ -320,6 +323,7 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *pdcch_order);
void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac);
+void handle_ulsync_loss(NR_UE_MAC_INST_t *mac);
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
NR_PDSCH_Config_t *pdsch_Config,
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index 6a6c7633bf..e189d7dcf9 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -271,7 +271,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca
// in case of re-establishment we don't need to release initial BWP config common
int first_bwp_rel = 0; // first BWP to release
- if (cause == RE_ESTABLISHMENT) {
+ if (cause == RE_ESTABLISHMENT || cause == RRC_SETUP_REESTAB_RESUME) {
first_bwp_rel = 1;
// release dedicated BWP0 config
NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[0];
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 5d3102c07d..8a892557b2 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -305,11 +305,13 @@ void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac,
unsigned int gNB_index,
uint8_t ack_nack,
uint8_t *pduP,
- uint32_t pdu_len)
+ uint32_t pdu_len,
+ int frame,
+ int slot)
{
if(ack_nack) {
LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
- nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
+ nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, frame, slot, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
if (mac->get_sib1)
mac->get_sib1 = false;
for (int i = 0; i < MAX_SI_GROUPS; i++) {
@@ -325,7 +327,7 @@ void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac,
}
else {
LOG_E(NR_MAC, "Got NACK on NR-BCCH-DL-SCH-Message (%s)\n", mac->get_sib1 ? "SIB1" : "other SI");
- nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, NULL, 0);
+ nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, frame, slot, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, NULL, 0);
}
}
@@ -3734,7 +3736,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len);
bool ret;
- switch(rx_lcid){
+ switch (rx_lcid) {
// MAC CE
case DL_SCH_LCID_CCCH:
// MSG4 RRC Setup 38.331
@@ -3871,6 +3873,11 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
case 1 ... 32:
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
return;
+ // discard the received subPDU if RB is suspended
+ if (is_lcid_suspended(mac, rx_lcid)) {
+ LOG_W(NR_MAC, "Received PDU for a suspended RB, corresponding to LCID %d. Dropping it.\n", rx_lcid);
+ break;
+ }
LOG_D(NR_MAC, "%4d.%2d : DLSCH -> LCID %d %d bytes\n", frameP, slot, rx_lcid, mac_len);
nr_mac_rlc_data_ind(mac->ue_id, mac->ue_id, false, rx_lcid, (char *)(pduP + mac_subheader_len), mac_len);
break;
@@ -3878,8 +3885,8 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
LOG_W(MAC, "unknown lcid %02x\n", rx_lcid);
break;
}
- pduP += ( mac_subheader_len + mac_len );
- pdu_len -= ( mac_subheader_len + mac_len );
+ pduP += (mac_subheader_len + mac_len);
+ pdu_len -= (mac_subheader_len + mac_len);
if (pdu_len < 0)
LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", mac->ue_id, frameP, slot, pdu_len);
}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index b810bf8de6..2c37b21f5b 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -182,6 +182,27 @@ void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
// TODO not sure what to do here
}
+void handle_ulsync_loss(NR_UE_MAC_INST_t *mac)
+{
+ // flush all HARQ buffers for all Serving Cells
+ for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
+ memset(&mac->dl_harq_info[k], 0, sizeof(*mac->dl_harq_info));
+ memset(&mac->ul_harq_info[k], 0, sizeof(*mac->ul_harq_info));
+ mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
+ mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
+ }
+ // clear any configured downlink assignments and uplink grants;
+ if (mac->dl_config_request)
+ memset(mac->dl_config_request, 0, sizeof(*mac->dl_config_request));
+ if (mac->ul_config_request)
+ clear_ul_config_request(mac);
+
+ // Need to receive SIB19 again after loosing UL SYNC
+ mac->state = UE_RECEIVING_SIB;
+ // gNB needs to send PDCCH ORDER triggering RA after detecting ULSYNC LOSS
+ LOG_W(NR_MAC, "Wait for PDCCH ORDER, RACH needs to performed to obtain ULSYNC.\n");
+}
+
void update_mac_dl_timers(NR_UE_MAC_INST_t *mac)
{
bool ra_window_expired = nr_timer_tick(&mac->ra.response_window_timer);
@@ -1266,10 +1287,11 @@ static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP,
{
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
+ if (lc_info->rb_suspended)
+ continue;
int lcid = lc_info->lcid;
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid);
mac_rlc_status_resp_t rlc_status = nr_mac_rlc_status_ind(mac->ue_id, frameP, lcid);
-
if (rlc_status.bytes_in_buffer > 0) {
LOG_D(NR_MAC,
"[UE %d] LCID %d has %d bytes to transmit at sfn %d.%d\n",
@@ -2553,6 +2575,8 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
lcid_remain_buffer,
lcid);
+ if (is_lcid_suspended(mac, lcid))
+ return false;
if (mac_ce_p->end_for_tailer - mac_ce_p->cur_ptr < sizeof(NR_MAC_SUBHEADER_LONG))
// We can't add one byte after the header
return false;
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 8dfa57f92b..88c8d5d377 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -77,10 +77,10 @@ static uint64_t get_nr_rlc_current_time(void)
static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id)
{
AssertFatal(channel_id != 0, "LCID = 0 shouldn't be handled here\n");
- nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1];
- if (rb->type == NR_RLC_NONE)
+ nr_lcid_rb_t *rb = &ue->lcid2rb[channel_id - 1];
+ if (rb->type == NR_LCID_NONE)
return;
- if (rb->type == NR_RLC_SRB) {
+ if (rb->type == NR_LCID_SRB) {
int id = rb->choice.srb_id - 1;
AssertFatal(id >= 0, "logic bug: impossible to have srb0 here\n");
if (ue->srb[id]) {
@@ -91,7 +91,7 @@ static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t chan
LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id);
}
else {
- AssertFatal(rb->type == NR_RLC_DRB,
+ AssertFatal(rb->type == NR_LCID_DRB,
"Invalid RB type\n");
int id = rb->choice.drb_id - 1;
if (ue->drb[id]) {
@@ -108,14 +108,14 @@ logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id)
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
for (logical_chan_id_t id = 1; id <= 32; id++) {
- nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1];
+ nr_lcid_rb_t *rb = &ue->lcid2rb[id - 1];
if (is_srb) {
- if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) {
+ if (rb->type == NR_LCID_SRB && rb->choice.srb_id == rb_id) {
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return id;
}
} else {
- if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) {
+ if (rb->type == NR_LCID_DRB && rb->choice.drb_id == rb_id) {
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return id;
}
@@ -130,14 +130,14 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i
{
if (channel_id == 0)
return ue->srb0;
- nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1];
- if (rb->type == NR_RLC_NONE)
+ nr_lcid_rb_t *rb = &ue->lcid2rb[channel_id - 1];
+ if (rb->type == NR_LCID_NONE)
return NULL;
- if (rb->type == NR_RLC_SRB) {
+ if (rb->type == NR_LCID_SRB) {
AssertFatal(rb->choice.srb_id > 0, "logic bug: impossible to have srb0 here\n");
return ue->srb[rb->choice.srb_id - 1];
} else {
- AssertFatal(rb->type == NR_RLC_DRB,
+ AssertFatal(rb->type == NR_LCID_DRB,
"Invalid RB type\n");
return ue->drb[rb->choice.drb_id - 1];
}
@@ -698,7 +698,7 @@ void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_Bear
NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity),
"servedRadioBearer for SRB mandatory present when setting up an SRB RLC entity\n");
int local_id = rlc_BearerConfig->logicalChannelIdentity - 1; // LCID 0 for SRB 0 not mapped
- ue->lcid2rb[local_id].type = NR_RLC_SRB;
+ ue->lcid2rb[local_id].type = NR_LCID_SRB;
ue->lcid2rb[local_id].choice.srb_id = rlc_BearerConfig->servedRadioBearer->choice.srb_Identity;
if (ue->srb[srb_id-1] != NULL) {
LOG_E(RLC, "SRB %d already exists for UE %d, do nothing\n", srb_id, ue_id);
@@ -763,7 +763,7 @@ static void add_drb_am(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_B
NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity),
"servedRadioBearer for DRB mandatory present when setting up an SRB RLC entity\n");
int local_id = rlc_BearerConfig->logicalChannelIdentity - 1; // LCID 0 for SRB 0 not mapped
- ue->lcid2rb[local_id].type = NR_RLC_DRB;
+ ue->lcid2rb[local_id].type = NR_LCID_DRB;
ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity;
if (ue->drb[drb_id-1] != NULL) {
LOG_E(RLC, "DRB %d already exists for UE %d, do nothing\n", drb_id, ue_id);
@@ -818,7 +818,7 @@ static void add_drb_um(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_B
NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity),
"servedRadioBearer for DRB mandatory present when setting up an SRB RLC entity\n");
int local_id = rlc_BearerConfig->logicalChannelIdentity - 1; // LCID 0 for SRB 0 not mapped
- ue->lcid2rb[local_id].type = NR_RLC_DRB;
+ ue->lcid2rb[local_id].type = NR_LCID_DRB;
ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity;
if (ue->drb[drb_id-1] != NULL) {
LOG_E(RLC, "DEBUG add_drb_um: warning DRB %d already exist for ue %d, do nothing\n", drb_id, ue_id);
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
index 3dec237958..67484e7108 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
@@ -28,22 +28,12 @@
typedef void nr_rlc_ue_manager_t;
-typedef enum nr_rlc_rb_type { NR_RLC_NONE = 0, NR_RLC_SRB = 1, NR_RLC_DRB = 2 } nr_rlc_rb_type;
-
typedef enum {
NR_RLC_OP_MODE_SPLIT_GNB,
NR_RLC_OP_MODE_MONO_GNB,
NR_RLC_OP_MODE_UE,
} nr_rlc_op_mode_t;
-typedef struct nr_rlc_rb_t {
- nr_rlc_rb_type type;
- union {
- int srb_id;
- int drb_id;
- } choice;
-} nr_rlc_rb_t;
-
typedef void (*rlf_handler_t)(int rnti);
typedef struct nr_rlc_ue_t {
@@ -51,7 +41,7 @@ typedef struct nr_rlc_ue_t {
nr_rlc_entity_t *srb0;
nr_rlc_entity_t *srb[3];
nr_rlc_entity_t *drb[MAX_DRBS_PER_UE];
- nr_rlc_rb_t lcid2rb[32];
+ nr_lcid_rb_t lcid2rb[32];
rlf_handler_t rlf_handler;
} nr_rlc_ue_t;
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 0d0829181e..e13ddac506 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -90,7 +90,14 @@ void print_ue_mac_stats(const module_id_t mod, const int frame_rx, const int slo
if (nbdl < 1)
nbdl = 1;
- cur += snprintf(cur, end - cur, "UE %d stats sfn: %d.%d, cumulated bad DCI %d\n", mod, frame_rx, slot_rx, mac->stats.bad_dci);
+ cur += snprintf(cur,
+ end - cur,
+ "UE %d RNTI %04x stats sfn: %d.%d, cumulated bad DCI %d\n",
+ mod,
+ mac->crnti,
+ frame_rx,
+ slot_rx,
+ mac->stats.bad_dci);
cur += snprintf(cur, end - cur, " DL harq: %lu", mac->stats.dl.rounds[0]);
int nb;
@@ -1106,9 +1113,11 @@ static int handle_bcch_dlsch(NR_UE_MAC_INST_t *mac,
unsigned int gNB_index,
uint8_t ack_nack,
uint8_t *pduP,
- uint32_t pdu_len)
+ uint32_t pdu_len,
+ int frame,
+ int slot)
{
- nr_ue_decode_BCCH_DL_SCH(mac, cc_id, gNB_index, ack_nack, pduP, pdu_len);
+ nr_ue_decode_BCCH_DL_SCH(mac, cc_id, gNB_index, ack_nack, pduP, pdu_len, frame, slot);
return 0;
}
@@ -1290,10 +1299,13 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio
break;
case FAPI_NR_RX_PDU_TYPE_SIB:
ret_mask |= (handle_bcch_dlsch(mac,
- dl_info->cc_id, dl_info->gNB_index,
+ dl_info->cc_id,
+ dl_info->gNB_index,
rx_indication_body.pdsch_pdu.ack_nack,
rx_indication_body.pdsch_pdu.pdu,
- rx_indication_body.pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
+ rx_indication_body.pdsch_pdu.pdu_length,
+ dl_info->frame,
+ dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_SIB;
break;
case FAPI_NR_RX_PDU_TYPE_DLSCH:
ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index f69e03b810..2ef11ce605 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -2542,6 +2542,34 @@ void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cp
LOG_I(RRC, "UE %d: received bearer release complete\n", cplt->gNB_cu_cp_ue_id);
}
+static void print_meas_result_quantity(FILE *f, const NR_MeasQuantityResults_t *mqr)
+{
+ fprintf(f, " resultSSB:");
+ if (!mqr) {
+ fprintf(f, " NOT PROVIDED\n");
+ return;
+ }
+ if (mqr->rsrp) {
+ const long rrsrp = *mqr->rsrp - 156;
+ fprintf(f, " RSRP %ld dBm", rrsrp);
+ } else {
+ fprintf(f, " RSRP not provided");
+ }
+ if (mqr->rsrq) {
+ const float rrsrq = (float) (*mqr->rsrq - 87) / 2.0f;
+ fprintf(f, " RSRQ %.1f dB", rrsrq);
+ } else {
+ fprintf(f, " RSRQ not provided");
+ }
+ if (mqr->sinr) {
+ const float rsinr = (float) (*mqr->sinr - 46) / 2.0f;
+ fprintf(f, " SINR %.1f dB", rsinr);
+ } else {
+ fprintf(f, " SINR not provided");
+ }
+ fprintf(f, "\n");
+}
+
static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults)
{
DevAssert(measresults->measResultServingMOList.list.count >= 1);
@@ -2550,37 +2578,21 @@ static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults)
NR_MeasResultServMO_t *measresultservmo = measresults->measResultServingMOList.list.array[0];
NR_MeasResultNR_t *measresultnr = &measresultservmo->measResultServingCell;
- NR_MeasQuantityResults_t *mqr = measresultnr->measResult.cellResults.resultsSSB_Cell;
if (measresultnr->physCellId)
fprintf(f,
- " servingCellId %ld MeasResultNR for phyCellId %ld:\n resultSSB:",
+ " servingCellId %ld MeasResultNR for phyCellId %ld:\n",
measresultservmo->servCellId,
*measresultnr->physCellId);
- if (mqr != NULL) {
- const long rrsrp = *mqr->rsrp - 156;
- const float rrsrq = (float) (*mqr->rsrq - 87) / 2.0f;
- const float rsinr = (float) (*mqr->sinr - 46) / 2.0f;
- fprintf(f, "RSRP %ld dBm RSRQ %.1f dB SINR %.1f dB\n", rrsrp, rrsrq, rsinr);
- } else {
- fprintf(f, "NOT PROVIDED\n");
- }
+ print_meas_result_quantity(f, measresultnr->measResult.cellResults.resultsSSB_Cell);
if (measresults->measResultNeighCells
&& measresults->measResultNeighCells->present == NR_MeasResults__measResultNeighCells_PR_measResultListNR) {
NR_MeasResultListNR_t *meas_neigh = measresults->measResultNeighCells->choice.measResultListNR;
for (int i = 0; i < meas_neigh->list.count; ++i) {
NR_MeasResultNR_t *measresultneigh = meas_neigh->list.array[i];
- NR_MeasQuantityResults_t *neigh_mqr = measresultneigh->measResult.cellResults.resultsSSB_Cell;
if (measresultneigh->physCellId)
- fprintf(f, " neighboring cell for phyCellId %ld:\n resultSSB:", *measresultneigh->physCellId);
- if (mqr != NULL) {
- const long rrsrp = *neigh_mqr->rsrp - 156;
- const float rrsrq = (float)(*neigh_mqr->rsrq - 87) / 2.0f;
- const float rsinr = (float)(*neigh_mqr->sinr - 46) / 2.0f;
- fprintf(f, "RSRP %ld dBm RSRQ %.1f dB SINR %.1f dB\n", rrsrp, rrsrq, rsinr);
- } else {
- fprintf(f, "NOT PROVIDED\n");
- }
+ fprintf(f, " neighboring cell for phyCellId %ld:\n", *measresultneigh->physCellId);
+ print_meas_result_quantity(f, measresultneigh->measResult.cellResults.resultsSSB_Cell);
}
}
}
diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c
index 09bce459f2..fe2eb2cfed 100644
--- a/openair2/RRC/NR_UE/L2_interface_ue.c
+++ b/openair2/RRC/NR_UE/L2_interface_ue.c
@@ -146,6 +146,9 @@ void process_msg_rcc_to_mac(MessageDef *msg)
bool can_start_ra = NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra;
nr_rrc_mac_config_other_sib(ue_id, NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, can_start_ra);
} break;
+ case NR_MAC_RRC_RESUME_RB:
+ nr_rrc_mac_resume_rb(ue_id, NR_MAC_RRC_RESUME_RB(msg).is_srb, NR_MAC_RRC_RESUME_RB(msg).rb_id);
+ break;
default:
LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg));
}
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index bb58191e24..90713ff50c 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -144,7 +144,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
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,
OCTET_STRING_t *masterCellGroup,
- long *fullConfig);
+ long *fullConfig,
+ int gNB_index);
static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers);
@@ -165,7 +166,120 @@ static void set_DRB_status(NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id, NR_R
rrc->status_DRBs[drb_id - 1] = status;
}
-static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc)
+static int get_ulsyncvalidityduration_timer_value(NR_NTN_Config_r17_t *ntncfg)
+{
+ int retval = 0;
+ AssertFatal(ntncfg, "NTN-Config IE not present\n");
+
+ if (ntncfg->ntn_UlSyncValidityDuration_r17) {
+ const int values[] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 120, 180, 240, 900};
+ retval = values[*ntncfg->ntn_UlSyncValidityDuration_r17];
+ }
+
+ return retval;
+}
+
+static void get_epochtime_from_sib19scheduling(NR_UE_RRC_SI_INFO *SI_info, int *frame, int *subframe)
+{
+ // TS 38.331 section 5.2.2.3.2
+ // SI-window starts at the slot #a, where a = x mod N
+ // x = (si-WindowPosition -1) × w, where w is the si-WindowLength;
+ // N is the number of slots in a radio frame
+ int wl_slots = 5 << SI_info->si_windowlength;
+ int x = (SI_info->sib19_windowposition - 1) * wl_slots;
+ int slots_per_subframe = 1 << SI_info->scs;
+ int N = slots_per_subframe * 10;
+ int slot_end_sib19_window = (x % N) + wl_slots;
+
+ *frame += (slot_end_sib19_window / N);
+ int slot = slot_end_sib19_window % N;
+ *subframe = ceil(slot / slots_per_subframe);
+
+ LOG_D(NR_RRC,
+ "Get EPOCHTIME: x:%d, N:%d, slot_endw:%d, frame:%d, subframe:%d , slot:%d\n",
+ x,
+ N,
+ slot_end_sib19_window,
+ *frame,
+ *subframe,
+ slot);
+}
+
+static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int frame)
+{
+ int epoch_frame = 0, epoch_subframe = 0;
+ int diff_frames = 0;
+ AssertFatal(frame >= 0, "Frame Incorrect, results in incorrect EPOCH time evaluation\n");
+ if (ntncfg->epochTime_r17) {
+ epoch_frame = ntncfg->epochTime_r17->sfn_r17;
+ epoch_subframe = ntncfg->epochTime_r17->subFrameNR_r17;
+ } else {
+ // EPOCH time is optional in case of SIB19. This case happens only in case of SIB19 NTN config
+ // If no EPOCH time is sent, epochtime points to SIB19 window end slot in the current scheduling window
+ epoch_frame = frame;
+ epoch_subframe = 0;
+ get_epochtime_from_sib19scheduling(SI_info, &epoch_frame, &epoch_subframe);
+ // Adding epochTime IE in SIB19, later MAC will use it.
+ ntncfg->epochTime_r17 = CALLOC(1, sizeof(NR_EpochTime_r17_t));
+ ntncfg->epochTime_r17->sfn_r17 = epoch_frame;
+ ntncfg->epochTime_r17->subFrameNR_r17 = epoch_subframe;
+ }
+ // For serving cell, the field sfn indicates the current SFN or the next upcoming SFN
+ // after the frame where the message indicating the epochTime is received
+ // i.e. Epochframe can be present or future SFN
+ diff_frames = (epoch_frame - frame + 1024) % 1024; // According to 38.331 Epochtime is defined for serving cell like this
+ LOG_D(NR_RRC, "Epoch frame %d, ahead by %d frames\n", epoch_frame, diff_frames);
+ return diff_frames;
+}
+
+static int get_ntn_timervalues(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int diff_frames, int *val430_ms)
+{
+ int val430 = get_ulsyncvalidityduration_timer_value(ntncfg);
+ int sib19_periodicity_ms = (SI_info->sib19_periodicity + 1) * 10;
+ *val430_ms = val430 * 1000 + diff_frames * 10; // in ms
+ if (*val430_ms <= sib19_periodicity_ms)
+ LOG_E(NR_RRC, "Too small T430 value. Might result in frequent ULSYNC failure\n");
+
+ // Depending on ulsyncvalidity duration, SIB19 timer expires 15secs/2secs before T430
+ // LArger values might be used for GEO and epoch time interval can be around 10 secs
+ // Lower values will be used for NGSO (LEO/MEO), epoch time interval can be between 2-3 secs.
+ // TODO remove the hardoded values and define a better strategy to determine the time of expiry
+ // with real GEO/LEO/MEO SATs.
+ int expire_before_ms = ((val430 >= 120) ? 10000 : 2000);
+ int diff = *val430_ms - expire_before_ms;
+ int sib19_timer_ms = (diff > 0) ? diff : ((*val430_ms - sib19_periodicity_ms) > 0) ? (*val430_ms - sib19_periodicity_ms) : 0;
+ LOG_D(NR_RRC, "val430:%d s, T430:%d ms, sib19_timer:%d ms\n", val430, *val430_ms, sib19_timer_ms);
+ return sib19_timer_ms;
+}
+
+static void nr_rrc_process_ntnconfig(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int frame)
+{
+ SI_info->SInfo_r17.sib19_validity = true;
+ // Check if Epochtime is sent or not
+ int diff_frames = eval_epoch_time(SI_info, ntncfg, frame);
+
+ if (ntncfg->ntn_UlSyncValidityDuration_r17) { // ulsyncvalidity duration configured
+ int val430_ms = 0, sib19_timer_ms = 0;
+ sib19_timer_ms = get_ntn_timervalues(SI_info, ntncfg, diff_frames, &val430_ms);
+ // T430 should be started only in connected mode.
+ // Inorder to avoid starting T430 when entering connected mode, T430 is started as soon as
+ // SIB19 is received, and if UE enters connected mode T430 will be in running.
+ // T430 expiry in RRC idle or inactive states does nothing.
+ nr_timer_setup(&rrc->timers_and_constants.T430, val430_ms, 10);
+ nr_timer_start(&rrc->timers_and_constants.T430);
+ // SIB19 should be received before T430 expires
+ // SIB19 validity timer should expire before T430 expiry such that new SIB19 is read
+ if (sib19_timer_ms > 0) {
+ nr_timer_setup(&SI_info->SInfo_r17.sib19_timer, sib19_timer_ms, 10);
+ nr_timer_start(&SI_info->SInfo_r17.sib19_timer);
+ } else
+ // This makes sure that SIB19 is read again in the next window
+ SI_info->SInfo_r17.sib19_validity = false;
+ } else
+ nr_timer_start(&SI_info->SInfo_r17.sib19_timer);
+}
+
+static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc, int frame)
{
instance_t ue_id = rrc->ue_id;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN);
@@ -240,11 +354,10 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si,
nr_timer_start(&SI_info->sib14_timer);
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700:
- SI_info->SInfo_r17.sib19_validity = true;
- if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
- xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700);
sib19 = typeandinfo->choice.sib19_v1700;
- nr_timer_start(&SI_info->SInfo_r17.sib19_timer);
+ if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
+ xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)sib19);
+ nr_rrc_process_ntnconfig(rrc, SI_info, sib19->ntn_Config_r17, frame);
break;
default:
break;
@@ -335,6 +448,27 @@ static bool verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1
return ntn_access && sib19_present;
}
+static void get_sib19_schedinfo(NR_UE_RRC_SI_INFO *SI_info, NR_SI_SchedulingInfo_v1700_t *si_SchedInfo_v1700)
+{
+ // Find the SIB19 periodicity configured in the scheduling info
+ if (si_SchedInfo_v1700) {
+ int count_v17 = si_SchedInfo_v1700->schedulingInfoList2_r17.list.count;
+ for (int i = 0; i < count_v17; i++) {
+ struct NR_SchedulingInfo2_r17 *schedulingInfo2 = si_SchedInfo_v1700->schedulingInfoList2_r17.list.array[i];
+ for (int j = 0; j < schedulingInfo2->sib_MappingInfo_r17.list.count; j++) {
+ struct NR_SIB_TypeInfo_v1700 *sib_TypeInfo_v1700 = schedulingInfo2->sib_MappingInfo_r17.list.array[j];
+ if (sib_TypeInfo_v1700->sibType_r17.present == NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17) {
+ if (sib_TypeInfo_v1700->sibType_r17.choice.type1_r17 == NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19) {
+ SI_info->sib19_periodicity = 8 << schedulingInfo2->si_Periodicity_r17;
+ SI_info->sib19_windowposition = schedulingInfo2->si_WindowPosition_r17;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_SIB1_t *sib1)
{
if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
@@ -355,9 +489,14 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf
si_SchedInfo_v1700 = sib1_v1700->si_SchedulingInfo_v1700;
}
+ AssertFatal(sib1->servingCellConfigCommon, "configuration issue in SIB1\n");
+ SI_info->scs = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing;
+ SI_info->si_windowlength = (sib1->si_SchedulingInfo) ? sib1->si_SchedulingInfo->si_WindowLength : 0;
// configure default SI
nr_rrc_configure_default_SI(SI_info, sib1->si_SchedulingInfo, si_SchedInfo_v1700);
rrc->is_NTN_UE = verify_NTN_access(SI_info, sib1_v1700);
+ if (rrc->is_NTN_UE)
+ get_sib19_schedinfo(SI_info, si_SchedInfo_v1700);
// configure timers and constant
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1);
@@ -376,7 +515,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe
LOG_E(NR_RRC, "RRCReconfiguration includes fullConfig but this is not implemented yet\n");
}
if (rec_1530->masterCellGroup)
- nr_rrc_ue_process_masterCellGroup(rrc, rec_1530->masterCellGroup, rec_1530->fullConfig);
+ nr_rrc_ue_process_masterCellGroup(rrc, rec_1530->masterCellGroup, rec_1530->fullConfig, gNB_index);
if (rec_1530->masterKeyUpdate) {
// TODO perform AS security key update procedure as specified in 5.3.5.7
LOG_E(NR_RRC, "RRCReconfiguration includes masterKeyUpdate but this is not implemented yet\n");
@@ -426,7 +565,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe
SEQUENCE_free(&asn_DEF_NR_SystemInformation, si, 1);
} else {
LOG_I(NR_RRC, "[UE %ld] Decoding dedicatedSystemInformationDelivery\n", rrc->ue_id);
- nr_decode_SI(SI_info, si, rrc);
+ nr_decode_SI(SI_info, si, rrc, rrc->current_frame);
}
}
if (rec_1530->otherConfig) {
@@ -502,7 +641,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
- nr_rrc_cellgroup_configuration(rrc, cellGroupConfig);
+ nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n");
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_CG);
@@ -894,6 +1033,10 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti)
nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL);
// resume SRB1
rrc->Srb[srb_id] = RB_ESTABLISHED;
+ MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
+ NR_MAC_RRC_RESUME_RB(msg).is_srb = true;
+ NR_MAC_RRC_RESUME_RB(msg).rb_id = 1;
+ itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
break;
case DURING_HANDOVER:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
@@ -924,7 +1067,9 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
uint8_t *const Sdu,
const uint8_t Sdu_len,
const uint8_t rsrq,
- const uint8_t rsrp)
+ const uint8_t rsrp,
+ int frame,
+ int slot)
{
NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo;
SI_info->sib_pending = false;
@@ -960,9 +1105,9 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
bcch_message->message.choice.c1->choice.systemInformationBlockType1 = NULL;
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
- LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id);
+ LOG_I(NR_RRC, "[UE %ld] %d:%d Decoding SI\n", rrc->ue_id, frame, slot);
NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation;
- nr_decode_SI(SI_info, si, rrc);
+ nr_decode_SI(SI_info, si, rrc, frame);
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
default:
@@ -1019,7 +1164,9 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
}
}
-static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, NR_ReconfigurationWithSync_t *reconfigurationWithSync)
+static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc,
+ NR_ReconfigurationWithSync_t *reconfigurationWithSync,
+ int gNB_index)
{
// perform Reconfiguration with sync according to 5.3.5.5.2
if (!rrc->as_security_activated && !(get_softmodem_params()->phy_test || get_softmodem_params()->do_ra)) {
@@ -1051,15 +1198,26 @@ static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, NR_Rec
}
rrc->rnti = reconfigurationWithSync->newUE_Identity;
// reset the MAC entity of this cell group (done at MAC in handle_reconfiguration_with_sync)
+
+ // 3GPP TS38.331 section 5.3.5.5.2
+ nr_timer_stop(&tac->T430);
+ if (reconfigurationWithSync->spCellConfigCommon &&
+ reconfigurationWithSync->spCellConfigCommon->ext2 &&
+ reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) {
+ NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17;
+ // EPOCH time is always sent if NTN config is sent through DCCH
+ AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n");
+ nr_rrc_process_ntnconfig(rrc, &rrc->perNB[gNB_index].SInfo, ntncfg, rrc->current_frame);
+ }
}
-void nr_rrc_cellgroup_configuration(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, int gNB_index)
{
NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig;
if(spCellConfig) {
if (spCellConfig->reconfigurationWithSync) {
LOG_I(NR_RRC, "Processing reconfigurationWithSync\n");
- nr_rrc_process_reconfigurationWithSync(rrc, spCellConfig->reconfigurationWithSync);
+ nr_rrc_process_reconfigurationWithSync(rrc, spCellConfig->reconfigurationWithSync, gNB_index);
}
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants);
if (spCellConfig->spCellConfigDedicated) {
@@ -1079,10 +1237,10 @@ void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t
AssertFatal(cellGroupConfig->sCellToAddModList == NULL, "Secondary serving cell addition not implemented\n");
}
-
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
OCTET_STRING_t *masterCellGroup,
- long *fullConfig)
+ long *fullConfig,
+ int gNB_index)
{
AssertFatal(!fullConfig, "fullConfig not supported yet\n");
NR_CellGroupConfig_t *cellGroupConfig = NULL;
@@ -1096,7 +1254,7 @@ 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(rrc, cellGroupConfig);
+ nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
LOG_D(RRC, "Sending CellGroupConfig to MAC the pointer will be managed by mac\n");
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_CG);
@@ -1143,21 +1301,67 @@ static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const
nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL);
}
+static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
+{
+ LOG_W(NR_RRC,
+ "[UE %ld] Recived RRCSetup in response to %s request\n",
+ rrc->ue_id, rrc->ra_trigger == RRC_CONNECTION_REESTABLISHMENT ? "RRCReestablishment" : "RRCResume");
+
+ // discard any stored UE Inactive AS context and suspendConfig
+ // TODO
+
+ // discard any current AS security context including
+ // K_RRCenc key, the K_RRCint key, the K_UPint key and the K_UPenc key
+ // TODO only kgnb is stored
+ memset(rrc->kgnb, 0, sizeof(rrc->kgnb));
+ rrc->as_security_activated = false;
+
+ // release radio resources for all established RBs except SRB0,
+ // including release of the RLC entities, of the associated PDCP entities and of SDAP
+ for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
+ if (get_DRB_status(rrc, i) != RB_NOT_PRESENT) {
+ set_DRB_status(rrc, i, RB_NOT_PRESENT);
+ nr_pdcp_release_drb(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 = 1; 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);
+ }
+ }
+ nr_sdap_delete_ue_entities(rrc->ue_id);
+
+ // release the RRC configuration except for the default L1 parameter values,
+ // default MAC Cell Group configuration and CCCH configuration
+ // TODO to be completed
+ NR_UE_MAC_reset_cause_t cause = RRC_SETUP_REESTAB_RESUME;
+ MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
+ NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
+ itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
+
+ // indicate to upper layers fallback of the RRC connection
+ // TODO
+
+ // stop timer T380, if running
+ // TODO not implemented yet
+}
+
static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, const NR_RRCSetup_t *rrcSetup)
{
// if the RRCSetup is received in response to an RRCReestablishmentRequest
// or RRCResumeRequest or RRCResumeRequest1
- // TODO none of the procedures implemented yet
- if (rrc->ra_trigger == RRC_CONNECTION_REESTABLISHMENT) {
- LOG_E(NR_RRC, "Handling of RRCSetup in response of RRCReestablishment not implemented yet. Going back to IDLE.\n");
- nr_rrc_going_to_IDLE(rrc, OTHER, NULL);
- return;
- }
+ if (rrc->ra_trigger == RRC_CONNECTION_REESTABLISHMENT || rrc->ra_trigger == RRC_RESUME_REQUEST)
+ nr_rrc_rrcsetup_fallback(rrc);
// perform the cell group configuration procedure in accordance with the received masterCellGroup
- nr_rrc_ue_process_masterCellGroup(rrc,
- &rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup,
- NULL);
+ nr_rrc_ue_process_masterCellGroup(rrc, &rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, NULL, 0);
// perform the radio bearer configuration procedure in accordance with the received radioBearerConfig
nr_rrc_ue_process_RadioBearerConfig(rrc,
&rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
@@ -1182,6 +1386,9 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, const NR_RRCSetup_t *
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_NAS_CONN_ESTABLISH_IND);
itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, msg_p);
+ // resetting the RA trigger state after receiving MSG4 with RRCSetup
+ rrc->ra_trigger = RA_NOT_RUNNING;
+
// set the content of RRCSetupComplete message
// TODO procedues described in 5.3.3.4 seems more complex than what we actualy do
rrc_ue_generate_RRCSetupComplete(rrc, rrcSetup->rrc_TransactionIdentifier);
@@ -1868,11 +2075,21 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
if (rrc->reconfig_after_reestab) {
// if this is the first RRCReconfiguration message after successful completion of the RRC re-establishment procedure
// resume SRB2 and DRBs that are suspended
- if (rrc->Srb[2] == RB_SUSPENDED)
+ if (rrc->Srb[2] == RB_SUSPENDED) {
rrc->Srb[2] = RB_ESTABLISHED;
+ MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
+ NR_MAC_RRC_RESUME_RB(msg).is_srb = true;
+ NR_MAC_RRC_RESUME_RB(msg).rb_id = 2;
+ itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
+ }
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
- if (get_DRB_status(rrc, i) == RB_SUSPENDED)
+ if (get_DRB_status(rrc, i) == RB_SUSPENDED) {
set_DRB_status(rrc, i, RB_ESTABLISHED);
+ MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
+ NR_MAC_RRC_RESUME_RB(msg).is_srb = false;
+ NR_MAC_RRC_RESUME_RB(msg).rb_id = i;
+ itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
+ }
}
rrc->reconfig_after_reestab = false;
}
@@ -1907,22 +2124,22 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
break;
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: {
- NR_DLInformationTransfer_t *dlInformationTransfer = c1->choice.dlInformationTransfer;
+ NR_DLInformationTransfer_t *dlInfo = c1->choice.dlInformationTransfer;
- if (dlInformationTransfer->criticalExtensions.present
- == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
+ if (dlInfo->criticalExtensions.present == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
+ NR_DLInformationTransfer_IEs_t *dlInfo_IE = dlInfo->criticalExtensions.choice.dlInformationTransfer;
/* This message hold a dedicated info NAS payload, forward it to NAS */
- NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
- dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;
-
- MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NAS_DOWNLINK_DATA_IND);
- dl_info_transfer_ind_t *msg = &NAS_DOWNLINK_DATA_IND(ittiMsg);
- msg->UEid = rrc->ue_id;
- msg->nasMsg.length = dedicatedNAS_Message->size;
- msg->nasMsg.nas_data = malloc(msg->nasMsg.length);
- memcpy(msg->nasMsg.nas_data, dedicatedNAS_Message->buf, msg->nasMsg.length);
- itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, ittiMsg);
- dedicatedNAS_Message->buf = NULL; // to keep the buffer, up to NAS to free it
+ NR_DedicatedNAS_Message_t *dedicatedNAS_Message = dlInfo_IE->dedicatedNAS_Message;
+ if (dedicatedNAS_Message) {
+ MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NAS_DOWNLINK_DATA_IND);
+ dl_info_transfer_ind_t *msg = &NAS_DOWNLINK_DATA_IND(ittiMsg);
+ msg->UEid = rrc->ue_id;
+ msg->nasMsg.length = dedicatedNAS_Message->size;
+ msg->nasMsg.nas_data = malloc(msg->nasMsg.length);
+ memcpy(msg->nasMsg.nas_data, dedicatedNAS_Message->buf, msg->nasMsg.length);
+ itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, ittiMsg);
+ dedicatedNAS_Message->buf = NULL; // to keep the buffer, up to NAS to free it
+ }
}
} break;
case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
@@ -2004,7 +2221,8 @@ void *rrc_nrue(void *notUsed)
} break;
case NRRRC_FRAME_PROCESS:
- LOG_D(NR_RRC, "Received %s: frame %d\n", ITTI_MSG_NAME(msg_p), NRRRC_FRAME_PROCESS(msg_p).frame);
+ rrc->current_frame = NRRRC_FRAME_PROCESS(msg_p).frame;
+ LOG_D(NR_RRC, "Received %s: frame %d\n", ITTI_MSG_NAME(msg_p), rrc->current_frame);
// increase the timers every 10ms (every new frame)
nr_rrc_handle_timers(rrc);
NR_UE_RRC_SI_INFO *SInfo = &rrc->perNB[NRRRC_FRAME_PROCESS(msg_p).gnb_id].SInfo;
@@ -2048,7 +2266,14 @@ void *rrc_nrue(void *notUsed)
if (bcch->is_bch)
nr_rrc_ue_decode_NR_BCCH_BCH_Message(rrc, bcch->gnb_index, bcch->phycellid, bcch->ssb_arfcn, bcch->sdu, bcch->sdu_size);
else
- nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(rrc, bcch->gnb_index, bcch->sdu, bcch->sdu_size, bcch->rsrq, bcch->rsrp);
+ nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(rrc,
+ bcch->gnb_index,
+ bcch->sdu,
+ bcch->sdu_size,
+ bcch->rsrq,
+ bcch->rsrp,
+ bcch->frame,
+ bcch->slot);
break;
case NR_RRC_MAC_SBCCH_DATA_IND:
@@ -2649,6 +2874,22 @@ void handle_t300_expiry(NR_UE_RRC_INST_t *rrc)
// TODO inform upper layers about the failure to establish the RRC connection
}
+void handle_t430_expiry(NR_UE_RRC_INST_t *rrc)
+{
+ // SPEC 38.331 section 5.2.2.6
+ // Reacquire SIB19 after T430 expiry
+ for (int i = 0; i < NB_CNX_UE; i++) {
+ rrcPerNB_t *nb = &rrc->perNB[i];
+ NR_UE_RRC_SI_INFO *SI_info = &nb->SInfo;
+ SI_info->SInfo_r17.sib19_validity = false;
+ }
+ // Indicate MAC that UL SYNC is LOST
+ NR_UE_MAC_reset_cause_t cause = UL_SYNC_LOST_T430_EXPIRED;
+ MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
+ NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
+ itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
+}
+
//This calls the sidelink preconf message after RRC, MAC instances are created.
void start_sidelink(int instance)
{
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index e428c4c160..960dc1aaa0 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -94,6 +94,7 @@ typedef enum RA_trigger_e {
RA_NOT_RUNNING,
RRC_CONNECTION_SETUP,
RRC_CONNECTION_REESTABLISHMENT,
+ RRC_RESUME_REQUEST,
DURING_HANDOVER,
NON_SYNCHRONISED,
TRANSITION_FROM_RRC_INACTIVE,
@@ -151,6 +152,11 @@ typedef struct UE_RRC_SI_INFO_NR_s {
bool sib14_validity;
NR_timer_t sib14_timer;
NR_UE_RRC_SI_INFO_r17 SInfo_r17;
+ // Extracted from SIB1
+ int scs;
+ int sib19_periodicity;
+ int sib19_windowposition;
+ int si_windowlength;
} NR_UE_RRC_SI_INFO;
typedef struct NR_UE_Timers_Constants_s {
@@ -167,6 +173,8 @@ typedef struct NR_UE_Timers_Constants_s {
NR_timer_t T325;
NR_timer_t T380;
NR_timer_t T390;
+ // NTN timer T430 which guards UL SYNC
+ NR_timer_t T430;
// counters
uint32_t N310_cnt;
uint32_t N311_cnt;
@@ -233,6 +241,8 @@ typedef struct NR_UE_RRC_INST_s {
bool reconfig_after_reestab;
// 5G-S-TMSI
uint64_t fiveG_S_TMSI;
+ // Frame timing received from MAC
+ int current_frame;
//Sidelink params
NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index f4728f0f58..7c5f749fa0 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -47,7 +47,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(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, int gNB_index);
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
NR_Release_Cause_t release_cause,
@@ -80,6 +80,7 @@ void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo);
void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id);
void handle_t300_expiry(NR_UE_RRC_INST_t *rrc);
+void handle_t430_expiry(NR_UE_RRC_INST_t *rrc);
void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac);
void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac);
diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c
index 6629055b3a..9286494f0b 100644
--- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c
+++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c
@@ -169,6 +169,14 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
// with release cause 'RRC connection failure'
nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL);
}
+
+ bool t430_expired = nr_timer_tick(&rrc->timers_and_constants.T430);
+ if (t430_expired && rrc->nrRrcState == RRC_STATE_CONNECTED_NR && rrc->is_NTN_UE) {
+ LOG_W(NR_RRC, "Timer T430 expired! Indicate UL SYNC LOSS to MAC\n");
+ // Upon T430 expiry, the UE shall reacquire SIB19 and re-obtain UL-SYNC
+ // Spec 38.331 Section 5.2.2.6
+ handle_t430_expiry(rrc);
+ }
}
int nr_rrc_get_T304(long t304)
diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c
index 5709d482c6..d7fb313fa8 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg.c
+++ b/openair3/NAS/NR_UE/nr_nas_msg.c
@@ -32,6 +32,7 @@
#include "nr_nas_msg.h"
#include
#include "NR_NAS_defs.h"
+#include
#include
#include
#include
@@ -1495,6 +1496,10 @@ static void handle_pdu_session_accept(uint8_t *pdu_buffer, uint32_t msg_length,
*/
void handleDownlinkNASTransport(uint8_t * pdu_buffer, int pdu_length, int instance)
{
+ if (pdu_length < 17) {
+ LOG_E(NAS, "Received DL NAS Transport message too short (%d)\n", pdu_length);
+ return;
+ }
uint8_t msg_type = *(pdu_buffer + 16);
if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
LOG_A(NAS, "Received PDU Session Establishment Accept in DL NAS Transport\n");
@@ -2079,10 +2084,23 @@ void *nas_nrue(void *args_p)
case FGS_PDU_SESSION_ESTABLISHMENT_REJ:
LOG_E(NAS, "Received PDU Session Establishment reject\n");
break;
- case FGS_REGISTRATION_REJECT:
- LOG_E(NAS, "Received Registration reject cause: %s\n", cause_text_info[pdu_buffer[17]].text);
+ case FGS_REGISTRATION_REJECT: {
+
+ if (pdu_length < 18) {
+ LOG_E(NAS, "Received Registration reject message too short\n");
+ break;
+ }
+
+ uint8_t cause = pdu_buffer[17];
+ if (cause >= sizeof(cause_text_info) / sizeof(cause_text_info[0])) {
+ LOG_E(NAS, "Received Registration reject cause %d unknown\n", cause);
+ break;
+ }
+
+ LOG_E(NAS, "Received Registration reject cause: %s\n", cause_text_info[cause].text);
exit(1);
break;
+ }
case FGS_SERVICE_ACCEPT: {
handle_service_accept(nas, &buffer);
break;
diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp
index 8fbb561149..6dde70b2eb 100644
--- a/radio/USRP/usrp_lib.cpp
+++ b/radio/USRP/usrp_lib.cpp
@@ -1202,9 +1202,9 @@ extern "C" {
}
}
else {
- if (openair0_cfg[0].clock_source != unset) {
- LOG_W(HW,"Time source set in both usrp_args and in time_source, ingnoring the latter!\n");
- }
+ if (openair0_cfg[0].time_source != unset) {
+ LOG_W(HW, "Time source set in both usrp_args and in openair0_cfg[0].time_source, ignoring the latter!\n");
+ }
}