1. 15 Dec, 2023 1 commit
    • Cedric Roux's avatar
      PER: fix encoding and decoding of OPENTYPE with size constraints · 03d18778
      Cedric Roux authored
      Constraints have to be used. If not the encoding or decoding may be
      wrong.
      
      For example RRC-Version of 3GPP 38.473 contains an extension with a
      fixed size constraint (so the size is not encoded).
      
      Here is a small ASN.1 file extracted from 38.473 to illustrate the
      problem.
      
      ----
      F1AP-PDU-Descriptions  {
      itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
      ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)}
      
      DEFINITIONS AUTOMATIC TAGS ::=
      
      BEGIN
      
      ProtocolExtensionID     ::= INTEGER (0..65535)
      Criticality             ::= ENUMERATED { reject, ignore, notify }
      Presence                ::= ENUMERATED { optional, conditional, mandatory }
      maxProtocolExtensions                                   INTEGER ::= 65535
      id-latest-RRC-Version-Enhanced                                          ProtocolIE-ID ::= 199
      
      ProtocolIE-ID           ::= INTEGER (0..65535)
      
      F1AP-PROTOCOL-EXTENSION ::= CLASS {
              &id                             ProtocolExtensionID                     UNIQUE,
              &criticality    Criticality,
              &Extension,
              &presence               Presence
      }
      WITH SYNTAX {
              ID                              &id
              CRITICALITY             &criticality
              EXTENSION               &Extension
              PRESENCE                &presence
      }
      
      ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::=
              SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
              ProtocolExtensionField {{ExtensionSetParam}}
      
      ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
              id                                      F1AP-PROTOCOL-EXTENSION.&id                             ({ExtensionSetParam}),
              criticality                     F1AP-PROTOCOL-EXTENSION.&criticality    ({ExtensionSetParam}{@id}),
              extensionValue          F1AP-PROTOCOL-EXTENSION.&Extension              ({ExtensionSetParam}{@id})
      }
      
      RRC-Version ::= SEQUENCE        {
              latest-RRC-Version                      BIT STRING (SIZE(3)),
              iE-Extensions                           ProtocolExtensionContainer { { RRC-Version-ExtIEs } }   OPTIONAL}
      
      RRC-Version-ExtIEs      F1AP-PROTOCOL-EXTENSION ::= {
              {ID id-latest-RRC-Version-Enhanced              CRITICALITY ignore EXTENSION OCTET STRING (SIZE(3))             PRESENCE optional },
              ...
      }
      
      END
      ----
      
      And a small program to test:
      
      ----
      
      int main(void)
      {
        RRC_Version_t version;
        unsigned char x;
        char out[1024];
      
        unsigned char ver3[3] = { 0x11, 0x05, 0x01 };
      
        version.latest_RRC_Version.buf = &x;
        version.latest_RRC_Version.buf[0] = 0xe0;
        version.latest_RRC_Version.size = 1;
        version.latest_RRC_Version.bits_unused = 5;
      
        ProtocolExtensionContainer_32P0_t ext = { 0 };
      
        RRC_Version_ExtIEs_t ie;
        ie.id = ProtocolIE_ID_id_latest_RRC_Version_Enhanced;
        ie.criticality = Criticality_ignore;
        ie.extensionValue.present = RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_;
        ie.extensionValue.choice.OCTET_STRING_SIZE_3_.buf = ver3;
        ie.extensionValue.choice.OCTET_STRING_SIZE_3_.size = 3;
        ASN_SEQUENCE_ADD(&ext.list, &ie);
      
        version.iE_Extensions = (void*)&ext;
      
        fflush(stdout);
        fflush(stderr);
        xer_fprint(stdout, &asn_DEF_RRC_Version, &version);
        fflush(stdout);
        fflush(stderr);
      
        void *dec;
      
        asn_enc_rval_t enc_ret = aper_encode_to_buffer(&asn_DEF_RRC_Version, NULL, &version, out, sizeof(out));
        if (enc_ret.encoded <= 0) printf("encode failed\n"); else printf("encode ok\n");
        printf("encoded aper[%ld]:", (enc_ret.encoded+7)/8);
        for (int i = 0; i < (enc_ret.encoded+7) / 8; i++) printf(" %2.2x", (unsigned char)out[i]);
        printf("\n");
      
        dec = NULL;
        asn_dec_rval_t dec_ret = asn_decode(NULL, ATS_ALIGNED_BASIC_PER, &asn_DEF_RRC_Version, &dec, out, (enc_ret.encoded+7) / 8);
        if (dec_ret.code) printf("decode failed\n"); else printf("decode ok\n");
        fflush(stdout);
        fflush(stderr);
        xer_fprint(stdout, &asn_DEF_RRC_Version, dec);
        fflush(stdout);
        fflush(stderr);
      
        enc_ret = uper_encode_to_buffer(&asn_DEF_RRC_Version, NULL, &version, out, sizeof(out));
        if (enc_ret.encoded <= 0) printf("encode failed\n"); else printf("encode ok\n");
        printf("encoded uper[%ld]:", (enc_ret.encoded+7)/8);
        for (int i = 0; i < (enc_ret.encoded+7) / 8; i++) printf(" %2.2x", (unsigned char)out[i]);
        printf("\n");
      
        dec = NULL;
        dec_ret = asn_decode(NULL, ATS_UNALIGNED_BASIC_PER, &asn_DEF_RRC_Version, &dec, out, (enc_ret.encoded+7) / 8);
        if (dec_ret.code) printf("decode failed\n"); else printf("decode ok\n");
        fflush(stdout);
        fflush(stderr);
        xer_fprint(stdout, &asn_DEF_RRC_Version, dec);
        fflush(stdout);
        fflush(stderr);
      
        return 0;
      }
      ----
      
      It encodes as following:
      
      APER: f0 00 00 00 c7 40 04 03 11 05 01
      UPER: f0 00 00 0c 74 10 0c 44 14 04
      
      Instead of:
      
      APER: f0 00 00 00 c7 40 03 11 05 01
      UPER: f0 00 00 0c 74 0c 44 14 04
      
      (Basically since the size is fixed, it shall not be encoded.)
      
      Note: this commit does not solve all cases. For example the constraint:
      
          SIZE(3..1000000)
      
      is not managed properly. (Solved in another commit.)
      03d18778
  2. 12 Dec, 2023 1 commit
  3. 11 Dec, 2023 4 commits
  4. 10 Dec, 2023 1 commit
  5. 08 Dec, 2023 3 commits
  6. 05 Dec, 2023 1 commit
  7. 04 Dec, 2023 2 commits
  8. 03 Dec, 2023 5 commits
  9. 02 Dec, 2023 1 commit
  10. 01 Dec, 2023 5 commits
  11. 30 Nov, 2023 2 commits
  12. 29 Nov, 2023 2 commits
  13. 28 Nov, 2023 3 commits
  14. 14 Nov, 2023 1 commit
  15. 13 Nov, 2023 1 commit
  16. 12 Nov, 2023 1 commit
  17. 09 Nov, 2023 3 commits
  18. 10 Oct, 2023 2 commits
  19. 06 Oct, 2023 1 commit