The generated source code and related project files are described below.
The sample demonstrates how to decode and encode messages for the 3GPP NG-RAN E1AP standard (TS 37.483 V18.2.0) using Rust code generated by the ASN.1/Rust Web Compiler.
The ASN.1/Rust Web Compiler generates a Rust codec and sample application from the E1AP ASN.1 schema. The generated sample decodes a PER-encoded E1AP-PDU, converts and prints the decoded value, and encodes the value back to PER.
To explore more samples (LTE RRC, 5G RRC, S1AP, X2AP), visit the main Sample Code page.
This sample shows how to:
The ASN.1/Rust Web Compiler generates the Rust codec, sample application, and Cargo configuration files required to build the project.
| File | Description |
|---|---|
| sample/src/main.rs | Generated Rust sample application that demonstrates how to decode, print, and re-encode an E1AP PDU. |
| sample/Cargo.toml | Cargo configuration for the sample application. |
| codec/src/ | Rust codec source generated from the NG-RAN E1AP ASN.1 schema. |
| codec/Cargo.toml | Cargo configuration for the generated codec. |
| Cargo.toml | Cargo workspace configuration for the generated project. |
| compiler_*.json | Compiler configuration associated with the generated project. |
The codec/ directory contains the Rust codec generated from the NG-RAN E1AP ASN.1 schema. The sample/src/main.rs file contains the generated sample application that demonstrates how to use the codec.
To generate the Rust codec and sample application using the ASN.1/Rust Web Compiler:
For this sample, the E1AP-PDU type is used to demonstrate PER encoding and decoding.
The generated sample application:
Before building the generated Rust project, install Cargo and the Rust compiler (rustc). The recommended way to install both is with rustup. See the Rust installation instructions.
Download and extract the archive generated by the ASN.1/Rust Web Compiler. The generated project contains the codec and sample subdirectories and a top-level Cargo.toml file.
Open a terminal in the root directory of the extracted project, where the top-level Cargo.toml file is located, and run:
cargo build
This command builds the generated Rust codec and sample application.
From the same directory, run:
cargo run sample
This command runs the generated sample application.
The following listing shows the generated Rust sample application, sample/src/main.rs. It demonstrates how to decode a PER-encoded E1AP PDU, convert and print the decoded value, encode the value back to PER, and handle errors using the generated Rust codec.
/*
******************************************************************
* Copyright (C) 2026 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.
* Generated Codec Name: my_codec
* ASN.1 Compiler Version: 1.1.9
*/
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(unused_parens)]
#![allow(unused_mut)]
#![allow(non_upper_case_globals)]
#![allow(unused_imports)]
#![allow(unused_assignments)]
use std::ptr;
use std::cell::LazyCell;
pub fn E1AP_PDU_sample(){
oss_print_string_literal("================================================================\x0a\x0a");
oss_print_string_literal("Encoding/Decoding value of type 'E1AP-PDU-Descriptions.E1AP-PDU':\x0a\x0a");
let sample_bytes : mut_oss_Vector_of_uint8 = vec![(((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((9) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((1) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((2) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8, (((i64_to_u8(((0) as i64))) as u32)) as u8];
let encoding_rule : oss_EncodingRules = oss_EncodingRules_per;
let mut decode_ok : bool = false;
let mut decoded_value : *mut E1AP_PDU = (ptr::null_mut() as *mut E1AP_PDU);
let mut error_messages : oss_String = oss_String_init();
(decode_ok, decoded_value, error_messages) = E1AP_PDU_Decode((& encoding_rule as *const oss_EncodingRules), (& sample_bytes));
if !decode_ok {
oss_print_string_literal("The 'Decode' call failed!\x0a");
oss_print_string((& error_messages as *const oss_String));
oss_print_string_literal("");
oss_exit(1);
}
let mut to_json_ok : bool = false;
let mut json_value : *mut oss_String = (ptr::null_mut() as *mut oss_String);
oss_String_Clear((&mut error_messages as *mut oss_String));
(to_json_ok, json_value, error_messages) = E1AP_PDU_ToString(decoded_value);
if !to_json_ok {
oss_print_string_literal("The 'ToString' call failed!\x0a");
oss_print_string((& error_messages as *const oss_String));
oss_print_string_literal("");
oss_exit(1);
}
oss_print_string_literal("Decoded value (formatted string): ");
oss_print_string(json_value);
oss_print_string_literal("\x0a\x0a");
let mut encode_ok : bool = false;
let mut encoded_value : *const mut_oss_Vector_of_uint8 = (ptr::null() as *const mut_oss_Vector_of_uint8);
oss_String_Clear((&mut error_messages as *mut oss_String));
(encode_ok, encoded_value, error_messages) = E1AP_PDU_Encode((& encoding_rule as *const oss_EncodingRules), decoded_value);
if !encode_ok {
oss_print_string_literal("The 'Encode' call failed!\x0a");
oss_print_string((& error_messages as *const oss_String));
oss_print_string_literal("");
oss_exit(1);
}
oss_print_hex(encoded_value);
oss_print_string_literal("\x0a");
if !(json_value == (ptr::null_mut() as *mut oss_String)) {
let mut tmp_value_1083217 : *mut oss_String = json_value;
if !(tmp_value_1083217 == (ptr::null_mut() as *mut oss_String)) {
oss_String_Dtr(tmp_value_1083217);
}
(_) = delete_oss_String(tmp_value_1083217);
}
(_) = delete_oss_Vector_of_uint8(encoded_value);
prune_E1AP_PDU(decoded_value);
(_) = delete_E1AP_PDU(decoded_value);
oss_String_Dtr((&mut error_messages as *mut oss_String));
}
/*
prints a native string literal to the console
a_str: a native reference to the string to be printed
*/
pub fn oss_print_string_literal(a_str: &str) {
print!("{}", a_str);
}
/*
prints raw bytes to the console
v: a reference to the constant vector of uint8 bytes to be printed
*/
pub fn oss_print_hex(v: *const mut_oss_Vector_of_uint8) {
if v.is_null() {
println!("Null pointer passed to print_oss_vector_hex.");
return;
}
let vec = unsafe { &*v };
print!("Encoding HEX (len={}): ", vec.len());
for byte in vec {
print!("{:02X} ", byte);
}
println!();
}
pub fn main(){
E1AP_PDU_sample();
}
use codec::bindings::*;
use codec::api::*;
This is an excerpt of the output produced when running the generated sample:
Encoding/Decoding value of type 'E1AP-PDU-Descriptions.E1AP-PDU':
Decoded value (formatted string):
{
...
"procedureCode": 0,
"criticality": "reject",
"value": {
...
}
}
Encoding HEX (len=13): 00 00 00 09 ... 00 02 00 00
The following excerpt shows the E1AP-PDU definition from the 3GPP TS 37.483 V18.2.0 ASN.1 schema used to generate this sample.
-- Excerpt from 3GPP TS 37.483 V18.2.0 (2024-07)
-- **************************************************************
--
-- Elementary Procedure definitions
--
-- **************************************************************
E1AP-PDU-Descriptions {
itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-PDU-Descriptions (0) }
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
-- **************************************************************
--
-- IE parameter types from other modules
--
-- **************************************************************
IMPORTS
Criticality,
ProcedureCode
FROM E1AP-CommonDataTypes
Reset,
ResetAcknowledge,
ErrorIndication,
GNB-CU-UP-E1SetupRequest,
GNB-CU-UP-E1SetupResponse,
GNB-CU-UP-E1SetupFailure,
GNB-CU-CP-E1SetupRequest,
GNB-CU-CP-E1SetupResponse,
GNB-CU-CP-E1SetupFailure,
GNB-CU-UP-ConfigurationUpdate,
GNB-CU-UP-ConfigurationUpdateAcknowledge,
GNB-CU-UP-ConfigurationUpdateFailure,
GNB-CU-CP-ConfigurationUpdate,
GNB-CU-CP-ConfigurationUpdateAcknowledge,
GNB-CU-CP-ConfigurationUpdateFailure,
BCBearerContextSetupRequest,
BCBearerContextSetupResponse,
BCBearerContextSetupFailure,
BCBearerContextModificationRequest,
BCBearerContextModificationResponse,
BCBearerContextModificationFailure,
BCBearerContextModificationRequired,
BCBearerContextModificationConfirm,
BCBearerContextReleaseCommand,
BCBearerContextReleaseComplete,
BCBearerContextReleaseRequest,
BearerContextSetupRequest,
BearerContextSetupResponse,
BearerContextSetupFailure,
BearerContextModificationRequest,
BearerContextModificationResponse,
BearerContextModificationFailure,
BearerContextModificationRequired,
BearerContextModificationConfirm,
BearerContextReleaseCommand,
BearerContextReleaseComplete,
BearerContextReleaseRequest,
BearerContextInactivityNotification,
DLDataNotification,
ULDataNotification,
DataUsageReport,
E1ReleaseRequest,
E1ReleaseResponse,
GNB-CU-UP-CounterCheckRequest,
GNB-CU-UP-StatusIndication,
MCBearerContextSetupRequest,
MCBearerContextSetupResponse,
MCBearerContextSetupFailure,
MCBearerContextModificationRequest,
MCBearerContextModificationResponse,
MCBearerContextModificationFailure,
MCBearerContextModificationRequired,
MCBearerContextModificationConfirm,
MCBearerNotification,
MCBearerContextReleaseCommand,
MCBearerContextReleaseComplete,
MCBearerContextReleaseRequest,
MRDC-DataUsageReport,
DeactivateTrace,
TraceStart,
PrivateMessage,
ResourceStatusRequest,
ResourceStatusResponse,
ResourceStatusFailure,
ResourceStatusUpdate,
IAB-UPTNLAddressUpdate,
IAB-UPTNLAddressUpdateAcknowledge,
IAB-UPTNLAddressUpdateFailure,
CellTrafficTrace,
EarlyForwardingSNTransfer,
GNB-CU-CPMeasurementResultsInformation,
IABPSKNotification
FROM E1AP-PDU-Contents
id-reset,
id-errorIndication,
id-gNB-CU-UP-E1Setup,
id-gNB-CU-CP-E1Setup,
id-gNB-CU-UP-ConfigurationUpdate,
id-gNB-CU-CP-ConfigurationUpdate,
id-e1Release,
id-bearerContextSetup,
id-bearerContextModification,
id-bearerContextModificationRequired,
id-bearerContextRelease,
id-bearerContextReleaseRequest,
id-bearerContextInactivityNotification,
id-dLDataNotification,
id-uLDataNotification,
id-dataUsageReport,
id-gNB-CU-UP-CounterCheck,
id-gNB-CU-UP-StatusIndication,
id-mRDC-DataUsageReport,
id-DeactivateTrace,
id-TraceStart,
id-privateMessage,
id-resourceStatusReportingInitiation,
id-resourceStatusReporting,
id-iAB-UPTNLAddressUpdate,
id-CellTrafficTrace,
id-earlyForwardingSNTransfer,
id-gNB-CU-CPMeasurementResultsInformation,
id-iABPSKNotification,
id-BCBearerContextSetup,
id-BCBearerContextModification,
id-BCBearerContextModificationRequired,
id-BCBearerContextRelease,
id-BCBearerContextReleaseRequest,
id-MCBearerContextSetup,
id-MCBearerContextModification,
id-MCBearerContextModificationRequired,
id-MCBearerNotification,
id-MCBearerContextRelease,
id-MCBearerContextReleaseRequest
FROM E1AP-Constants;
-- **************************************************************
--
-- Interface Elementary Procedure Class
--
-- **************************************************************
E1AP-ELEMENTARY-PROCEDURE ::= CLASS {
&InitiatingMessage ,
&SuccessfulOutcome OPTIONAL,
&UnsuccessfulOutcome OPTIONAL,
&procedureCode ProcedureCode UNIQUE,
&criticality Criticality DEFAULT ignore
}
WITH SYNTAX {
INITIATING MESSAGE &InitiatingMessage
[SUCCESSFUL OUTCOME &SuccessfulOutcome]
[UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome]
PROCEDURE CODE &procedureCode
[CRITICALITY &criticality]
}
-- **************************************************************
--
-- Interface PDU Definition
--
-- **************************************************************
E1AP-PDU ::= CHOICE {
initiatingMessage InitiatingMessage,
successfulOutcome SuccessfulOutcome,
unsuccessfulOutcome UnsuccessfulOutcome,
...
}
InitiatingMessage ::= SEQUENCE {
procedureCode E1AP-ELEMENTARY-PROCEDURE.&procedureCode ({E1AP-ELEMENTARY-PROCEDURES}),
criticality E1AP-ELEMENTARY-PROCEDURE.&criticality ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
value E1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
}
SuccessfulOutcome ::= SEQUENCE {
procedureCode E1AP-ELEMENTARY-PROCEDURE.&procedureCode ({E1AP-ELEMENTARY-PROCEDURES}),
criticality E1AP-ELEMENTARY-PROCEDURE.&criticality ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
value E1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
}
UnsuccessfulOutcome ::= SEQUENCE {
procedureCode E1AP-ELEMENTARY-PROCEDURE.&procedureCode ({E1AP-ELEMENTARY-PROCEDURES}),
criticality E1AP-ELEMENTARY-PROCEDURE.&criticality ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
value E1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
}
-- **************************************************************
--
-- Interface Elementary Procedure List
--
-- **************************************************************
E1AP-ELEMENTARY-PROCEDURES E1AP-ELEMENTARY-PROCEDURE ::= {
E1AP-ELEMENTARY-PROCEDURES-CLASS-1 |
E1AP-ELEMENTARY-PROCEDURES-CLASS-2 ,
...
}
E1AP-ELEMENTARY-PROCEDURES-CLASS-1 E1AP-ELEMENTARY-PROCEDURE ::= {
reset |
gNB-CU-UP-E1Setup |
gNB-CU-CP-E1Setup |
gNB-CU-UP-ConfigurationUpdate |
gNB-CU-CP-ConfigurationUpdate |
e1Release |
bearerContextSetup |
bearerContextModification |
bearerContextModificationRequired |
bearerContextRelease |
resourceStatusReportingInitiation |
iAB-UPTNLAddressUpdate |
bCBearerContextSetup |
bCBearerContextModification |
bCBearerContextModificationRequired |
bCBearerContextRelease |
mCBearerContextSetup |
mCBearerContextModification |
mCBearerContextModificationRequired |
mCBearerContextRelease ,
...
}
E1AP-ELEMENTARY-PROCEDURES-CLASS-2 E1AP-ELEMENTARY-PROCEDURE ::= {
errorIndication |
bearerContextReleaseRequest |
bearerContextInactivityNotification |
dLDataNotification |
uLDataNotification |
dataUsageReport |
gNB-CU-UP-CounterCheck |
gNB-CU-UP-StatusIndication |
mRDC-DataUsageReport |
deactivateTrace |
traceStart |
privateMessage |
cellTrafficTrace |
resourceStatusReporting |
earlyForwardingSNTransfer |
gNB-CU-CPMeasurementResultsInformation |
iABPSKNotification |
bCBearerContextReleaseRequest |
mCBearerContextReleaseRequest |
mCBearerNotification ,
...
}
-- **************************************************************
--
-- Interface Elementary Procedures
--
-- **************************************************************
This sample is provided solely for illustration purposes to demonstrate how to process 3GPP NG-RAN E1AP messages using Rust code generated by the ASN.1/Rust Web Compiler. It does not represent a complete application. The copyright and license statements included in the generated source files remain fully applicable.
If you have questions about using this sample, contact OSS Nokalva Support.