---
id: codecs--asn1-decoder-plugin
title: "ASN.1 decoder"
summary: "Decodes a binary ASN.1 stream (for example telecom CDR files) into typed records. Flow types are generated from an ASN.1 module definition; every top-level record found in the stream is emitted on `Output`."
audience: user
keywords: "input, output, header, continue, asndefinition, encoding, mode, fillerbyte, framing, fileheaderskip, recordheaderskip, maxdepth, roottypename, batchmode"
---
# ASN.1 decoder

Decodes a binary ASN.1 stream (for example telecom CDR files) into typed records. Flow types are generated from an ASN.1 module definition; every top-level record found in the stream is emitted on `Output`.

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | input | `Viaducta.Plugins.Files.Types.ViaFileStream` | The binary stream to decode (for example from a file reader). |
| Output | output | generated root type (`<flow namespace>.<RootType>`) | Called once per decoded root record. |
| Header | output | `<flow namespace>.Ts32297FileHeader` (with `Framing` = `TS32297`) | Called once per file with the decoded TS 32.297 file header, before the records. Only when connected. |
| Continue | continue output | any (the input) | Called with the input stream after the whole stream is decoded. |

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `AsnDefinition` | ASN.1 module (editor) | | The module text. Triggers reconfigure. |
| `Encoding` | dropdown: `BER`, `CER`, `DER`, `OER`, `PER` | `BER` | Encoding rules for primitive values. |
| `Mode` | dropdown: `1` STRICT, `2` RELAXED | `2` | `1` stops on the first decoding error; `2` logs it and continues. |
| `FillerByte` | integer (0-255) | empty | Optional padding byte between records; filler bytes are skipped. Not used with `TS32297` framing (a zero CDR length marks padding there). |
| `Framing` | dropdown: `NONE` None, `FIXED` Fixed header skip, `TS32297` 3GPP TS 32.297 | `NONE` | How records are framed in the file. `NONE`: a raw stream of TLV records. `FIXED`: skip `FileHeaderSkip` bytes at the start and `RecordHeaderSkip` bytes before each record. `TS32297`: CDR file with file header and a CDR header per record, lengths read from the data. Triggers reconfigure (registers the `Header` type). |
| `FileHeaderSkip` | integer (0-1048576) | `0` | `FIXED` framing: bytes skipped at the start of the file. |
| `RecordHeaderSkip` | integer (0-65535) | `0` | `FIXED` framing: bytes skipped before every record; the record length comes from the BER TLV. |
| `MaxDepth` | integer (1-9999) | `99` | Maximum nesting depth of a record, protects against malformed data. |
| `RootTypeName` | type (type selector) | | Full name of the type decoded at stream level. Set automatically by reconfigure; triggers reconfigure. |
| `BatchMode` | dropdown: `1` Auto, `2` Always, `3` Never | `1` | Whether the records decoded from one file form a batch for batch consumers (ASN.1 encoder, Write file, Bulk insert, ...). `Auto`: only if the input file is not already in a batch; inside a batch (e.g. a file read by Read file) the records stay in that batch. `Always`: a child batch per file (label = file name). `Never`: no batch. |

## ASN.1 definition

A standard module: `Name DEFINITIONS [AUTOMATIC|IMPLICIT|EXPLICIT TAGS] ::= BEGIN ... END`. Supported constructs: `SEQUENCE`, `SET`, `CHOICE`, `SEQUENCE OF`, `SET OF`, `ENUMERATED`, `INTEGER` (also `INTEGER64`, `BIGINT`), `BOOLEAN`, `REAL`, `NULL`, `OCTET STRING`, `BIT STRING`, `OBJECT IDENTIFIER`, `IA5String`, `PrintableString`, `UTF8String`, `NumericString`, `VisibleString`, `GeneralizedTime`, `UTCTime`, context tags `[n]` with `IMPLICIT`/`EXPLICIT`, `OPTIONAL`/`DEFAULT`, `SIZE` constraints.

```asn1
CDR DEFINITIONS IMPLICIT TAGS ::= BEGIN
CallRecord ::= SEQUENCE {
  callingNumber [0] OCTET STRING,
  duration      [1] INTEGER OPTIONAL
}
END
```

## Behaviour

- Reconfigure (changing `AsnDefinition`) parses the module and generates one flow class per type definition (named after the ASN.1 type, C#-friendly) in the flow namespace. The first type that is not used as a member of another type becomes the root: its full name is written to `RootTypeName` and set on `Output`. Pick another root with `RootTypeName` if needed.
- At start the module is compiled again; per input the stream is read record by record. When a batch is opened (`BatchMode`) it ends after the last record was processed downstream and before `Continue`: consumers commit then. In `STRICT` mode a file with problems fails its batch and the consumers roll back; in lenient mode skipped records don't fail it. A flow stop in the middle of a file fails its batch.
- `TS32297` framing: the file header is read first (a broken header fails the file) and sent to `Header`; each record's CDR header must announce a data record format compatible with `Encoding`, otherwise the record fails. At the end the record count is compared with the header's `NumberOfCdrs`, and a non-zero `LostCdrIndicator` is reported as a warning.
- A framing error stops reading the file; the records framed before it are still emitted and the problem is reported (`STRICT`: the file fails).
- Decoding problems are shown as warnings; errors are also written to the log with the hex content of the offending part. In `STRICT` mode the first error stops decoding with an exception.

## Notes

- Records are read as tag-length-value; `Encoding` only changes how primitive values are decoded. Use `BER`/`DER`/`CER` for TLV files; `PER` and `OER` streams are not structurally supported.
- Only `ViaFileStream` input is accepted; any other input fails with "Unsupported input type".

## Example

```json
{ "Encoding": "BER", "Mode": "2", "FillerByte": 255, "MaxDepth": 99, "RootTypeName": "MyFlow.CallRecord" }
```

Collect files → File reader → **ASN.1 decoder** → Data mapper → Bulk insert
