Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPDLC encoding build failure #13

Closed
hvastani opened this issue Jun 7, 2021 · 3 comments
Closed

CPDLC encoding build failure #13

hvastani opened this issue Jun 7, 2021 · 3 comments

Comments

@hvastani
Copy link

hvastani commented Jun 7, 2021

I am trying to encode an uplink UM106MaintainSpeed message using the following sample code

#include <stdint.h>
#include <string.h>
#include <math.h>
#include <libacars/asn1/FANSATCUplinkMessage.h>
#include <libacars/asn1/FANSATCUplinkMsgElementId.h>
#include <libacars/asn1/FANSATCUplinkMsgElementIdSequence.h>
#include <libacars/asn1/FANSSpeed.h>
#include <libacars/libacars.h>
#include <libacars/cpdlc.h>


void build() {
    FANSATCUplinkMessage_t um;
    um.aTCMessageheader.msgIdentificationNumber = 15;
    um.aTCMessageheader.msgReferenceNumber = NULL;
    um.aTCMessageheader.timestamp->hours = 9;
    um.aTCMessageheader.timestamp->minutes = 25;
    um.aTCMessageheader.timestamp->seconds = 35;
    um.aTCuplinkmsgelementId.present = FANSATCUplinkMsgElementId_PR_uM106Speed,
    um.aTCuplinkmsgelementId.choice.uM106Speed.present = FANSSpeed_PR_speedIndicated;
    um.aTCuplinkmsgelementId.choice.uM106Speed.choice.speedIndicated = 200;
    um.aTCuplinkmsgelementid_seqOf = NULL;

    la_proto_node *node = la_proto_node_new();
    //LA_NEW(la_cpdlc_msg, msg);
    la_cpdlc_msg msg;
    msg.data = &um;
    node->data = &msg;
    node->td = &la_DEF_cpdlc_message;
    msg.asn_type = &asn_DEF_FANSATCUplinkMessage;

    unsigned char output[50];
    uper_encode_to_buffer(&asn_DEF_FANSATCUplinkMessage, node, output, 50);
}

int main(int argc, char **argv) {
    build();
}

I added this file to the examples directory and updated the CMakeLists.txt EXAMPLE_BINARIES set

I get the following compile error when running make

MakeFiles/cpdlc_maintain_speed.dir/cpdlc_maintain_speed.c.o: In function `build':
cpdlc_maintain_speed.c:(.text+0x8a): undefined reference to `asn_DEF_FANSATCUplinkMessage'
cpdlc_maintain_speed.c:(.text+0xa4): undefined reference to `asn_DEF_FANSATCUplinkMessage'
cpdlc_maintain_speed.c:(.text+0xb0): undefined reference to `uper_encode_to_buffer'
collect2: error: ld returned 1 exit status
make[2]: *** [examples/cpdlc_maintain_speed] Error 1
make[1]: *** [examples/CMakeFiles/cpdlc_maintain_speed.dir/all] Error 2
make: *** [all] Error 2

Are there other changes needed to be made to build this code ?

@szpajder
Copy link
Owner

szpajder commented Jun 8, 2021

Binaries in examples directory get linked with libacars-2.so.2, but this library does not contain the routines that perform encoding. Only decoders are included. Hence, you can't use uper_encode_to_buffer() because it's simply not there - neither in libacars headers nor in the resulting library.

You may ask then, why is that, given that this function exists in asn1/per_encoder.c. Indeed, it does, because all code in the asn1 subdirectory is generated automatically and the generator kindly provides routines for decoding as well as encoding. However libacars by design only does decoding, so the encoding code could safely be removed from the tree and the library would still do everything it does now. Removal of redundant code requires manual work and I would need to do this every time I regenerate the ASN.1 code - so I don't because I'm lazy :-) But it's on my TODO list and I'll probably do this one day. Meanwhile you can use it to achieve your goal, but in a little different way - you need to put your program directly into libacars source tree and build it together with libacars, but link it directly to the asn1 library, which has the uper_encode_to_buffer() function that you need. Do the following:

  • put your program into the libacars/libacars directory
  • add the following to CMakeLists.txt in this directory:
add_executable(cpdlc_maintain_speed cpdlc_maintain_speed.c)
target_link_libraries(cpdlc_maintain_speed asn1 acars)
  • the program should look like this:
#include <stdio.h>
#include "asn1/FANSATCUplinkMessage.h"
#include "asn1/FANSTimestamp.h"
#include "asn1/asn_application.h"

void build() {
        FANSATCUplinkMessage_t um = {0};
        um.aTCMessageheader.msgIdentificationNumber = 15;
        um.aTCMessageheader.msgReferenceNumber = NULL;
        FANSTimestamp_t t = {0};
        t.hours = 9;
        t.minutes = 25;
        t.seconds = 35;
        um.aTCMessageheader.timestamp = &t;
        um.aTCuplinkmsgelementId.present = FANSATCUplinkMsgElementId_PR_uM106Speed,
        um.aTCuplinkmsgelementId.choice.uM106Speed.present = FANSSpeed_PR_speedIndicated;
        um.aTCuplinkmsgelementId.choice.uM106Speed.choice.speedIndicated = 20;
        um.aTCuplinkmsgelementid_seqOf = NULL;

        unsigned char output[50] = {0};
        asn_enc_rval_t rval = uper_encode_to_buffer(&asn_DEF_FANSATCUplinkMessage, &um, output, 50);
        if(rval.encoded == -1) {
                printf("Encoding failed at type %s\n", rval.failed_type->name);
        } else {
                printf("Encoding successful, %zd bits produced\n", rval.encoded);
                for(int i = 0; i < rval.encoded / 8 + (rval.encoded % 8 > 0); i++) {
                        printf("%02x ", output[i]);
                }
                printf("\n");
        }
}

int main() {
        build();
}
  • Build libacars as usual. Your program will be built as well.

Also note that FANSSpeedIndicated is expressed in tens of knots, so in order to express 200, you have to put a value of 20.

@hvastani
Copy link
Author

Thanks for your quick reply. I realized that those encode functions were not available in the libacars library so I added a few to support cpdlc encoding like a 'la_cpdlc_build' function to cpdlc.c which calls 'la_asn1_encode_as' function which calls 'uper_encode_to_buffer' and its working great. If you like, I can make a patch for it for your review.

It would be great if the libacars library supported both encoding and decoding including the json serialize/deserialize.
Good catch on the indicated speed value.

Thanks for your help

@szpajder
Copy link
Owner

Thank you for suggestion, however I prefer to keep libacars to be a decoding library. Complete implementation of all encoders would require writing a significant amount of code, which use would be extremely limited, but it would still need to be maintained by someone (guess who). I therefore prefer to spend time on projects that might be interesting to a bit broader audience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants