mouse07410 / asn1c

The ASN.1 Compiler
http://lionet.info/asn1c/
BSD 2-Clause "Simplified" License
97 stars 71 forks source link

Unable to add an element to a message's 'SEQUENCE' field #117

Closed JonSmet closed 1 year ago

JonSmet commented 1 year ago

Hello,

I am working with the J2735 201603 ASN spec (which was compiled using the vlm-master branch of this repository), and I am unable to UPER encode a message that has a 'SEQUENCE' field after trying to add an element to this SEQUENCE. I have tried different approaches over the past week for adding an element to this 'SEQUENCE' field, but none have enabled me to successfully UPER encode the message.

Since I am unable to share the J2735 ASN spec, I've provided a simpler example ASN spec for a made-up VehicleMessage below, along with snippets from relevant generated header files and a code snippet where the UPER encoding fails after adding an element to the VehicleMessage's SEQUENCE field. Hopefully this helps convey the issue I am running into.

Any guidance on how to properly add an element to this 'SEQUENCE' field would be appreciated! I suspect I am incorrectly using asn_sequence_add(), but am unsure how to fix it. Please let me know if any additional information is needed.

Simplified ASN Spec (Modified excerpt from my .asn file since I am unable to share it):

VehicleMessage ::= SEQUENCE {
   speed            Velocity
   extensionList    SEQUENCE (SIZE(1..8)) OF
                    Extension {{ VehicleMessageExtension }} OPTIONAL,
   ...
   }

Velocity ::= INTEGER (0..127)

MESSAGE-EXT-ID-AND-TYPE ::= CLASS {
   &id     Extension-Id UNIQUE,
   &Type
   } WITH SYNTAX {&Type IDENTIFIED BY &id}

Extension        { MESSAGE-EXT-ID-AND-TYPE: Set} ::= SEQUENCE {
   extension-Id    MESSAGE-EXT-ID-AND-TYPE.&id( {Set} ),
   extension-Value  MESSAGE-EXT-ID-AND-TYPE.&Type( {Set}{@extension-Id} )
   }

extension-Id ::= INTEGER (0..63)
   fourWheelerExt       Extension-Id::= 0  -- FourWheelerExtensions
   eightWheelerExt      Extension-Id::= 1  -- EightWheelerExtensions

VehicleMessageExtension MESSAGE-EXT-ID-AND-TYPE ::= { 
   { FourWheelerExtensions       IDENTIFIED BY fourWheelerExt } |
   { EightWheelerExtensions     IDENTIFIED BY eightWheelerExt} ,
   ... 
   }   

Relevant snippets from the generated header files:

/* From VehicleMessage.h */
/* VehicleMessage */
typedef struct VehicleMessage {
    Velocity_t   speed;
    struct VehicleMessage__extensionList {
        A_SEQUENCE_OF(struct VehicleMessageExtension ) list;

        /* Context for parsing across buffer boundaries */
        asn_struct_ctx_t _asn_ctx;
    } *extensionList;
    /*
     * This type is extensible,
     * possible extensions are below.
     */

    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} VehicleMessage_t;

/* From Extension.h */
/* Dependencies */
typedef enum VehicleMessageExtension__extension_Value_PR {
    VehicleMessageExtension__extension_Value_PR_NOTHING,    /* No components present */
    VehicleMessageExtension__extension_Value_PR_FourWheelerExtensions,
    VehicleMessageExtension__extension_Value_PR_EightWheelerExtensions
} VehicleMessageExtension__extension_Value_PR;

/* Extension */
typedef struct VehicleMessageExtension {
    Extension_Id_t   extension_Id;
    struct VehicleMessageExtension__extension_Value {
        VehicleMessageExtension__extension_Value_PR present;
        union VehicleMessageExtension__extension_Value_u {
            FourWheelerExtensions_t  FourWheelerExtensions;
            EightWheelerExtensions_t     EightWheelerExtensions;
        } choice;

        /* Context for parsing across buffer boundaries */
        asn_struct_ctx_t _asn_ctx
    } extension_Value;

    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} VehicleMessageExtension_t;

Code snippet below that describes some of my failed attempts at encoding the message after adding an element to the VehicleMessage_t's extensionList sequence.:

        VehicleMessage_t* vehicle_msg;
        vehicle_msg = (VehicleMessage_t*) calloc(1, sizeof(VehicleMessage_t));

        vehicle_msg->speed = 24;  // Set VehicleMessage 'speed' field

        VehicleMessageExtension_t* extension_element;
        extension_element= (VehicleMessageExtension_t*) calloc(1, sizeof(VehicleMessageExtension_t));

        extension_element->extension_Id = 1; // Set extension ID to 1 for 'eightWheelerExt'
        extension_element->extension_Value.present = VehicleMessageExtension__extension_Value_PR_EightWheelerExtensions;

        // Encoding of vehicle_msg fails with any attempt at adding an element to the message's extensionList
        // NOTE: vehicle_msg is encoded successfully if no attempt is made to add extension_element to the message's extensionList
        asn_sequence_add(&vehicle_msg->extensionList->list, extension_element); // Fails in the encoding step
        // asn_sequence_add(&vehicle_msg->extensionList, extension_element); // Another approach I've tried, this fails in the encoding step as well

        // Encode message
        uint8_t buffer[544];
        size_t buffer_size=sizeof(buffer);
        asn_enc_rval_t ec;
        ec = uper_encode_to_buffer(&asn_DEF_VehicleMessage, 0 , vehicle_msg, buffer , buffer_size);

        // Log a warning if encoding fails
        if(ec.encoded == -1) {
            std::cout<< "Encoding has failed.";
        }
        else {
            std::cout<< "Encoding has succeeded.";
        }
JonSmet commented 1 year ago

@jamidon Hello, I was reading through your recent issue (#113) and saw that you were able to successfully add an element to a BasicSafetyMessage's regional sequence and encode the message. That seems very similar to the work I am trying to do, if you have time would you be willing to describe how you were able to do this?

JonSmet commented 1 year ago

I was able to fix this issue. I ended up adding to partII->list using the following approach:

        VehicleMessage_t* vehicle_msg;
        vehicle_msg = (VehicleMessage_t*) calloc(1, sizeof(VehicleMessage_t));

        vehicle_msg->speed = 24;  // Set VehicleMessage 'speed' field

       VehicleMessage_t::VehicleMessage__extensionList*  extension_list;
       extension_list = (VehicleMessage_t::VehicleMessage__extensionList*) calloc(1, sizeof(VehicleMessage_t::VehicleMessage__extensionList));

        VehicleMessageExtension_t* extension_element;
        extension_element= (VehicleMessageExtension_t*) calloc(1, sizeof(VehicleMessageExtension_t));

        extension_element->extension_Id = 1; // Set extension ID to 1 for 'eightWheelerExt'
        extension_element->extension_Value.present = VehicleMessageExtension__extension_Value_PR_EightWheelerExtensions;

        asn_sequence_add(&extension_list->list, extension_element);

        vehicle_msg->extensionList = extension_list;

        // Encode message
        uint8_t buffer[544];
        size_t buffer_size=sizeof(buffer);
        asn_enc_rval_t ec;
        ec = uper_encode_to_buffer(&asn_DEF_VehicleMessage, 0 , vehicle_msg, buffer , buffer_size);