Merge branch 'integration_2025_w25' into 'develop'
Integration: `2025.w25` Closes #970 and #969 See merge request oai/openairinterface5g!3485 * !3083 Speed up ubuntu22 image build * !3428 NR UE fallback to RRCSetup from RRCReestablishment * !3479 Suspend RBs at UE * !3446 DL NAS Transport: Fix Message Type retrieval on too short message * !3445 Finalize FAPI dump functions, add Digital Beamforming Table and Precoding Matrix Table to CONFIG.request * !3447 NAS Registration Reject: Add bounds and lengths checks * !3481 RNTI information printed in UE stats * !3484 gNB RRC: handle optional measResultQuantity fields independently * !3480 USRP lib: fix incorrect config check for time_source fallback * !3483 UE segfault in DLInformationTransfer * !3367 Enabling usage of ulsyncvalidityDuration timer in SIB19 * !3482 CI: Add "may_fail" step to execute flaky steps
This commit is contained in:
@@ -224,7 +224,6 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' </table>\n')
|
||||
self.htmlFile.write(' </div>\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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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;
|
||||
|
||||
+6
-5
@@ -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:
|
||||
|
||||
@@ -95,7 +95,6 @@ class RANManagement():
|
||||
self.cmd_prefix = '' # prefix before {lte,nr}-softmodem
|
||||
self.node = ''
|
||||
self.command = ''
|
||||
self.command_fail = False
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
000001
|
||||
000011
|
||||
000012
|
||||
000002
|
||||
000003
|
||||
000004
|
||||
@@ -38,7 +40,21 @@
|
||||
<desc>This should succeed</desc>
|
||||
<node>localhost</node>
|
||||
<command>true</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000011">
|
||||
<class>Custom_Command</class>
|
||||
<desc>This may fail</desc>
|
||||
<may_fail>true</may_fail>
|
||||
<node>localhost</node>
|
||||
<command>false</command>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000012">
|
||||
<class>Custom_Command</class>
|
||||
<desc>This is still executed</desc>
|
||||
<node>localhost</node>
|
||||
<command>true</command>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
@@ -46,7 +62,6 @@
|
||||
<desc>This should fail</desc>
|
||||
<node>localhost</node>
|
||||
<command>false</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000003">
|
||||
@@ -54,7 +69,6 @@
|
||||
<desc>This should be skipped</desc>
|
||||
<node>localhost</node>
|
||||
<command>true</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000004">
|
||||
@@ -63,6 +77,5 @@
|
||||
<always_exec>true</always_exec>
|
||||
<node>localhost</node>
|
||||
<command>true</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
</testCaseList>
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
<desc>Simulate a DL radio channel with noise (3 dB)</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo channelmod modify 0 noise_power_dB 3 | nc --send-only 192.168.71.181 8091</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030021">
|
||||
@@ -166,7 +165,6 @@
|
||||
<desc>Trigger Reestablishment</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>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'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020022">
|
||||
@@ -185,7 +183,6 @@
|
||||
<desc>Verify Reestablishment</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ci get_reestab_count | nc 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040021">
|
||||
@@ -193,7 +190,6 @@
|
||||
<desc>Simulate a disruption of DL radio channel (ploss 55)</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo channelmod modify 0 ploss 55 | nc 192.168.71.181 8091</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040022">
|
||||
@@ -201,7 +197,6 @@
|
||||
<desc>Get UE sync state (UE ID 0)</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_NOT_SYNC</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040023">
|
||||
@@ -209,7 +204,6 @@
|
||||
<desc>Restoration of the original DL channel conditions (ploss 20)</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo channelmod modify 0 ploss 20 | nc 192.168.71.181 8091</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040024">
|
||||
@@ -217,7 +211,6 @@
|
||||
<desc>Get UE sync state (UE ID 0)</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_CONNECTED</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040025">
|
||||
@@ -225,7 +218,6 @@
|
||||
<desc>Trigger Handover</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ci trigger_f1_ho | nc 192.168.71.150 9090</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040026">
|
||||
@@ -233,7 +225,6 @@
|
||||
<desc>UE (1) connected to DU-PCI 0?</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ci fetch_du_by_ue_id 1 | nc 192.168.71.150 9090 | grep "3584"</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040027">
|
||||
@@ -241,7 +232,6 @@
|
||||
<desc>UE (1) connected to DU-PCI 1?</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ci fetch_du_by_ue_id 1 | nc 192.168.71.150 9090 | grep "3585"</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100021">
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
|
||||
<testCase id="444445">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach OAI UE 2 to 10</desc>
|
||||
<desc>Detach OAI UE 3 to 10</desc>
|
||||
<id>rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10</id>
|
||||
<nodes>cacofonix cacofonix cacofonix cacofonix cacofonix cacofonix cacofonix cacofonix</nodes>
|
||||
</testCase>
|
||||
|
||||
@@ -151,7 +151,6 @@
|
||||
<desc>Force Msg3 C-RNTI RA</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ciUE force_crnti_ra | nc 192.168.71.150 8091</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040002">
|
||||
@@ -159,7 +158,6 @@
|
||||
<desc>Force RRC_IDLE (UE ID 0)</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ciUE force_RRC_IDLE | nc 192.168.71.150 8091</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
<desc>Check that UE synched</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK"</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
|
||||
@@ -108,14 +108,6 @@
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="004000">
|
||||
<class>Custom_Command</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean-Up any residual volume</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>docker volume rm 5g_rfsimulator_tdd_dora_rrc.config</command>
|
||||
</testCase>
|
||||
|
||||
<testCase id="222222">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
|
||||
@@ -70,9 +70,9 @@
|
||||
|
||||
<testCase id = "100000">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Reset USRP</desc>
|
||||
<desc>Reset USRP on nepes</desc>
|
||||
<node>nepes</node>
|
||||
<command>sudo -S /usr/lib/uhd/utils/b2xx_fx3_utils --reset-device</command>
|
||||
<command>sudo -S /usr/local/lib/uhd/utils/b2xx_fx3_utils --reset-device</command>
|
||||
</testCase>
|
||||
|
||||
<testCase id="200000">
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
|
||||
<testCase id="100010">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/3Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/3Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 45M -t 30 -R</iperf_args>
|
||||
<id>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</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
@@ -193,7 +193,7 @@
|
||||
|
||||
<testCase id="100030">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30 -R</iperf_args>
|
||||
<id>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</id>
|
||||
<iperf_tcp_rate_target>2</iperf_tcp_rate_target>
|
||||
@@ -202,7 +202,7 @@
|
||||
|
||||
<testCase id="100020">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/1Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/1Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 15M -t 30</iperf_args>
|
||||
<id>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</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
@@ -213,7 +213,7 @@
|
||||
|
||||
<testCase id="100040">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30</iperf_args>
|
||||
<svr_id>oc-cn5g</svr_id>
|
||||
<id>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</id>
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
|
||||
<testCase id="000010">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/4Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/4Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 60M -t 30 -R</iperf_args>
|
||||
<id>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</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
@@ -190,7 +190,7 @@
|
||||
|
||||
<testCase id="000030">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30 -R</iperf_args>
|
||||
<id>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</id>
|
||||
<iperf_tcp_rate_target>3.9</iperf_tcp_rate_target>
|
||||
@@ -199,7 +199,7 @@
|
||||
|
||||
<testCase id="000020">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/1.5Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/1.5Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 22.5M -t 30</iperf_args>
|
||||
<id>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</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
@@ -210,7 +210,7 @@
|
||||
|
||||
<testCase id="000040">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30</iperf_args>
|
||||
<svr_id>oc-cn5g</svr_id>
|
||||
<id>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</id>
|
||||
|
||||
@@ -200,14 +200,12 @@
|
||||
<desc>Trigger Reestablishment</desc>
|
||||
<node>ofqot</node>
|
||||
<command>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'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
<testCase id="060002">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Verify Reestablishment</desc>
|
||||
<node>ofqot</node>
|
||||
<command>echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030201">
|
||||
|
||||
@@ -188,14 +188,12 @@
|
||||
<desc>Trigger Reestablishment (on DU)</desc>
|
||||
<node>ofqot</node>
|
||||
<command>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'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
<testCase id="360002">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Verify Reestablishment (on CU)</desc>
|
||||
<node>ofqot</node>
|
||||
<command>echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100002">
|
||||
|
||||
@@ -233,14 +233,12 @@
|
||||
<desc>Trigger Reestablishment (on DU)</desc>
|
||||
<node>ofqot</node>
|
||||
<command>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'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
<testCase id="160002">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Verify Reestablishment (on CU)</desc>
|
||||
<node>ofqot</node>
|
||||
<command>echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="130201">
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
<desc>Setup sriov and network interfaces Metanoia</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/setup_sriov_metanoia.sh</script>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="110000">
|
||||
@@ -92,7 +91,7 @@
|
||||
|
||||
<testCase id="100010">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/570Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/570Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 570M -t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
|
||||
@@ -103,7 +102,7 @@
|
||||
|
||||
<testCase id="100030">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_tcp_rate_target>80</iperf_tcp_rate_target>
|
||||
@@ -112,7 +111,7 @@
|
||||
|
||||
<testCase id="100020">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/100Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/100Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 100M -t 30</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
|
||||
@@ -123,7 +122,7 @@
|
||||
|
||||
<testCase id="100040">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_tcp_rate_target>80</iperf_tcp_rate_target>
|
||||
@@ -166,7 +165,6 @@
|
||||
<desc>Set CPU to idle state, set kernel parameters to default values</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/setup_cleanup.sh</script>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
100020
|
||||
100030
|
||||
100040
|
||||
100011
|
||||
103000
|
||||
100002
|
||||
130000
|
||||
@@ -49,7 +50,6 @@
|
||||
<desc>Setup sriov and network interfaces VVDN</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_vvdn_gnb/setup_sriov_vvdn.sh</script>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="110000">
|
||||
@@ -90,7 +90,7 @@
|
||||
|
||||
<testCase id="100010">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/600Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/600Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 600M -t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
|
||||
@@ -99,9 +99,20 @@
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100011">
|
||||
<class>Iperf</class>
|
||||
<desc>Optional iperf (DL/700Mbps/UDP)(30 sec)</desc>
|
||||
<may_fail>true</may_fail>
|
||||
<iperf_args>-u -b 700M -t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
|
||||
<svr_id>oc-cn5g-20897</svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100030">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (DL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_tcp_rate_target>40</iperf_tcp_rate_target>
|
||||
@@ -110,7 +121,7 @@
|
||||
|
||||
<testCase id="100020">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/80Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/80Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 80M -t 30</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
|
||||
@@ -121,7 +132,7 @@
|
||||
|
||||
<testCase id="100040">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
|
||||
<desc>iperf (UL/TCP)(30 sec)</desc>
|
||||
<iperf_args>-t 30</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_tcp_rate_target>10</iperf_tcp_rate_target>
|
||||
@@ -164,7 +175,6 @@
|
||||
<desc>Set CPU to idle state, set kernel parameters to default values</desc>
|
||||
<node>cacofonix</node>
|
||||
<script>yaml_files/sa_fhi_7.2_vvdn_gnb/setup_cleanup.sh</script>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
@@ -194,14 +194,12 @@
|
||||
<desc>Trigger Reestablishment</desc>
|
||||
<node>ofqot</node>
|
||||
<command>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'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
<testCase id="260002">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Verify Reestablishment</desc>
|
||||
<node>ofqot</node>
|
||||
<command>echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="230201">
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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--;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_Type>_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--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}, \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+32
-20
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
+286
-45
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "nr_nas_msg.h"
|
||||
#include <netinet/in.h>
|
||||
#include "NR_NAS_defs.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user