maxime-esa / asn1scc

ASN1SCC: An open source ASN.1 compiler for embedded systems

Home Page:https://www.thanassis.space/asn1.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ACN optional choice with determinant and present-when

mario-bucev opened this issue · comments

If we take #288 and use present-when, the decoder now seems to decode a different message from what was encoded:

Determinant2d DEFINITIONS AUTOMATIC TAGS ::= BEGIN
EXPORTS ALL;

MyChoiceEnum ::= ENUMERATED
{
    choice1 (1),
    choice2 (2)
}

MyTopMostSeq ::= SEQUENCE
{
    myChoice1 MyChoice OPTIONAL,
    myChoice2 MyChoice OPTIONAL
}

MyChoice ::= CHOICE
{
    choice1 MyTuple,
    choice2 INTEGER
}

MyTuple ::= SEQUENCE
{
    fst INTEGER,
    snd INTEGER
}

END
Determinant2d DEFINITIONS ::= BEGIN

MyChoiceEnum [size 32, encoding pos-int, endianness big, encode-values]

MyTopMostSeq []
{
    myDeterminant MyChoiceEnum [],
    myBool1 BOOLEAN [],
    myBool2 BOOLEAN [],
    myChoice1 <myDeterminant> [present-when myBool1],
    myChoice2 <myDeterminant> [present-when myBool2]
}

MyChoice <MyChoiceEnum: theDeterminant> [determinant theDeterminant]

END

In the following, we set that .myChoice2 as absent, but when decoded, the result is set to be present:

#include <stdio.h>
#include <assert.h>
#include "Determinant2d.h"

int main(void)
{
    TMyTopMostSeq topMost = {
        .myChoice1 = {
            .kind = choice1_PRESENT,
            .u = {.choice1 = {.fst = 42, .snd = 24}}
        },
        .myChoice2 = {
            .kind = choice1_PRESENT, // even though it is technically absent
            .u = {}
        },
        .exist = {.myChoice1 = 1, .myChoice2 = 0}
    };
    unsigned char buf[TMyTopMostSeq_REQUIRED_BYTES_FOR_ACN_ENCODING];
    BitStream bs;
    BitStream_Init(&bs, buf, sizeof buf);
    int errCode;
    flag ok = TMyTopMostSeq_ACN_Encode(&topMost, &bs, &errCode, true);
    // Prints ok = 1  errCode = 0
    printf("ok = %d  errCode = %d\n", ok, errCode);

    bs.currentByte = 0;
    bs.currentBit = 0;
    TMyTopMostSeq topMostDec;
    ok = TMyTopMostSeq_ACN_Decode(&topMostDec, &bs, &errCode);
    // Prints ok = 1  errCode = 0
    printf("ok = %d  errCode = %d\n", ok, errCode);
    // Prints myChoice1.kind = 1  myChoice2.kind = 1
    printf("myChoice1.kind = %d  myChoice2.kind = %d\n", topMostDec.myChoice1.kind, topMostDec.myChoice2.kind);
    // Prints exist.myChoice1 = 1  exist.myChoice2 = 1  even though myChoice2 is said to be absent
    printf("exist.myChoice1 = %d  exist.myChoice2 = %d\n", topMostDec.exist.myChoice1, topMostDec.exist.myChoice2);
    printf("myChoice1.u.choice1.fst = %ld   myChoice1.u.choice1.snd = %ld\n", topMostDec.myChoice1.u.choice1.fst, topMostDec.myChoice1.u.choice1.snd);
}

It was a bug and it's now fixed in the latest commit. I've tested the fix with the ASN.1 and ACN grammar you mentioned and it works well. Please verify on your side and close the ticket if all looks good

Yes, the issue is fixed, thanks a lot!