5G RRC Java Sample Code Using OSS ASN.1 Tools


This sample is provided as part of the OSS ASN.1 Tools trial and commercial shipments. The source code and related files are listed below for reference.

The sample demonstrates how to use the OSS ASN.1 Tools to process messages for the 3GPP 5G RRC standard (TS 38.331 version 19.0.0).

It runs on Linux on x86-64 as an example and illustrates how to decode, inspect, and create PER Unaligned 5G RRC messages using the OSS ASN.1 Tools API.

The sample reads RRC messages from .uper files, decodes and prints them, accesses message components, and creates and encodes a response message.

A Unix shell script (run.sh) is included for running the test program using the OSS ASN.1/Java runtime.

To explore more samples (LTE RRC, 5G RRC, S1AP, X2AP, NGAP), visit the main Sample Code page.

Overview

This sample shows how to:

  • Initialize the OSS ASN.1/Java runtime for the 5G RRC schema.
  • Read .uper files that contain valid PER-encoded 5G RRC messages.
  • Decode and print 5G RRC messages.
  • Access RRC message components.
  • Create and encode a response message (for example, for SecurityModeCommand).
  • Run the sample test program using the provided run.sh script.

Files in This Sample

The files listed below are included in the OSS ASN.1 Tools trial and commercial shipments and are used by this sample program:

File Description
README.TXT Instructions and sample overview.
rrc.asn ASN.1 file that describes the 3GPP 5G RRC protocol (TS 38.331), used with this program example.
rrc-directives.dir Additional directives for rrc.asn.
RRCRelease.uper Valid RRCRelease message encoded with PER Unaligned.
SecurityModeCommand.uper Valid SecurityModeCommand message encoded with PER Unaligned.
Trrc.java Simple Java program that shows how to work with 5G RRC protocol data. It reads input messages from files, decodes and prints them, accesses message components, and creates and encodes a response message for SecurityModeCommand.
rrc.cmd ASN.1 compiler command file used to ASN.1-compile the 5G RRC specifications.
run.sh Unix shell script that runs the sample test.
sample.out Expected output from this test.
gui/ ASN.1 Studio project for viewing/compiling schema and generating sample data.

Build and Run Instructions

(Installation instructions for the OSS ASN.1 Tools are included in all trial and commercial shipments.)

To build and run this sample, install a trial or licensed version of the OSS ASN.1 Tools for Java.

1. Verify environment variables

Before running the test, ensure the following are set appropriately:

  • OSS_ASN1_JAVA
  • CLASSPATH
  • PATH
2. Run the sample
./run.sh
3. Clean up generated files
./run.sh cleanup
4. Other Platforms

Note: The Java source code in this sample is platform-independent. Linux commands are shown as an example, but equivalent samples and build instructions are available for Windows, macOS, and other platforms. For help with platform-specific instructions, please contact OSS Support.

Code Listing: Trrc.java

The following listing shows the main Java source file for this sample test program, Trrc.java. It demonstrates how to read PER-encoded 5G RRC messages from files, decode and print them, and create and encode a response message using the OSS ASN.1 Tools API.

Show Trrc.java source code
/*****************************************************************************/
/* Copyright (C) 2025 OSS Nokalva, Inc.  All rights reserved.                */
/*****************************************************************************/
/* THIS FILE IS PROPRIETARY MATERIAL OF OSS NOKALVA, INC.                    */
/* AND MAY BE USED ONLY BY DIRECT LICENSEES OF OSS NOKALVA, INC.             */
/* THIS FILE MAY NOT BE DISTRIBUTED.                                         */
/* THIS COPYRIGHT STATEMENT MAY NOT BE REMOVED.                              */
/*****************************************************************************/
/* THIS SAMPLE PROGRAM IS PROVIDED AS IS. THE SAMPLE PROGRAM AND ANY RESULTS */
/* OBTAINED FROM IT ARE PROVIDED WITHOUT ANY WARRANTIES OR REPRESENTATIONS,  */
/* EXPRESS, IMPLIED OR STATUTORY.                                            */
/*****************************************************************************/
/*
 * $Id: 5G-rrc-java.html 3327 2026-01-06 10:07:48Z macra $
 */

/*
 * Demonstrates part of RRC protocol layer of an 5G UE stack.
 */

import java.io.*;

import com.oss.asn1.*;
import com.oss.util.*;

import rrc.*;
import rrc.oss_rrc_nr_rrc_definitions.*;

public class Trrc {

    static Coder coder;
    static String border = "-------------------------------------------------------";

    /*
     * Decodes and prints the input messages; creates, encodes and prints
     * the output (response) messages.
     */
    public static void main(String[] args)
    {
	// Initialize the project
	try {
	    Rrc.initialize();
	} catch (Exception e) {
	    System.out.println("Initialization exception: " + e);
	    System.exit(1);
	}

	coder = Rrc.getPERUnalignedCoder();
	coder.enableAutomaticEncoding();
	coder.enableAutomaticDecoding();
	coder.enableEncoderDebugging();
	coder.enableDecoderDebugging();

	// An optional parameter includes the path to all the files that are used by
	// the program.
	String path = (args.length > 0) ? args[0] : null;

	try {
	    testDL_DCCH_Message(path, "RRCRelease.uper");
	} catch (Exception e) {
	    System.out.println(e);
	}

	try {
	    testDL_DCCH_Message(path, "SecurityModeCommand.uper");
	} catch (Exception e) {
	    System.out.println(e);
	}
	System.out.println("\nTesting successful");
    }

    /*
     * Represents am imcomplete implementation of UE-side function processing
     * a downlink DCCH message. It decodes the message, prints it, and creates
     * a response for some particular alternatives. The function can be used
     * to implement a complete 5G RRC UE-side dispatcher.
     */
    static void testDL_DCCH_Message(String path, String filename) throws IOException, Exception
    {
	OSS_RRC_DL_DCCH_Message 	request;
	OSS_RRC_UL_DCCH_Message 	response;

	File file = new File(path, filename);
	if (!file.exists()) {
	    throw new IOException("Failed to open the " + file.toString() + " file. " +
		"Restart the sample program using as input parameter the name of the directory " +
		"where the '" + file.getName() + "' file is located.\n");
	}
	FileInputStream source = new FileInputStream(file);

	System.out.println("============================================================================");
	System.out.println("Read encoding from file: " + filename + "\n");
	System.out.println("Decoding the input downlink DCCH message");
	System.out.println(border);
	/* Deserialize input message */
        request = (OSS_RRC_DL_DCCH_Message)coder.decode(
    			    source, new OSS_RRC_DL_DCCH_Message());
	source.close();
	System.out.println("\nPDU decoded");

	if (!request.getMessage().hasC1()) {
	    throw new Exception("Incorrect message");
	}

	OSS_RRC_DL_DCCH_MessageType.C1 msg_typ = request.getMessage().getC1();
	System.out.println(border);
	switch (msg_typ.getChosenFlag()) {
	    /* You can take unimplemented CHOICE alternatives one by
	     * one and add support for them */
	    case OSS_RRC_DL_DCCH_MessageType.C1.rrcReconfiguration_chosen:
		System.out.println("Unimplemented");
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.rrcResume_chosen:
		System.out.println("Unimplemented");
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.rrcRelease_chosen:
		System.out.println(request);
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.rrcReestablishment_chosen:
		System.out.println("Unimplemented");
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.securityModeCommand_chosen:
		/* Print deserialized message */
		System.out.println(request);
		System.out.println("Creating response");
		System.out.println(border);
		/* Create response */
		response = createSecurityModeCommandResponse(request);

		System.out.println();
		System.out.println("Response created successfully");
		System.out.println(border);
		/* Print outcome message */
		System.out.println(response);
		System.out.println("Encoding response");
		System.out.println(border);
		/* Serialize outcome message */
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
		    coder.encode(response, out);
		    out.close();
		} catch (Exception e) {
		    System.out.println("Encoding failed: " + e);
		    System.exit(1);
		}

		/* Print serialized outcome message */
		System.out.println("\nEncoded response "
				+ "(" + out.size() + " bytes):");
		System.out.println(HexTool.getHex(out.toByteArray()));
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.dlInformationTransfer_chosen:
		/* Print deserialized message */
		System.out.println(request);
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.ueCapabilityEnquiry_chosen:
		System.out.println("");
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.counterCheck_chosen:
		System.out.println("Unimplemented");
		break;
	    case OSS_RRC_DL_DCCH_MessageType.C1.mobilityFromNRCommand_chosen:
		System.out.println("Unimplemented");
		break;
	    default:
		System.out.println("Unknown CHOICE alternative selected");
		break;
	}
    }

    /*
     * Creates an OSS_RRC_UL_DCCH_Message PDU (security mode complete)
     * for given OSS_RRC_DL_DCCH_Message PDU (security mode command).
     */
    static OSS_RRC_UL_DCCH_Message createSecurityModeCommandResponse(
				OSS_RRC_DL_DCCH_Message request)
    throws IOException, Exception
    {
	OSS_RRC_IntegrityProtAlgorithm ipalg;
	OSS_RRC_CipheringAlgorithm calg;

	if (!request.getMessage().hasC1()
	    || !request.getMessage().getC1().hasSecurityModeCommand()
	    || !request.getMessage().getC1().getSecurityModeCommand()
                                             .getCriticalExtensions()
                                             .hasSecurityModeCommand())
	    throw new Exception("cannot handle ASN.1 data");



	ipalg = request.getMessage()
                        .getC1()
                        .getSecurityModeCommand()
                        .getCriticalExtensions()
                        .getSecurityModeCommand()
                        .getSecurityConfigSMC()
                        .getSecurityAlgorithmConfig()
                        .getIntegrityProtAlgorithm();

	calg = request.getMessage()
                       .getC1()
                       .getSecurityModeCommand()
                       .getCriticalExtensions()
                       .getSecurityModeCommand()
                       .getSecurityConfigSMC()
                       .getSecurityAlgorithmConfig()
                       .getCipheringAlgorithm();

	if (ipalg != OSS_RRC_IntegrityProtAlgorithm.nia0
		&& ipalg != OSS_RRC_IntegrityProtAlgorithm.nia1
		&& ipalg != OSS_RRC_IntegrityProtAlgorithm.nia2)
	    throw new Exception("unknown integrity protection");

	if (calg != OSS_RRC_CipheringAlgorithm.nea0
		&& calg != OSS_RRC_CipheringAlgorithm.nea1
		&& calg != OSS_RRC_CipheringAlgorithm.nea2)
	    throw new Exception("unknown ciphering");

	OSS_RRC_RRC_TransactionIdentifier transactionIdentifier =
		request.getMessage()
                        .getC1()
                        .getSecurityModeCommand()
                        .getRrc_TransactionIdentifier();
	OSS_RRC_SecurityModeComplete.CriticalExtensions criticalExtensions =
	    OSS_RRC_SecurityModeComplete.CriticalExtensions.
		createCriticalExtensionsWithSecurityModeComplete(
		    new OSS_RRC_SecurityModeComplete_IEs());
	OSS_RRC_SecurityModeComplete securityModeComplete =
	    new OSS_RRC_SecurityModeComplete(transactionIdentifier, criticalExtensions);
	OSS_RRC_UL_DCCH_MessageType.C1 c1 =
	    OSS_RRC_UL_DCCH_MessageType.C1.createC1WithSecurityModeComplete(securityModeComplete);
	OSS_RRC_UL_DCCH_MessageType message =
	    OSS_RRC_UL_DCCH_MessageType.createOSS_RRC_UL_DCCH_MessageTypeWithC1(c1);
	OSS_RRC_UL_DCCH_Message response = new OSS_RRC_UL_DCCH_Message(message);

	return response;
    }
}

Expected Output (Excerpt)

The following excerpt shows the key stages of running the sample:

============================================================================
Read encoding from file: RRCRelease.uper

Decoding downlink DCCH message
-------------------------------------------------------
Decoded RRCRelease:
  rrc-TransactionIdentifier = 2
  redirectedCarrierInfo:
    carrierFreq = 2
    ssbSubcarrierSpacing = kHz15

PDU decoded successfully
============================================================================
Read encoding from file: SecurityModeCommand.uper

Decoded SecurityModeCommand:
  rrc-TransactionIdentifier = 1
  cipheringAlgorithm = nea0
  integrityProtAlgorithm = nia0

Creating response
-------------------------------------------------------
Response created successfully

Encoding response
-------------------------------------------------------
Encoded UL-DCCH-Message (SecurityModeComplete)

Encoded response (2 bytes):
2A00

Testing successful

Note: The full runtime output includes detailed decode traces for each ASN.1 structure and field. The excerpt above highlights the most relevant steps for clarity.

ASN.1 Schema Excerpt (rrc.asn)

Show excerpt from rrc.asn
-- Excerpt from rrc.asn 3GPP TS 38.331 V19.0.0 (2025-09) 

-- TAG-NR-RRC-DEFINITIONS-START

NR-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=

BEGIN

-- TAG-NR-RRC-DEFINITIONS-STOP

-- TAG-BCCH-BCH-MESSAGE-START

BCCH-BCH-Message ::=            SEQUENCE {
    message                         BCCH-BCH-MessageType
}

BCCH-BCH-MessageType ::=        CHOICE {
    mib                             MIB,
    messageClassExtension           SEQUENCE {}
}

-- TAG-BCCH-BCH-MESSAGE-STOP

-- TAG-BCCH-DL-SCH-MESSAGE-START

BCCH-DL-SCH-Message ::=         SEQUENCE {
    message                         BCCH-DL-SCH-MessageType
}

BCCH-DL-SCH-MessageType ::=     CHOICE {
    c1                              CHOICE {
        systemInformation               SystemInformation,
        systemInformationBlockType1     SIB1
    },
    messageClassExtension           SEQUENCE {}
}

-- TAG-BCCH-DL-SCH-MESSAGE-STOP

-- TAG-DL-CCCH-MESSAGE-START

DL-CCCH-Message ::=             SEQUENCE {
    message                         DL-CCCH-MessageType
}

DL-CCCH-MessageType ::=         CHOICE {
    c1                              CHOICE {
        rrcReject                       RRCReject,
        rrcSetup                        RRCSetup,
        spare2                          NULL,
        spare1                          NULL
    },
    messageClassExtension           SEQUENCE {}
}

-- TAG-DL-CCCH-MESSAGE-STOP

-- TAG-DL-DCCH-MESSAGE-START

DL-DCCH-Message ::=                  SEQUENCE {
    message                             DL-DCCH-MessageType
}

DL-DCCH-MessageType ::=             CHOICE {
    c1                                  CHOICE {
        rrcReconfiguration                  RRCReconfiguration,
        rrcResume                           RRCResume,
        rrcRelease                          RRCRelease,
        rrcReestablishment                  RRCReestablishment,
        securityModeCommand                 SecurityModeCommand,
        dlInformationTransfer               DLInformationTransfer,
        ueCapabilityEnquiry                 UECapabilityEnquiry,
        counterCheck                        CounterCheck,
        mobilityFromNRCommand               MobilityFromNRCommand,
        dlDedicatedMessageSegment-r16       DLDedicatedMessageSegment-r16,
        ueInformationRequest-r16            UEInformationRequest-r16,
        dlInformationTransferMRDC-r16       DLInformationTransferMRDC-r16,
        loggedMeasurementConfiguration-r16  LoggedMeasurementConfiguration-r16,
                spare3 NULL, spare2 NULL, spare1 NULL
    },
    messageClassExtension   SEQUENCE {}
}

-- TAG-DL-DCCH-MESSAGE-STOP

-- TAG-MCCH-MESSAGE-START

MCCH-Message-r17 ::= SEQUENCE {
    message              MCCH-MessageType-r17
}

MCCH-MessageType-r17 ::= CHOICE {
    c1                       CHOICE {
        mbsBroadcastConfiguration-r17     MBSBroadcastConfiguration-r17,
        spare1                            NULL
    },
    messageClassExtension   SEQUENCE {}
}

-- TAG-MCCH-MESSAGE-STOP

-- TAG-MULTICASTMCCH-MESSAGE-START

MulticastMCCH-Message-r18 ::= SEQUENCE {
    message               MulticastMCCH-MessageType-r18
}

MulticastMCCH-MessageType-r18 ::= CHOICE {
    c1                        CHOICE {
        mbsMulticastConfiguration-r18     MBSMulticastConfiguration-r18,
        spare1                            NULL
    },
    messageClassExtension    SEQUENCE {}
}

-- TAG-MULTICASTMCCH-MESSAGE-STOP

-- TAG-PCCH-PCH-MESSAGE-START

PCCH-Message ::=                SEQUENCE {
    message                         PCCH-MessageType
}

PCCH-MessageType ::=            CHOICE {
    c1                              CHOICE {
        paging                          Paging,
        spare1  NULL
    },
    messageClassExtension       SEQUENCE {}
}

-- TAG-PCCH-PCH-MESSAGE-STOP

-- TAG-UL-CCCH-MESSAGE-START


UL-CCCH-Message ::=             SEQUENCE {
    message                         UL-CCCH-MessageType
}

UL-CCCH-MessageType ::=         CHOICE {
    c1                              CHOICE {
        rrcSetupRequest                 RRCSetupRequest,
        rrcResumeRequest                RRCResumeRequest,
        rrcReestablishmentRequest       RRCReestablishmentRequest,
        rrcSystemInfoRequest            RRCSystemInfoRequest
    },
    messageClassExtension           SEQUENCE {}
}

-- TAG-UL-CCCH-MESSAGE-STOP

-- TAG-UL-CCCH1-MESSAGE-START


UL-CCCH1-Message ::=            SEQUENCE {
    message                         UL-CCCH1-MessageType
}

UL-CCCH1-MessageType ::=        CHOICE {
    c1                              CHOICE {
        rrcResumeRequest1               RRCResumeRequest1,
        spare3 NULL,
        spare2 NULL,
        spare1 NULL

    },
    messageClassExtension SEQUENCE {}
}

Using ASN.1 Studio (Optional)

The gui/ subdirectory contains an ASN.1 Studio project for this sample. With ASN.1 Studio you can:

  • Open the 5G RRC ASN.1 modules.
  • Generate code from the ASN.1 schema.
  • Create and edit sample encoded 5G RRC messages.
  • Export projects to a shell script. When exporting trrc.a1sproj, specify Trrc as the "Class or .jar name to execute".

Related Samples

Disclaimer

This sample is provided solely for illustration purposes, for example to demonstrate usage of the OSS ASN.1 Tools API with 3GPP 5G RRC messages. It does not represent a complete application. To build and run this sample, you must use a trial or licensed version of the appropriate OSS ASN.1 Tools. The copyright and license statements included in each source file remain fully applicable.

Need Help?

If you have questions about using this sample, contact OSS Nokalva Support.

See Also

source