1. 20 Dec, 2023 3 commits
  2. 19 Dec, 2023 1 commit
    • Cedric Roux's avatar
      APER: fix non negative normally small whole numbers · ee6458b2
      Cedric Roux authored
      aper_put_nsnnwn() and aper_get_nsnnwn() were wrong. All the places
      where they were used are modified, if needed.
      
      The functions aper_get_constrained_whole_number() and
      aper_put_constrained_whole_number() are introduced.
      They don't cover all cases, very big numbers are not supported.
      
      The sample ASN.1 file and C program at the end show some issues.
      
      For sequence-of, APER decoding fails and the XER output after
      APER encode/decode is:
      
      -----------
      xer after encode/decode:
      <ListOfInt>
          <INTEGER>1</INTEGER>
          <INTEGER>259</INTEGER>
      </ListOfInt>
      -----------
      
      instead of:
      
      -----------
      xer after encode/decode:
      <ListOfInt>
          <INTEGER>1</INTEGER>
          <INTEGER>2</INTEGER>
          <INTEGER>3</INTEGER>
      </ListOfInt>
      -----------
      
      For the enum test, we have:
      
      -----------
      aper ue lost[1]: d4
      -----------
      
      instead of:
      
      -----------
      aper ue lost[1]: 95
      -----------
      
      And APER decoding fails.
      
      For the choice test, we see:
      
      -----------
      aper snssai[3]: 80 01 00
      -----------
      
      instead of:
      
      -----------
      aper snssai[3]: 84 01 00
      -----------
      
      And XER after encode/decode is wrong.
      
      To generate C code from the ASN.1 file, asn1c is run as:
      asn1c -pdu=all -fno-include-deps -fcompound-names -gen-UPER -no-gen-BER -no-gen-JER -no-gen-OER -gen-APER -no-gen-example
      
      ASN.1 file:
      
      -----------
      Test DEFINITIONS AUTOMATIC TAGS ::=
      
      BEGIN
      
      TestCond-Type ::= CHOICE{
              gBR                                     ENUMERATED {true, ...},
              aMBR                            ENUMERATED {true, ...},
              isStat                          ENUMERATED {true, ...},
              isCatM                          ENUMERATED {true, ...},
              rSRP                            ENUMERATED {true, ...},
              rSRQ                            ENUMERATED {true, ...},
              ...,
              ul-rSRP                         ENUMERATED {true, ...},
              cQI                                     ENUMERATED {true, ...},
              fiveQI                          ENUMERATED {true, ...},
              qCI                                     ENUMERATED {true, ...},
              sNSSAI                          ENUMERATED {true, ...}
      }
      
      CauseRadioNetwork ::= ENUMERATED {
              handover-desirable-for-radio-reasons,
              time-critical-handover,
              resource-optimisation-handover,
              reduce-load-in-serving-cell,
              partial-handover,
              unknown-new-eNB-UE-X2AP-ID,
              unknown-old-eNB-UE-X2AP-ID,
              unknown-pair-of-UE-X2AP-ID,
              ho-target-not-allowed,
              tx2relocoverall-expiry,
              trelocprep-expiry,
              cell-not-available,
              no-radio-resources-available-in-target-cell,
              invalid-MME-GroupID,
              unknown-MME-Code,
              encryption-and-or-integrity-protection-algorithms-not-supported,
              reportCharacteristicsEmpty,
              noReportPeriodicity,
              existingMeasurementID,
              unknown-eNB-Measurement-ID,
              measurement-temporarily-not-available,
              unspecified,
              ...,
              load-balancing,
              handover-optimisation,
              value-out-of-allowed-range,
              multiple-E-RAB-ID-instances,
              switch-off-ongoing,
              not-supported-QCI-value,
              measurement-not-supported-for-the-object,
              tDCoverall-expiry,
              tDCprep-expiry,
              action-desirable-for-radio-reasons,
              reduce-load,
              resource-optimisation,
              time-critical-action,
              target-not-allowed,
              no-radio-resources-available,
              invalid-QoS-combination,
              encryption-algorithms-not-supported,
              procedure-cancelled,
              rRM-purpose,
              improve-user-bit-rate,
              user-inactivity,
              radio-connection-with-UE-lost,
              failure-in-the-radio-interface-procedure,
              bearer-option-not-supported,
              mCG-Mobility,
              sCG-Mobility,
              count-reaches-max-value,
              unknown-old-en-gNB-UE-X2AP-ID,
              pDCP-Overload
      }
      
      ListOfInt ::= SEQUENCE (SIZE (3)) OF INTEGER
      
      END
      -----------
      
      C program:
      
      -----------
      
      void test(void *v, int is_aper, char *name, void *t)
      {
        unsigned char b[128];
        asn_enc_rval_t r = asn_encode_to_buffer(NULL,
                             is_aper ? ATS_ALIGNED_BASIC_PER
                                     : ATS_UNALIGNED_BASIC_PER,
                             t, v, b, sizeof(b));
        if (r.encoded <= 0) printf("error\n"); else printf("ok\n");
        printf("%s %s[%ld]:", is_aper ? "aper" : "uper", name, r.encoded);
        for (int i = 0; i < r.encoded; i++) printf(" %2.2x", b[i]);
        printf("\n");
      
        void *ret = NULL;
        asn_dec_rval_t d = asn_decode(NULL,
                             is_aper ? ATS_ALIGNED_BASIC_PER
                                     : ATS_UNALIGNED_BASIC_PER,
                             t, &ret, b, r.encoded);
        if (d.consumed != r.encoded) printf("error\n"); else printf("ok\n");
        printf("xer of input:\n");
        xer_fprint(stdout, t, v);
        printf("xer after encode/decode:\n");
        xer_fprint(stdout, t, ret);
      }
      
      int main(void)
      {
        /* test sequence of */
        ListOfInt_t l = { 0 };
        long val[3] = { 1, 2, 3 };
        asn_sequence_add(&l.list, &val[0]);
        asn_sequence_add(&l.list, &val[1]);
        asn_sequence_add(&l.list, &val[2]);
        test(&l, 1, "sequence-of (size 3)", &asn_DEF_ListOfInt);
        test(&l, 0, "sequence-of (size 3)", &asn_DEF_ListOfInt);
      
        /* test enum */
        CauseRadioNetwork_t v;
        v = CauseRadioNetwork_radio_connection_with_UE_lost;
      
        test(&v, 1, "ue lost", &asn_DEF_CauseRadioNetwork);
        test(&v, 0, "ue lost", &asn_DEF_CauseRadioNetwork);
      
        v = CauseRadioNetwork_cell_not_available;
      
        test(&v, 1, "no cell", &asn_DEF_CauseRadioNetwork);
        test(&v, 0, "no cell", &asn_DEF_CauseRadioNetwork);
      
        /* test choice */
        TestCond_Type_t w;
        w.present = TestCond_Type_PR_sNSSAI;
        w.choice.sNSSAI = TestCond_Type__sNSSAI_true;
      
        test(&w, 1, "snssai", &asn_DEF_TestCond_Type);
        test(&w, 0, "snssai", &asn_DEF_TestCond_Type);
      
        w.present = TestCond_Type_PR_gBR;
        w.choice.sNSSAI = TestCond_Type__gBR_true;
      
        test(&w, 1, "gbr", &asn_DEF_TestCond_Type);
        test(&w, 0, "gbr", &asn_DEF_TestCond_Type);
      
        return 0;
      }
      -----------
      ee6458b2
  3. 16 Dec, 2023 6 commits
  4. 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
  5. 12 Dec, 2023 1 commit
  6. 11 Dec, 2023 4 commits
  7. 10 Dec, 2023 1 commit
  8. 08 Dec, 2023 3 commits
  9. 05 Dec, 2023 1 commit
  10. 04 Dec, 2023 2 commits
  11. 03 Dec, 2023 5 commits
  12. 02 Dec, 2023 1 commit
  13. 01 Dec, 2023 5 commits
  14. 30 Nov, 2023 2 commits
  15. 29 Nov, 2023 2 commits
  16. 28 Nov, 2023 2 commits
    • Mouse's avatar
      Update asn_random_fill.c · 23e6769e
      Mouse authored
      Per Chetan Pandey, addressing missing include that leaves random() undeclared
      23e6769e
    • Mouse's avatar
      Update GeneralizedTime.c · 60a820fa
      Mouse authored
      As per #493 in vlm/asn1c by Chetan Pandey, fixing the timezone macro
      60a820fa