Skip to content

How to code a SEQUENCE OF inside a SEQUENCE OF (asn1 to c) #168

@Santiago1969

Description

@Santiago1969

I'm working with vanetza to make cpms messages, I have built the .c and .cpp files from the asn1, so the structures of the message have the structure of the asn1. I have a structure (PerceptionDataContainer) which is a SEQUENCE OF PerceptionData, the Sequence of is a special type of list. Each PerceptionData have a perceivedobjects structure which is a SEQUENCE OF PerceivedObject struct, I have made this code to add information to these struct;

vanetza::asn1::Cpm cpm;

auto object = asn1::allocate<PerceivedObject_t>(); //this fill the struct PerceivedObject with basic info
auto perception = asn1::allocate<PerceptionData_t>();

PerceivedObject *arrayobjeto[2];

cpm->cpm.cpmParameters.perceptionData = asn1::allocate<CpmParameters::CpmParameters__perceptionData>();

cpm->header.protocolVersion=2;
cpm->header.messageID=ItsPduHeader__messageID_cpm;
cpm->header.stationID=1;
cpm->cpm.cpmParameters.managementContainer.stationType=2;

for(int i=0; i<2;i++) {
    arrayobjeto[i]=asn1::allocate<PerceivedObject>();
    arrayobjeto[i]->objectID= i+1;
    arrayobjeto[i]->timeOfMeasurement = TimeOfMeasurement_oneMilliSecond;
    arrayobjeto[i]->xDistance.value = DistanceValue_oneMeter;
    arrayobjeto[i]->xDistance.confidence = DistanceConfidence_oneMeter;
    arrayobjeto[i]->yDistance.value = DistanceValue_oneMeter;
    arrayobjeto[i]->yDistance.confidence = DistanceConfidence_oneMeter;
    arrayobjeto[i]->xSpeed.value = SpeedValueExtended_oneCentimeterPerSec;
    arrayobjeto[i]->xSpeed.confidence = SpeedConfidence_equalOrWithinOneMeterPerSec;
    arrayobjeto[i]->ySpeed.value = SpeedValueExtended_oneCentimeterPerSec;
    arrayobjeto[i]->ySpeed.confidence = SpeedConfidence_equalOrWithinOneMeterPerSec;
}
perception->containerId=1;
perception->containerData.present=PerceptionData__containerData_PR_PerceivedObjectContainer;
perception->containerData.choice.PerceivedObjectContainer.numberOfPerceivedObjects=1;

for(int i=0; i<2;i++) {
    EXPECT_EQ(0, ASN_SEQUENCE_ADD(&perception->containerData.choice.PerceivedObjectContainer.perceivedObjects,arrayobjeto[i]));
}
EXPECT_EQ(0, ASN_SEQUENCE_ADD(&cpm->cpm.cpmParameters.perceptionData->list, perception));
EXPECT_EQ(1, cpm->cpm.cpmParameters.perceptionData->list.count);
EXPECT_EQ(2, cpm->cpm.cpmParameters.perceptionData->list.array[0]->containerData.choice.PerceivedObjectContainer.perceivedObjects.list.count);
EXPECT_EQ(perception, cpm->cpm.cpmParameters.perceptionData->list.array[0]);
EXPECT_EQ(arrayobjeto[0], cpm->cpm.cpmParameters.perceptionData->list.array[0]->containerData.choice.PerceivedObjectContainer.perceivedObjects.list.array[0]);


EXPECT_TRUE(cpm.validate());
EXPECT_FALSE(cpm.encode().empty());
ByteBuffer buffer = cpm.encode();
std::cout << "tamaño: " << buffer.size() << "\n";
for (const auto byte:buffer){
    printf("%02x ",byte);
}

ASSERT_TRUE(cpm.decode(buffer));
std::cout << cpm.size();

The definitions of the structs are these:

typedef struct CpmParameters {
   CpmManagementContainer_t     managementContainer;
   struct OriginatingStationData   *stationDataContainer;  /* OPTIONAL */
   struct CpmParameters__perceptionData {
    A_SEQUENCE_OF(struct PerceptionData) list;
    
    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} *perceptionData;

....

  typedef struct PerceptionData {
    CpmContainerId_t     containerId;
    struct PerceptionData__containerData {
        PerceptionData__containerData_PR present;
        union PerceptionData__containerData_u {
            SensorInformationContainer_t     SensorInformationContainer;
            PerceivedObjectContainer_t   PerceivedObjectContainer;
            FreeSpaceAddendumContainer_t     FreeSpaceAddendumContainer;
      } choice;
    
    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} containerData;

....

typedef struct PerceivedObjectContainer {
   NumberOfPerceivedObjects_t   numberOfPerceivedObjects;  /* DEFAULT 0 */
   struct PerceivedObjectContainer__perceivedObjects {
       A_SEQUENCE_OF(struct PerceivedObject) list;
    
    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} perceivedObjects;

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

I have reached a good encode but it can not be decode correctly and it seems I have loaded the data into the structs not perfectly, anyone knows how to do it correctly?

When I encode in vanetza the data it does a solution like this: 02 0e 00 00 00 01 00 00 20 13 5a 4e 90 06 b4 9d 20 00 00 00 00 00 18 6a 00 00 01 24 80 80 80 00 00 57 75 03 82 64 40 e0 99 20 00 63 80 01 8c 00 00 04 bb a8 1c 13 22 07 04 c9 00 03 1c 00 0c 60
But when I try to decode it it return false, (can't decode correctly the message) When I don't include the fields of the SEQUENCE OFs it encodes and decodes correctly

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions