yafred / asn1-tool Goto Github PK
View Code? Open in Web Editor NEWA java tool to generate Java encoders and decoders from ASN.1 specifications.
License: MIT License
A java tool to generate Java encoders and decoders from ASN.1 specifications.
License: MIT License
I am trying to compile the attached ASN file but I am getting the following error. I have done some troubleshooting and narrowed the cause to the following line in the ASN file:
DrivingLaneStatus ::= BIT STRING (SIZE (1..13))
When I remove this line the file is compiled correctly.
Any idea why is this line is not accepted by the compiler?
Thank you
Same as here
Additional data should not raise an exception
Example:
SearchResultDone ::= [APPLICATION 5] LDAPResult
LDAPResult ::= SEQUENCE {
resultCode ENUMERATED {
...
SearchResultDone inheriting from LDAPResult uses method getValue() not present in LDAPResult
Hi
I was trying to parse few dictionaries with this tool using JAR. Almost everything is successful but when any dictionary which contains (_) anywhere, ASNParser stops parsing and throws error.
Is there anyway to come out from this?
I've an attribute "defaultCallHandling_" in dictionary but parser stops on validation.
Below is a code which I use to validate & traversing dictionaries:
CharStream charStream = CharStreams.fromFileName("f:/dicts/av1.asn"); ASNLexer lexer = new ASNLexer(charStream); TokenStream tokens = new CommonTokenStream(lexer); ASNParser parser = new ASNParser(tokens); ParseTree tree = parser.specification();
Thanks!
When a specification is using IMPORTS FROM module and the referenced module is not found, there is an a ugly exception.
Instead, there should be a clear message that module is not found
Hi!
Perform the following steps, modifying the compiler.java class:
-f ASN.1 specification.
-p just print the validated model.
-jo generate Java code in the given folder.
-jp use this package as a prefix for generated Java code (ASN.1 module names are added to this prefix to get the full package name).
The problem is that it doesn't work.
I see you enter the if module (line.getOptions (). Length == 0)
I run and the screen shows the data of that module.
Should I make those modifications to the compiler.java file?
Thank you.
Error while validating the below ASN1 sample
G-009 DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
NGAP-PROTOCOL-IES ::= CLASS {
&id ProtocolIE-ID UNIQUE,
&criticality Criticality,
&Value,
&presence Presence
}
WITH SYNTAX {
ID &id
CRITICALITY &criticality
TYPE &Value
PRESENCE &presence
}
ERROR:
line 4:28 mismatched input '{' expecting {'END', UCASE_ID, LCASE_ID}
Example:
SubstringFilter ::= SEQUENCE {
type AttributeDescription,
-- at least one must be present,
-- initial and final can occur at most once
substrings SEQUENCE OF CHOICE {
initial [0] AssertionValue,
any [1] AssertionValue,
final [2] AssertionValue } }
final
is a Java keywork (generated code will not compile)
Found this on stackoverflow
Hello,
This project seems to be actively maintained since 2018 but the README still says "Warning: This tool is in development". Is it really not recommended for production use yet?
I want to parse DER-encoded values with the following structure in my Kotlin library.
Relaynet-RAMF DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
RAMF ::= SEQUENCE
{
recipient VisibleString (SIZE(1..1000)),
messageId VisibleString (SIZE(1..256)),
creationTimeUtc DATE-TIME,
ttl INTEGER (0..7776000),
payload OCTET STRING
}
END
Would you advise against using this library for this?
I'm trying to use the compiler to encode a DENM message (https://forge.etsi.org/rep/ITS/asn1/denm_en302637_3)
My code right now look like this.
public class CreateDENMMessage {
public static void main(String[] args) {
// Create an instance of DENM
DENM denmMessage = new DENM();
// Set Header Information (if required)
ItsPduHeader header = new ItsPduHeader();
header.setProtocolVersion(2);
header.setMessageID(MessageID.DENM);
header.setStationID(1280119804);
// Set header attributes here
denmMessage.setHeader(header);
// Create a DecentralizedEnvironmentalNotificationMessage
DecentralizedEnvironmentalNotificationMessage denm = new DecentralizedEnvironmentalNotificationMessage();
ManagementContainer manage = new ManagementContainer();
ActionID action = new ActionID();
action.setOriginatingStationID(1280119804);
action.setSequenceNumber(1);
manage.setActionID(action);
manage.setDetectionTime(622991125); //622991127886
manage.setReferenceTime(622991129); //622991127890
manage.setTermination(Termination.Enum.ISCANCELLATION);
ReferencePosition refpos = new ReferencePosition();
refpos.setLatitude(367474912);
refpos.setLongitude(-45555876);
PosConfidenceEllipse ellipse = new PosConfidenceEllipse();
ellipse.setSemiMajorConfidence(400);
ellipse.setSemiMinorConfidence(400);
ellipse.setSemiMajorOrientation(0);
refpos.setPositionConfidenceEllipse(ellipse);
Altitude alti = new Altitude();
alti.setAltitudeValue(10717);
alti.setAltitudeConfidence(AltitudeConfidence.Enum.ALT_000_02);
refpos.setAltitude(alti);
manage.setEventPosition(refpos);
manage.setRelevanceDistance(RelevanceDistance.Enum.LESSTHAN500M);
manage.setRelevanceTrafficDirection(RelevanceTrafficDirection.Enum.ALLTRAFFICDIRECTIONS);
manage.setValidityDuration(7);
manage.setTransmissionInterval(500);
manage.setStationType(15);
denm.setManagement(manage);
SituationContainer situ = new SituationContainer();
situ.setInformationQuality(0);
CauseCode event = new CauseCode();
event.setCauseCode(CauseCodeType.ACCIDENT);
event.setSubCauseCode(0);
situ.setEventType(event);
situ.setLinkedCause();
situ.setEventHistory();
denm.setSituation(situ);
LocationContainer loca = new LocationContainer();
Speed event_sp = new Speed();
event_sp.setSpeedValue(0);
event_sp.setSpeedConfidence(127);
loca.setEventSpeed(event_sp);
loca.setRoadType(null);
Heading event_h = new Heading();
event_h.setHeadingValue(0);
event_h.setHeadingConfidence(127);
loca.setEventPositionHeading(event_h);
loca.setTraces();
denm.setLocation(loca);
// Add the DecentralizedEnvironmentalNotificationMessage to the DENM
denmMessage.setDenm(denm);
// Validate the DENM message (if required)
try {
//DENM.validate(denmMessage);
} catch (Exception e) {
// Handle validation errors
e.printStackTrace();
}
// Encode a DENM
ByteArrayOutputStream bufferOut = new ByteArrayOutputStream();
BERWriter berWriter = new BERWriter(bufferOut);
try{
DENM.writePdu(denmMessage, berWriter);
} catch (Exception e) {
e.printStackTrace();
}
byte[] berEncoded = bufferOut.toByteArray();
// Convert the byte array to a hex string
String berHex = bytesToHex(berEncoded);
System.out.println("Encoded DENM in BER hex: " + berHex);
}
The compilation is error free but the hex string is not the expected, any idea why would I'm not getting the correct hex string? It can be tested on this website (https://www.marben-products.com/decoder-asn1-automotive/) 'decode from direct input' option.
The encoded hex string although it is not correct it can be decoded back to the original values defined in the script pasted.
Thanks in advance.
Originally posted by @Serfermor in #21 (comment)
Cit-pat ::= SEQUENCE { -- patent citation
title VisibleString ,
authors Auth-list, -- author/inventor
country VisibleString , -- Patent Document Country
doc-type VisibleString , -- Patent Document Type
number VisibleString OPTIONAL, -- Patent Document Number
date-issue Date OPTIONAL, -- Patent Issue/Pub Date
class SEQUENCE OF VisibleString OPTIONAL , -- Patent Doc Class Code
app-number VisibleString OPTIONAL , -- Patent Doc Appl Number
app-date Date OPTIONAL , -- Patent Appl File Date
applicants Auth-list OPTIONAL , -- Applicants
assignees Auth-list OPTIONAL , -- Assignees
priority SEQUENCE OF Patent-priority OPTIONAL , -- Priorities
abstract VisibleString OPTIONAL } -- abstract of patent
Hello.
I have no clue if you would still be working on this, but constraint checking would be nice. For example:
FooProtocol DEFINITIONS ::= BEGIN
FooQuestion ::= SEQUENCE {
trackingNumber INTEGER(0..199),
question IA5String
}
END
Here the value for trackingNumber
can only be an integer, and it must be between 0 and 199. Of course this is no Ada, so the usual bound checks would do.
What would we do if it fails though? I presume this would result in a runtime error, but we should be able to catch this error, so perhaps what it should do is throw a constraint error that one could somehow catch? Is it feasible or possible? I do not know Java enough to tell.
This change constrains trackingNumbers to have a value between 0 and 199 inclusive, and questionNumbers to have a value between 10 and 20 inclusive. The size of the questions array can be between 0 and 10 elements, with the answers array between 1 and 10 elements. The anArray field is a fixed length 100 element array of integers that must be in the range 0 to 1000. The '...' extensibility marker means that the FooHistory message specification may have additional fields in future versions of the specification; systems compliant with one version should be able to receive and transmit transactions from a later version, though able to process only the fields specified in the earlier version. Good ASN.1 compilers will generate (in C, C++, Java, etc.) source code that will automatically check that transactions fall within these constraints. Transactions that violate the constraints should not be accepted from, or presented to, the application. Constraint management in this layer significantly simplifies protocol specification because the applications will be protected from constraint violations, reducing risk and cost.
From https://en.wikipedia.org/wiki/ASN.1#Example.
Look at how Erlang does it (this is the compiled FooProtocol.erl
):
dec_FooQuestion(Tlv, TagIn) ->
%%-------------------------------------------------
%% decode tag and length
%%-------------------------------------------------
Tlv1 = match_tags(Tlv, TagIn),
%%-------------------------------------------------
%% attribute trackingNumber(1) with type INTEGER
%%-------------------------------------------------
[V1|Tlv2] = Tlv1,
Term1 = begin
Val1 = decode_integer(V1, [2]),
if 0 =< Val1, Val1 =< 199 ->
Val1;
true ->
exit({error,{asn1,bad_range}})
end
end,
[...]
As we are decoding FooQuestion
, when we reach trackingNumber
, we are trying to decode the value as an integer, and if the value is less than 0 or greater than 199, then it exits with the error: {error,{asn1,bad_range}}
. It is pretty straightforward. We should have something like that.
I would hope that it is possible in Java, too. As I said, in case of a constraint failure due to a wrong value for trackingNumber
, in Erlang it returns {error, {asn1, bad_range}}
.
This is how you catch for such an error (though here we catch all errors) when you are doing the decoding in Erlang (user code):
case 'FooProtocol':decode('FooProtocol', Bytes) of
{ok, _FP} -> ok;
{error, Reason} -> exit({error, Reason})
end
Again, the above code catches all errors as-is, and exits with them, so it would exit with {error, {asn1, bad_range}}
, but the important thing is that you could easily catch the above in particular by changing {error, Reason}
to {error, {asn1, bad_range}}
(or better yet, adding it above, since we do want to catch the rest, too).
For completeness' sake, that would look like (user code):
case 'FooProtocol':decode('FooProtocol', Bytes) of
{ok, _FP} -> ok;
{error, {asn1, bad_range}} -> HANDLE_THE_BAD_RANGE_ERROR_HERE;
{error, Reason} -> exit({error, Reason})
end
Just to demonstrate:
1> X = {'FooQuestion', 200, "foo"}.
{'FooQuestion',200,"foo"}
2> {ok, Bin} = 'FooProtocol':encode('FooQuestion', X).
{ok,<<48,9,2,2,0,200,22,3,102,111,111>>}
3> {ok, Q} = 'FooProtocol':decode('FooQuestion', Bin).
** exception error: no match of right hand side value
{error,
{asn1,
{bad_range,
[{'FooProtocol',dec_FooQuestion,2,
[{file, "/tmp/erlang/FooProtocol.erl"},
{line,130}]},
{'FooProtocol',decode,2,
[{file, "/tmp/erlang/FooProtocol.erl"},
{line,56}]},
{erl_eval,do_apply,6,
[{file,"erl_eval.erl"},{line,689}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,446}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,
[{file,"shell.erl"},{line,627}]}]}}}
As we can see, attempting to decode it with the invalid value (200
) results in error {error,{asn1,bad_range}}
. This is something you can catch like I did in the code above. Something like this would be ideal in Java. It has to be thrown from the generated file so the user can catch it when using its decode method.
Found this on stackoverflow
The problem could be solved with Converter if we had a readBigInteger in ASNValueReader as we have now in BERReader
Hello!
The compiler does not support ANY / ANY DEFINED BY. According to the specification it should be replaced by an open type.
Is there some compiler class in charge of handling open types or ANY?
I've been using the tool and looking at the code, but I didn't find anything.
Thank you!
Symbol 'CrlSeries' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'EccP256CurvePoint' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'EciesP256EncryptedKey' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'EncryptionKey' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'GeographicRegion' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'GroupLinkageValue' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'HashAlgorithm' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'HashedId3' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'HashedId8' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Hostname' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'IValue' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'LinkageValue' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Opaque' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Psid' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'PsidSsp' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'PsidSspRange' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'PublicEncryptionKey' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'PublicVerificationKey' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'SequenceOfHashedId3' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'SequenceOfPsidSsp' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'SequenceOfPsidSspRange' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'ServiceSpecificPermissions' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Signature' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'SubjectAssurance' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'SymmetricEncryptionKey' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'ThreeDLocation' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Time64' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Uint3' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Uint8' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Uint16' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'Uint32' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
Symbol 'ValidityPeriod' is imported in module 'IEEE1609dot2' from an undefined module 'IEEE1609dot2BaseTypes'
[line 76:24] Type 'Uint8' neither defined nor imported
[line 81:30] Type 'Opaque' neither defined nor imported
[line 84:30] Type 'Opaque' neither defined nor imported
[line 89:21] Type 'HashAlgorithm' neither defined nor imported
[line 92:21] Type 'Signature' neither defined nor imported
[line 96:21] Type 'HashedId8' neither defined nor imported
[line 113:28] Type 'Psid' neither defined nor imported
[line 114:28] Type 'Time64' neither defined nor imported
[line 115:28] Type 'Time64' neither defined nor imported
[line 116:28] Type 'ThreeDLocation' neither defined nor imported
[line 117:28] Type 'HashedId3' neither defined nor imported
[line 119:28] Type 'EncryptionKey' neither defined nor imported
[line 121:28] Type 'SequenceOfHashedId3' neither defined nor imported
[line 126:21] Type 'HashedId3' neither defined nor imported
[line 127:21] Type 'CrlSeries' neither defined nor imported
[line 173:31] Type 'HashedId8' neither defined nor imported
[line 173:31] Type 'HashedId8' neither defined nor imported
[line 175:24] Type 'HashedId8' neither defined nor imported
[line 180:24] Type 'HashedId8' neither defined nor imported
[line 185:28] Type 'EciesP256EncryptedKey' neither defined nor imported
[line 186:28] Type 'EciesP256EncryptedKey' neither defined nor imported
[line 197:21] Type 'Opaque' neither defined nor imported
[line 216:29] Type 'Uint8' neither defined nor imported
[line 220:29] Type 'Signature' neither defined nor imported
[line 246:29] Type 'HashedId8' neither defined nor imported
[line 247:29] Type 'HashAlgorithm' neither defined nor imported
[line 249:29] Type 'HashedId8' neither defined nor imported
[line 254:28] Type 'HashedId3' neither defined nor imported
[line 255:28] Type 'CrlSeries' neither defined nor imported
[line 256:28] Type 'ValidityPeriod' neither defined nor imported
[line 257:28] Type 'GeographicRegion' neither defined nor imported
[line 258:28] Type 'SubjectAssurance' neither defined nor imported
[line 259:28] Type 'SequenceOfPsidSsp' neither defined nor imported
[line 263:28] Type 'PublicEncryptionKey' neither defined nor imported
[line 273:29] Type 'Hostname' neither defined nor imported
[line 280:27] Type 'IValue' neither defined nor imported
[line 281:27] Type 'LinkageValue' neither defined nor imported
[line 282:27] Type 'GroupLinkageValue' neither defined nor imported
[line 298:21] Type 'SequenceOfPsidSspRange' neither defined nor imported
[line 304:29] Type 'PublicVerificationKey' neither defined nor imported
[line 305:29] Type 'EccP256CurvePoint' neither defined nor imported
Does the compiler requires all modules to be defined in the same ASN.1 file?
Is there any way to compile dependent modules in different ASN.1 files?
Hi @yafred,
We are using the tool to generate the Java classes based on Asn File.
Problem we are facing is like we have generated files based on tap312.asn, which is able to decode the tap file which is encoded with tap312 version.
but the same is not able to properly deocde the files which are encoded with the tap311 version.
do you think any issue would be there ??
Thanks,
Imam
Hi,
first of all, thanks a lot for this very nice project.
One thing i'm missing at the moment is the possibilty to use decimal values bigger than 4 byte.
Are there any plans of yours to implement that?
Kind regards
Fabian
Hello
I was wondering if i can generate CDR using your code,
I also can not generate the BER in the console.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.