NR SA SDT (Small Data Transmission)
The purpose of this tutorial is to show you how to configure gNB so that it enables SDT (Small Data Transmission) when small sized user data meeting the sdt criteria flows.
SDT is a mechanism for UEs in RRC_INACTIVE mode to transmit (and receive) data or control without fully resuming the RRC connection. The goal is to minimize the number of exchanged messages, typically for low energy consumption scenarios in IoT with small messages sent periodically.
SDT comes with two flavors:
- RA-SDT, based on Random Access, which could in turn be either 4-steps Random Access or 2-steps Random Access
- CG-SDT, based on Configured Grants
Table of Contents
Introduction
Small Data Transmission (SDT) represents a significant evolution in the 5G New Radio (NR) architecture, enabling efficient low-latency and low-energy data exchange for devices operating in RRC_INACTIVE mode. Traditionally, user equipment (UE) needed to transition to RRC_CONNECTED mode before any user-plane data transmission, resulting in additional signaling overhead and increased energy consumption—particularly problematic for IoT devices that frequently send small, sporadic data packets. SDT addresses this challenge by allowing data and control information to be sent or received without a full RRC connection resumption, thus streamlining data paths, reducing latency, and conserving device battery life. Architecturally, SDT leverages both Random Access (RA-SDT) and Configured Grant (CG-SDT) mechanisms for uplink transmissions. RA-SDT utilizes the standard Random Access Procedure, which can be configured for either 4-step or 2-step access, while CG-SDT relies on pre-allocated resources to further minimize signaling. The integration of SDT in gNB (next-generation NodeB) configuration is essential for supporting massive Machine Type Communication (mMTC) and IoT deployments in 5G, where a large number of devices require efficient, scalable, and energy-conscious data exchange. This tutorial provides a comprehensive guide to configuring gNB for SDT, focusing on the technical aspects, underlying architectural concepts, and practical setup steps required to support small data transmissions in a 5G network environment.
-
Context and Background
- 5G NR introduces RRC_INACTIVE state to optimize signaling and power consumption, especially for scenarios involving IoT and MTC devices.
- SDT enables UEs in RRC_INACTIVE state to transmit or receive small data payloads without resuming the full RRC connection, reducing latency and network overhead.
- SDT is vital for applications where periodic or sporadic small messages are exchanged, such as smart metering, sensor networks, and asset tracking.
-
Relevance and Importance
- Minimizes energy consumption and signaling traffic, crucial for massive IoT deployments in 5G networks.
- Facilitates low-latency communication and improved network efficiency by bypassing full RRC resumption procedures for eligible small data transmissions.
- Supports advanced 5G use cases by providing scalable mechanisms for device connectivity and data transfer in dense, heterogeneous network environments.
-
Tutorial Objectives and Learning Outcomes
- Gain an understanding of the SDT feature in the context of 5G NR RRC states and procedures.
- Learn the architectural distinctions and operational principles of RA-SDT (Random Access-based) and CG-SDT (Configured Grant-based) mechanisms.
- Understand the configuration steps required at the gNB to enable and optimize SDT for eligible user data flows.
- Acquire practical knowledge for identifying scenarios where SDT is applicable and for troubleshooting typical deployment challenges.
-
Prerequisite Knowledge and Skills
- Familiarity with 5G NR architecture, including gNB functional components and RRC state machine.
- Understanding of radio resource management concepts and 5G signaling procedures.
- Basic experience with network configuration, particularly in 5G or LTE environments.
- General knowledge of IoT use cases and their requirements for energy and signaling efficiency.
Summary of the Tutorial
This tutorial focuses on testing Small Data Transmission (SDT) using two main procedures: RA-SDT (Random Access-based SDT) with 2-Step RACH and CG-SDT (Configured Grant-based SDT), both in FDD mode. The testing is performed using Amarisoft UEsim and specified configurations for core network, gNB, DRB, and UE. The following is a summary of the test procedures and methodologies described:
-
Test Setup
- Two setups are described:
- Setup A: Uses a commercial UE.
- Setup B: Uses Amarisoft UEsim as the DUT for UAI support. Setup B is used in this tutorial.
- SIM Card: The SIM provided with the system is used as-is.
- Configuration: If custom configuration is needed, additional guidance is provided in referenced configuration guides.
- Two setups are described:
-
Key Configuration Parameters
- The tutorial highlights several essential configuration parameters for SDT operation, such as sdt, rsrp_threshold, logical_channel_sr_delay_timer, ul_data_volume_threshold, t319a, session_inactivity_timer, and more.
- Additional configurations related to RRC Inactive, 2-Step RACH, and Configured Grant are required for the SDT environment.
-
Test 1: RA-SDT (FDD with 2-Step RACH)
-
Configuration Steps:
- Modify and use gnb-sa-sdt-2step-rach.cfg for the gNB, drb_nr_sdt.cfg for DRB, and ue-nr-sa-fdd-20Mhz-sdt.cfg for UEsim.
- Set the cell to FDD mode and configure the appropriate band and ARFCN.
- Configure the sdt parameter block in rrc_inactive, including parameters like rsrp_threshold, ul_data_volume_threshold, and t319a.
- Set prach_feature_preambles_list in the RACH configuration; adjust time_domain_offset if CRC errors appear in MsgA.
- Optionally set rx_to_tx_latency to 2.
- For DRB, ensure sdt_allowed is set to true for the test's 5QI.
- Enable cn_assistance_info_support in mme-ims-cn-assistance.cfg for RRC Inactive support.
- On UEsim, set FDD mode, match band and frequency to gNB, enable rrc_inactive_support, and set as_release to 17.
-
Test Execution:
- Verify the cell configuration before starting.
- Start trace mode ('t' command) and wait for UE connection.
- Allow UE to attach and enter RRC Inactive state after idle timeout.
- Generate uplink user data (e.g., by executing a ping from UEsim or using an app on commercial UE).
-
Log Analysis:
- Check SIB1 configurations; verify msgA-ConfigCommon contains smallData-r17.
- Ensure msgA-PUSCH-TimeDomainOffset-r16 is properly set for timing alignment.
- Confirm gNB advertises SDT capability and criteria for SDT trigger.
- Verify UE capability information includes SDT support.
- Validate the UE enters RRC Inactive state with SDT configuration and can trigger SDT by sending PRACH with the relevant feature index.
- Observe RRC Resume procedure and initiation of SDT session upon user data generation.
-
Configuration Steps:
-
Test 2: CG-SDT (FDD with Configured Grant)
-
Configuration Steps:
- Modify and use gnb-sa-cg-sdt.cfg for the gNB and drb_nr_sdt.cfg for DRBs.
- Set cell to FDD mode, enable CG_SDT, and configure appropriate FDD band and ARFCN.
- Adjust RACH Occasion settings (ssb_per_prach_occasion, cb_preambles_per_ssb) for CG SDT.
- Configure feature_combination and feature_priorities for SDT.
- Place sdt and configuration_grant configuration under rrc_inactive.
- As with RA-SDT, ensure sdt_allowed is true for the test's 5QI in the DRB file.
- Enable cn_assistance_info_support in the MME configuration.
- On UEsim, set FDD mode, configure band/frequency, enable rrc_inactive_support, and set as_release to 17.
-
Test Execution:
- Confirm the cell configuration.
- Run trace mode and wait for UE connection.
- UE attaches, then transitions to RRC Inactive after timeout.
- Trigger uplink data (e.g., ping from UEsim or commercial UE).
-
Log Analysis:
- Check SIB1 for featureCombinationPreambleList containing smallData-r17.
- Verify gNB and UE both advertise CG-SDT and RA-SDT support and capabilities.
- Ensure UE supports configured grant for SDT (check cg-SDT-r17 and ra-SDT-r17 in UE capability information).
- UE should enter RRC Inactive with the correct SDT configuration; for CG-based SDT, all CG configuration is embedded in sdt-Config-r17.
- Observe PRACH with prach_feature_index for SDT, followed by RRC Resume and SDT session initiation.
- For PUSCH, logs may show error icons for unused slots, which is normal if no user data is present; successful SDT transfers are indicated with specific log messages.
-
Configuration Steps:
Overall, the tutorial provides detailed step-by-step procedures for configuring and verifying both RA-SDT and CG-SDT in an NR FDD environment using Amarisoft tools, with emphasis on correct configuration and log verification for SDT feature enablement and operation.
Test Setup
Test setup for this tutorial is as shown below. This is just for low layer testing, you may not need any complicated IP layer setup.
- SIM Card used in this tutorial is the one delivered with the system as it is.
- If you want to change the configuration, The tutorial Configuration Guide would help
Use Setup A for a commercial UE or Setup B for Amarisoft UEsim. In this test, Setup B is used.
Setup A
This setup uses a commercial UE as DUT
The commercial UE talks to the callbox over the air. The callbox uses one SDR card with external antennas.

Setup B
This setup is the case where you use a commerical Amarisoft UEsim as a DUT supporting UAI (UE-Assistance Information)
The callbox and the UEsim are connected by RF cables between their SDR cards. Four cables link the ports of the callbox to the ports of the UEsim. No antenna is used in this setup.

Key Configuration Parameters
Followings are important configuration parameters for this tutorial. You may click on the items for the descriptions from Amarisoft documents.
- sdt
- rsrp_threshold
- logical_channel_sr_delay_timer
- ul_data_colum_threshold
- t319a
- session_inactivity_timer
- session_max_duration
- continue_rohc_context
- configured_grant (CG-SDT only)
- prach_feature_preambles_list
- feature_combination
- preambles_per_ssb
- two_steps_prach (RA-SDT with 2 step RACH only)
- feature_priorities.sdt
- drb_config.sdt_allowed
NOTE : For simplicity, I listed configuration parameters which are directly related to SDT, but you sould need additional configuration to set an enviroment for SDT to be used (e.g, RRC Inactive, 2 Step RACH, Configured Grant etc). You can refer to following tutorials related to the additional configurations.
- RRC Inactive Configuration Parameters
- 2 Step RACH Configuration Parameters
- CG Configuration Parameters
Test 1 : RA-SDT : FDD with 2 Step RACH
This test is to show how to configure RA-SDT (i.e, SDT via RACH, 2 step rach in this tutorial).
Configuration
The configuration shown here is common configuration for all the subtests belonging to Test 1 and I will not show this configuration repeatedly for every subtest.
I have used gnb-sa-sdt-2step-rach.cfg which is copied and modified from gnb-sa.cfg on Callbox (gNB) and used drb_nr_sdt.cfg which is copied and modified from drb_nr.cfg

I am using mme-ims-cn-assistance.cfg and ims config as shown below.

On UEsim, I used ue-nr-sa-fdd-20Mhz-sdt.cfg which has been copied and modified from ue-nr-sa.cfg (

gnb-sa-sdt-2step-rach.cfg is configured as follows.
First I configured the cell as an FDD Cell for this specific test (NR_TDD 0)
The other defines are FR2 0, N_ANTENNA_DL 2, N_ANTENNA_UL 1 and NR_BANDWIDTH 20. USE_SRS is 0.
CONTINUE_ROHC is set to 0. This keeps the continue_rohc_context line inside the sdt block disabled in this test.

And specify the FDD band and ARFCN as you like (band, dl_nr_arfcn)
Because NR_TDD is 0, the #else branch at the bottom is the one in use. It sets band 7 and dl_nr_arfcn 531000. ssb_subcarrier_spacing is 15 and subcarrier_spacing is 30 kHz. ssb_pos_bitmap is "1000".
The n78 and band 257 branches above it are for TDD and FR2. They are not used in this test.

The important setting is sdt configuration within rrc_inactive block(
I configured sdt within the rrc_inactive block. sdt is then used when its criteria are met while the UE is in rrc_inactive state. rsrp_threshold -110 is broadcast as sdt-RSRP-Threshold-r17. ul_data_volume_threshold 800 becomes sdt-DataVolumeThreshold-r17, and t319a 400 becomes t319a-r17. You will find these three values again in SIB1 in the Log Analysis section.
session_inactivity_timer is 100 and session_max_duration is 250. If there is no transmission during session_inactivity_timer, the gNB suspends the RRC connection again. If the SDT session lasts longer than session_max_duration, the gNB resumes the RRC connection. continue_rohc_context "cell" sits inside #if CONTINUE_ROHC. It is not used in this test because CONTINUE_ROHC is 0.
The rest of rrc_inactive is the usual setting. ran_paging_cycle is 32, inactivity_timer is 5000, t380_mins is 10 and release_timer_mins is 15. rna_cell_list carries plmn "00101" and cell_id_list [0x1234501].

Another important setting for RA-SDT (RACH based SDT) is to configure prach_freature_preambles_list within the rach configuration. (
The rach related settings are in nr_cell_default. bandwidth, n_antenna_dl and n_antenna_ul there take NR_BANDWIDTH, N_ANTENNA_DL and N_ANTENNA_UL from the defines.

The global two_steps_prach block is the default two step rach configuration. It is used for the two step rach that is not for sdt, e.g, two step rach for initial attach. shared_ro has cb_preambles_per_ssb_per_sro 16. msga_pusch uses mcs 5, time_domain_offset 6, l_crb 1 and po_fdm 4. msga_rsrp_threshold is -110, msgb_response_window is 40 and msgb_mcs is 9.
prach_feature_preambles_list defines the preamble partition for sdt. feature_combination ["sdt"] sets the combination of features for this partition to sdt. preambles_per_ssb is 4. I did not set preamble_start. It then defaults to cb_preambles_per_ssb plus cb_preambles_per_ssb_per_sro. In this run that is 8 plus 16, so the partition starts at preamble 24.
The two_steps_prach inside the partition inherits the global two_steps_prach. It overwrites only the values given here: time_domain_offset 5, l_crb 4, po_fdm 2 and mcs 12. Everything else comes from the global block. feature_priorities sets sdt to 1.

This may not be a mandatory setting, but I would recommend to set rx_to_tx_latency 2.
rx_to_tx_latency 2 sits next to k_min 4 in the cell configuration.
![]()
Since SDT is associated with a specific DRB, a specific drb file configured for sdt is used.
drb_config points to "drb_nr_sdt.cfg". This is a user specific drb file made from the default drb file.

drb_nr_sdt.cfg is configured as follows
For this configuration, you need to figure out which DRB/5QI will be used in your test, set sdt_allowed to true for the specific 5QI that will be used in your test. (
In this test the traffic uses qci 9, so I set sdt_allowed : true in that drb block. The default is false. With sdt_allowed true, and if the UE supports SDT, the bearer is configured for SDT when the RRC connection is suspended.
The rest of the block is the normal DRB setting. logical_channel_config uses priority 13 and logicalChannelGroup 7. "5qi_qos" has priority_level 90.

mme-ims-cn-assistance.cfg is configured as shown below.
In mme configuration, enable cn_assistance_info_support to make core network capable of triggering RRC Inactive state.
cn_assistance_info_support: true makes the AMF send a Core Network Assistance Information in the Initial Context Setup. This is a required setting on the core network side to enable the RRC Inactive feature.

ue-nr-sa-fdd-20Mhz-sdt.cfg is configured as shown below. (
Set the UEsim to be FDD (TDD 0).
The other defines are N_ANTENNA_DL 2, CELL_BANDWIDTH 20 and FR2 0.

Set the band and frequency (dl_nr_arfcn) to match the configuration of Callbox (gNB).
With FR2 0 and TDD 0, the #else branch at the bottom is used. It sets band 7, dl_nr_arfcn 531000 and ssb_nr_arfcn 530910. ssb_subcarrier_spacing is 15 and subcarrier_spacing is 30, the same as on the gNB.
The FR2 and TDD branches are not used in this test. This includes rx_to_tx_latency 4 in the FR2 branch. The value that applies is rx_to_tx_latency 2 near the end of the cell, with n_antenna_ul 1.

The key parameter on UEsim is to enable rrc_incative_support parameter. This parameter let UEsim to inform the supportability of rrc-inactive in UE capability information. And set as_release to 17 which let UE notify release 17 capability like SDT.
as_release 17 enables Release 17 features like SDT. rrc_inactive_support true enables RRC inactive. tun_setup_script "ue-ifup" creates the IP interface for each UE PDN. That is what lets you generate packets such as ping from UEsim.

Perform the Test
First check out the cell configuration and see if everything is configured as intended.
cell phy shows one NR cell on n7 with BW 20. DL ARFCN is 531000 and UL ARFCN is 507000, with SCS 30. DL uses 2 antennas and 2 layers, and UL uses 1. The SSB ARFCN is 530910 with SCS 15.
cell shows PCI 500, TAC 0x000064 and PLMN 00101. I also ran log bcch=1 so that SIB1 is written to the log.

run 't' (trace) command and wait for the connection from UE. Here in this example, you see the RACH for initial attach (2 step rach in this case) and then UE gets into RRC inactive state when there is no user traffic for a certain period of time.
The first two PRACH lines, seq=16 and seq=22, are the 2 step rach for initial attach. The UE with RNTI 8c02 exchanges some data and then shows [inactive]. The trace keeps printing [inactive] while the UE is in RRC Inactive state.
After I started the ping, a series of 2 step RACH is triggered by the user traffic. Their seq values are 24 to 27. These are the preambles of the sdt partition in prach_feature_preambles_list.

Once the call state is in RRC Inactive, generate a traffic from UE (i.e, generating mo Data).
I ran ip netns exec ue1 ping 192.168.2.1 on UEsim. The replies come back with time between 12.0 ms and 20.0 ms.

Log Analysis
Following is the log snapshot that are involved in UE assistance information message and handling process.
There are many configurations to be checked in SIB1 for this tutorial.
Check out rach-configCommon. This configuration is not so important for this tutorial but not do harm if you check.
rach-ConfigGeneric uses prach-ConfigurationIndex 16 and zeroCorrelationZoneConfig 15. preambleReceivedTargetPower is -110 and ra-ResponseWindow is sl20. ssb-perRACH-OccasionAndCB-PreamblesPerSSB is one: n8. That gives 8 contention based preambles per SSB before the 2 step RACH and sdt preambles.

The important point of this tutorial is to transfer user data (Small Data) through MsgA. Check out if the IE smallData-r17 is enabled in msgA configuration(msgA-ConfigCommon).
smallData-r17 true sits in featureCombination-r17 of featureCombinationPreamblesList-r17. startPreambleForThisPartition-r17 is 24 and numberOfPreamblesPerSSB-ForThisPartition-r17 is 4. These come from prach_feature_preambles_list. That is why the PRACH for SDT in the trace uses seq 24 to 27.
separateMsgA-PUSCH-Config-r17 carries the msgA PUSCH for this partition. msgA-MCS-r16 is 12 and msgA-PUSCH-TimeDomainOffset-r16 is 5. nrofPRBs-PerMsgA-PO-r16 is 4 and nrofMsgA-PO-FDM-r16 is two. These are the values I set in the two_steps_prach inside the sdt partition.

This may not be mandatory configuration directly related to RA-SDT, but as far as I tested this seems to be affect a lot for the msgA decoding for SDT. The parameter is msgA-PUSCH-TimeDomainOffset-r16 which is set by the configuration parameter 'time_domain_offset'. This is time difference(gap) in slot between PRACH and MsgA.
This msgA-PUSCH-Config-r16 is the Message A configuration for the 2 step RACH that is not for SDT. msgA-PUSCH-TimeDomainOffset-r16 is 6, from time_domain_offset 6 in the global two_steps_prach. msgA-MCS-r16 is 5, nrofPRBs-PerMsgA-PO-r16 is 1 and nrofMsgA-PO-FDM-r16 is four. The SDT partition uses its own offset of 5.

Then make sure that gNB notifies that it is capable of SDT and criteria for triggering SDT. Check out sdt-ConfigCommon-r17 and featureProiorities-r17.
sdt-ConfigCommon-r17 indicates that this cell supports SDT. sdt-RSRP-Threshold-r17 is 46, sdt-DataVolumeThreshold-r17 is byte800 and t319a-r17 is ms400. These come from rsrp_threshold -110, ul_data_volume_threshold 800 and t319a 400 in the sdt block. featurePriorities-r17 carries sdt-Priority-r17 1 from feature_priorities.

Now check out UE capability to check if UE support the feature (SDT)
The gNB sends UE capability enquiry with rat-Type nr. The capabilityRequestFilter asks for bandNR 7.

Make it sure that UE support RA SDT by checking out the IE ra-SDT-r17 in UE capability Information message.
ra-SDT-r17 supported indicates that the UE supports SDT via RACH. The same UE capability information also carries inactiveState supported.

Now power on UE and wait until UE gets into connected state. If there is no traffic for a certain period of time, the call state gets into RRC Inactive. Make it sure that it gets into the RRC Inactive state with sdt-Config-r17 configured.
suspendConfig in RRC release indicates that the call status is getting into RRC Inactive. It carries fullI-RNTI '1234508C02'H, shortI-RNTI '508C02'H, ran-PagingCycle rf32 and t380 min10. ran-NotificationAreaInfo lists ran-AreaCells '001234501'H.
sdt-Config-r17 setup carries sdt-DRB-List-r17 with DRB 1. This enables SDT on that DRB, which comes from sdt_allowed in drb_nr_sdt.cfg. After the release, NGAP sends the RRC inactive transition report and the gNB prints set UE to inactive state.

Then power on UE and wait until UE complete the initial connection and got into RRC Inactive state.
At this point, ping from UEsim (or commercial UE). Then UE would send PRACH with prach_feature_index. This indicates that the PRACH is for SDT.
The PRACH line is sequence_index=26 ta=2 prb=3:3 two_steps=1 prach_feature_index=0 snr=29.2. prach_feature_index=0 points to the partition with feature_combination ["sdt"].
Right after the PRACH, the gNB allocates a new UE. The IP/ICMP packet 192.168.2.2 > 192.168.2.1 goes out over GTPU, and the reply 192.168.2.1 > 192.168.2.2 comes back. The RRC resume request then comes on CCCH-NR. The gNB resumes the connection of ue_id 0x0002, whose old C-RNTI was 0x8c02, and prints Start SDT session.

Then you see RRC Resume is initiated and SDT session starts.
rrcResumeRequest carries resumeIdentity '508C02'H. This is the shortI-RNTI given in suspendConfig. resumeMAC-I is 'B693'H and resumeCause is mo-Data.
Right after it, the gNB prints Start SDT session and re-establishes PDCP on DRB1. The ping data then goes over DRB1. The next PRACH with sequence_index=25 and prach_feature_index=0 follows a few slots later.

Test 2 : CG-SDT : FDD
This test is to show how to configure CG-SDT(i.e, SDT via Configuration Granted Physical channel).
Configuration
The configuration shown here is common configuration for all the subtests belonging to Test 1 and I will not show this configuration repeatedly for every subtest.
I have used gnb-sa-cg-sdt.cfg which is copied and modified from gnb-sa.cfg on Callbox (gNB) and used drb_nr_sdt.cfg which is copied and modified from drb_nr.cfg

I am using mme-ims-cn-assistance.cfg and ims config as shown below.

On UEsim, I used ue-cg-sdt.cfg which has been copied and modified from ue-nr-sa.cfg (

gnb-sa-cg-sdt.cfg is configured as follows.
First I configured the cell as an FDD Cell for this specific test (NR_TDD 0). Set CG_SDT to 1 so that the configuration related to CG-SDT are configured.
N_ANTENNA_DL and N_ANTENNA_UL are both 1 in this test. SDT_TSRA and SDT_REDCAP are 0, so the two step rach and RedCap parts of this file are not used. CG_SDT 1 enables and configures CG_SDT.

And specify the FDD band and ARFCN as you like (band, dl_nr_arfcn)
band is 7. Since SDT_REDCAP is 0, the #else branch is used, with dl_nr_arfcn 536000 and bandwidth 20. The SDT_REDCAP branch with 531000 and bandwidth 40 is not used.
Under #if CG_SDT, ssb_pos_bitmap is "1111" instead of "1000". ssb_period is 5 ms and n_id_cell is 500.

Change RO(RACH Occation) configuration (ssb_per_prach_occasion, cb_preambles_per_ssb) a little bit to bettr fit for CG SDT
Under #if CG_SDT, ssb_per_prach_occasion is 4 and cb_preambles_per_ssb is 4. Without CG_SDT they would be 1 and 8.
The rest of prach is the usual set. prach_config_index is 16, zero_correlation_zone_config is 15 and preamble_received_target_power is -110. ra_response_window is 20 and ra_contention_resolution_timer is 64 ms.

Set prach features preambles and feature priorities to SDT (feature_combination, feature_priorities).
The two_steps_prach blocks sit under #if SDT_TSRA. They are not used in this test because SDT_TSRA is 0. The sdt partition therefore uses 4 step RACH.
In prach_feature_preambles_list, feature_combination is ["sdt"] and preambles_per_ssb is 4. feature_priorities sets sdt to 1. redcap 2 is under #if SDT_REDCAP and is not used.

Configure rrc_inactive feature and put sdt configuration and configuration_grant configuration in it.
rrc_inactive uses ran_paging_cycle 32, use_full_resume_id true, t380_mins 10 and release_timer_mins 15. Inside it, sdt uses rsrp_threshold -110, ul_data_volume_threshold 800 and t319a 600. session_inactivity_timer is 100 and session_max_duration is 480.
configured_grant is configured within sdt under #if CG_SDT. This is what adds CG-SDT support. rsrp_threshold_ssb is -110 and time_alignment_timer is 1280. ssb_per_cg_pusch is 1 and dmrs_ports_bitmap is "0101".
grant defines the UL grant in the initial BWP. It uses l_crb 4, mcs 10 and periodicity 40, with skip_uplink_tx_snr_threshold 1.0. If you want CG occasions more or less often, change periodicity. It should be larger than 5 milliseconds.

Since SDT is associated with a specific DRB, a specific drb file configured for sdt is used.
drb_config points to "drb_nr_sdt.cfg", the same drb file as in Test 1.

drb_nr_sdt.cfg is configured as follows
For this configuration, you need to figure out which DRB/5QI will be used in your test, set sdt_allowed to true for the specific 5QI that will be used in your test. (
This is the same drb_nr_sdt.cfg as in Test 1. sdt_allowed : true is set in the qci 9 block.

mme-ims-cn-assistance.cfg is configured as shown below.
In mme configuration, enable cn_assistance_info_support to make core network capable of triggering RRC Inactive state.
This is the same setting as in Test 1, with cn_assistance_info_support true.

ue-cg-sdt.cfg is configured as shown below. (
Set the UEsim to be FDD (TDD 0).
N_ANTENNA_DL and N_ANTENNA_UL are 1. SDT_TSRA and SDT_REDCAP are 0, the same as on the gNB.

Set the band and frequency (dl_nr_arfcn) to match the configuration of Callbox (gNB).
band is 7. With SDT_REDCAP 0, the #else branch is used. dl_nr_arfcn is 536000 (2680 MHz), ssb_nr_arfcn is 535970 and bandwidth is 20. These match the gNB.
rx_to_tx_latency is set to 3. global_timing_advance is 6 and multi_ue is true.

The key parameter on UEsim is to enable rrc_incative_support parameter. This parameter let UEsim to inform the supportability of rrc-inactive in UE capability information. And set as_release to 17 which let UE notify release 17 capability like SDT.
as_release 17 enables Release 17 features like SDT. rrc_inactive_support true enables RRC inactive. redcap true is under #if SDT_REDCAP and is not used.
apn "internet" is the APN that the UE requests for the PDU session. tun_setup_script "ue-ifup" creates the IP interface used for ping from UEsim.

Perform the Test
First check out the cell configuration and see if everything is configured as intended.
cell phy shows one NR cell on n7 with BW 20. DL ARFCN is 536000 and UL ARFCN is 512000, with SCS 30. DL and UL both use 1 antenna and 1 layer. The SSB ARFCN is 535970 with SCS 15. cell shows PCI 500 and PLMN 00101.

run 't' (trace) command and wait for the connection from UE. Here in this example, you see the RACH for initial attach (2 step rach in this case) and then UE gets into RRC inactive state when there is no user traffic for a certain period of time.
The first PRACH, seq=51, is the 4 step rach for initial attach. The UE with RNTI 4601 then shows [inactive] and stays in RRC Inactive state.
After I started the ping, 4 step RACH is triggered by the user traffic, with seq 52 and 53. This test uses 4 step RACH because SDT_TSRA is 0.

Once the call state is in RRC Inactive, generate a traffic from UE (i.e, generating mo Data).
I ran ip netns exec ue1 ping 192.168.3.1 on UEsim. The replies come back with time between 22.1 ms and 37.0 ms.

Log Analysis
Following is the log snapshot that are involved in UE assistance information message and handling process.
There are many configurations to be checked in SIB1 for this tutorial.
Check out rach-configCommon. In this test, SDT will be associated with 4 Step RACH as well as with CG (Configured Grant). Check out if featureCombinationPreambleList carries the smallData-r17 within featureCombination-r17.
ssb-perRACH-OccasionAndCB-PreamblesPerSSB is four: 4. This comes from ssb_per_prach_occasion 4 and cb_preambles_per_ssb 4.
featureCombinationPreamblesList-r17 sits directly in rach-ConfigCommon this time, not in a msgA configuration. Its featureCombination-r17 carries smallData-r17 true. startPreambleForThisPartition-r17 is 4 and numberOfPreamblesPerSSB-ForThisPartition-r17 is 4.

Then make sure that gNB notifies that it is capable of SDT and criteria for triggering SDT. Check out sdt-ConfigCommon-r17 and featureProiorities-r17.
sdt-RSRP-Threshold-r17 is 46, sdt-DataVolumeThreshold-r17 is byte800 and t319a-r17 is ms600. featurePriorities-r17 carries sdt-Priority-r17 1.
useFullResumeID is true, from use_full_resume_id true. ssb-PositionsInBurst is inOneGroup 'F0'H. This is the four SSBs from ssb_pos_bitmap "1111".

Now check out UE capability to check if UE support the feature (SDT)
The gNB sends UE capability enquiry with rat-Type nr and bandNR 7. The UE capability information that follows carries the IEs checked in the next three steps.

Make it sure that UE support configured grant since this test is for SDT associated with CG (Configured Grant)
configuredUL-GrantType1 supported and configuredUL-GrantType2 supported in phy-ParametersCommon indicate the support of CG.

Make it sure that UE support CG SDT by checking out the IE cg-SDT-r17 in UE capability Information message.
cg-SDT-r17 supported indicates the support of cg-sdt.

Make it sure that UE support RA SDT by checking out the IE ra-SDT-r17 in UE capability Information message.
ra-SDT-r17 supported indicates the support of ra-sdt. The UE needs it here because the gNB also offers SDT on the 4 step RACH partition. inactiveState supported is in the same message.

Now power on UE and wait until UE gets into connected state.
If there is no traffic for a certain period of time, the call state gets into RRC Inactive.
RRC release carries suspendConfig and switches the UE to RRC Inactive state. fullI-RNTI is '1234504601'H and shortI-RNTI is '504601'H. ran-PagingCycle is rf32 and t380 is min10.
This time ran-NotificationAreaInfo uses ran-AreaConfigList with trackingAreaCode '000000'H. After the release, NGAP reports the RRC inactive transition and the gNB prints set UE to inactive state.

Make it sure that it gets into the RRC Inactive state with sdt-Config-r17 configured. In case of CG based SDT, all the details of the CG configuration should be embedded within sdt-Config-r17.
sdt-Config-r17 carries sdt-DRB-List-r17 with DRB 1. sdt-MAC-PHY-CG-Config-r17 carries the CG for the initial BWP in cg-SDT-ConfigInitialBWP-NUL-r17. periodicity is sym40x14 and mcsAndTBS is 10, from periodicity 40 and mcs 10 in grant. nrofHARQ-Processes is 1 and repK is n1.
cg-SDT-Configuration-r17 has sdt-SSB-Subset-r17 shortBitmap 'F'H and sdt-SSB-PerCG-PUSCH-r17 one. sdt-DMRS-Ports-r17 is dmrsType1 '0A'H. cg-SDT-TimeAlignmentTimer-r17 is ms1280 and cg-SDT-RSRP-ThresholdSSB-r17 is 46. cg-SDT-CS-RNTI-r17 is 17922.

Then power on UE and wait until UE complete the initial connection and got into RRC Inactive state.
At this point, ping from UEsim (or commercial UE). Then UE would send PRACH with prach_feature_index. This indicates that the PRACH is for SDT. Then you see RRC Resume is initiated and SDT session starts.
The PRACH line is sequence_index=53 ta=0 prb=3:3 prach_feature_index=0 ssb_index=3. prach_feature_index=0 points to the partition with feature_combination ["sdt"]. The RAR carries rapid=53.
The ping packet 192.168.3.2 > 192.168.3.1 goes out over GTPU, and the reply comes back. The RRC resume request comes on CCCH-NR. The gNB resumes ue_id 0x0001, whose old C-RNTI was 0x4601, and prints Start SDT session.

You may see a lot of PUSCH marked as a error icon, but this is not really errors. The PUSCH with error followed by the message 'CG-SDT was skipped. do not request retransmission' indicates 'this slot is allowed for PUSCH, but UE does not send PUSCH because there is no user data to send'.
If the PUSCH carries the user data (SDT data in this case), you will see the additional log print like 'cg_sdt, cg_sdt_pusch_idx, cg_sdt_ssb_idx'.
In this run, the CG PUSCH comes every 20 ms on prb=37:4 with tb_len=185. Most of them are followed by CG-SDT was skipped, do not request retransmission. The UE is allowed to send PUSCH as per CG, but it did not send it because there was no user data.
The PUSCH at 18:03:34.685 carries the SDT data. It prints cg_sdt=1 cg_sdt_pusch_idx=3 cg_sdt_ssb_idx=3. The gNB then prints Resuming connection of ue_id 0x0001 with CG-SDT and Start SDT session. The ping packet 192.168.3.2 > 192.168.3.1 is then forwarded over GTPU.
