═══ 1. Note ═══ Before using this information and the product it supports, be sure to read the general information under Notice First Edition, December 1993 IBM welcomes your comments. A form for readers comments may be provided at the back of this publication, or you may address your comments to the following address: Rome Networking Software Laboratory IBM Semea S.p.A. P.le Giulio Pastore, 6 00144 Rome Italy When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information in any way it believes appropriate without incurring any obligation to you. ═══ 2. Notices ═══ References in this publication to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program, or service. Evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, is the user's responsibility. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Commercial Relations, IBM Corporation, Purchase, NY 10577. ═══ 2.1. Trademarks and Service Marks ═══ The following terms, denoted by an asterisk (*) in this publication, are trademarks of the IBM Corporation in the United States and/or other countries: AIX AIX/6000 BookMaster IBM OS/2 ═══ 3. Introduction ═══ The General Data Stream Encoder Decoder (GenE/D) is a software system for encoding and decoding communications data streams in both SNA and OSI architectures. GenE/D can be used in any situation where two applications have to exchange data and they agree on: o The protocol, describable using the Abstract Syntax Notation One (ASN.1) o The transfer syntax, prescribed by IBM* General Data Stream Definitions (GDSD) or ISO/OSI Basic Encoding Rules (BER) This means that the GenE/D system can be integrated not only in SNA and OSI applications, but also in any TCP/IP, LAN, and proprietary protocol application. ═══ 3.1. Related Documentation ═══ ═══ 3.1.1. ISO/IEC Standards ═══ ISO/IEC 8824 Information Processing - Open Systems Interconnection - Specification of Abstract Syntax Notation One (ASN.1) (April 1990) ISO/IEC 8825 Information Processing - Open Systems Interconnection - Specification of Abstract Syntax Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1) (April 1990) ═══ 3.1.2. SNA Protocols ═══ SNA Logical Unit Version 6 Reference: Peer Protocols , SC31-6808-01 ═══ 3.2. Terminology ═══ o A data stream (DS) is a sequence of bytes. In OSI environment it is referred to as a Protocol Data Unit (PDU). o A byte (eight bits) in the OSI environment is referred to as an octet. o The terms IDENTIFIER and TYPE are used interchangeably to indicate a specific field of the GDS variable. ═══ 4. Overview ═══ The General Data Stream Encoder consists of the following components: o The Abstract Syntax Notation One (ASN.1) language compiler, used to compile the ASN.1 specification of the data stream structure. The result of the compiling step consists of a TBL file containing a Symbol Table and a Metatable. The TBL file is system independent. o The TBL file translator, used to transform the TBL file in a system-dependent form usable by the run-time routines library. o The runtime routines library, containing a set of routines that the User Application Program (UAP) can call to encode or decode the data stream, and to do other useful operations. The data stream can be encoded/decoded following two encoding rules: - ISO/IEC 8825 Basic Encoding Rules - IBM General Data Stream Definitions ASN.1 is a format notation for describing syntactic and semantic aspects of data. ASN.1 is an abstract representation because it does not specify how data is represented in a local computer nor does it specify how data is represented when they are communicated between systems. For two applications to meaningfully communicate with each other, they must first agree on this level of abstraction. The second requirement is that the two involved applications agree on a way to represent information when it is transferred between them. That is, the applications must agree on a transfer syntax. The third form of data representation is the local syntax, in which form each application directly manipulates the data. The local syntax depends on the application programming language, the compiler for the programming language, and the computer architecture on which the application runs. In general, the relationship between abstract, transfer, and local representations is many to many. For data communications specifications, the abstract and transfer syntaxes are the only relevant representations. ASN.1 is an abstract representation. Basic Encoding Rules (BER) and IBM General Data Stream Definitions (GDSD) are two transfer representations. The following figure gives an overall description of the GenE/D system and of its use by the UAP. GenE/D System, overall description ═══ 5. Characteristics Summary ═══ These section summarizes the characteristics and functions of the GenE/D system. ═══ 5.1. GenE/D System Users ═══ GenE/D users are networking applications and systems programmers. ═══ 5.2. High-level protocol definition language ═══ The protocol used by the communicating applications (that is, the syntax of the data streams exchanged) must be defined for the GenE/D system using the ASN.1 notation. This type of interface offers the following advantages: o It is system independent. o It is general enough to cover all types of communication protocols. o It is an ISO/OSI standard notation, used not only in the OSI architecture, but also in TCP/IP and other proprietary network architectures. o All the OSI 6 and 7 level protocols are already defined with ASN.1, so for these protocols the coding effort is reduced. ═══ 5.3. High-level application interface ═══ A set of C runtime routines are available to the application in order to: o Initialize or terminate a session o Search or access the data o Convert the data o Encode or decode the data o Format the data ═══ 5.4. Product Independence ═══ GenE/D can be used by different applications. GenE/D is coded in C language. ═══ 5.5. Portability ═══ GenE/D runs on OS/2* and AIX/6000* systems. ═══ 5.6. Protocol independence ═══ GenE/D can encode and decode any type of data stream. A Metatable and Symbol Table must be generated (using the ASN.1 compiler) for each protocol the application wants to follow during the encoding and decoding of the data streams. ═══ 5.7. IBM GDS Definitions and BER support ═══ GenE/D supports two possible transfer syntaxes: o The transfer syntax prescribed by the IBM General Data Streams Definitions, used in the SNA architecture. o The transfer syntax prescribed by the OSI Basic Encoding Rules, used in OSI and other architectures. ═══ 5.8. Unrecognized data management ═══ GenE/D can pass over unrecognized data. This function could be needed if more than one application uses the same Metatable and Symbol Table (the same protocol), but a new version of this protocol is not supported by all of them. ═══ 5.9. Data Stream Segmentation Support ═══ GenE/D supports the two segmentation algorithms implemented in SNA products for GDS data streams (the DIA/SNADS and the LU6.2/LEN segmentation algorithms). ═══ 5.10. Indefinite Length Data Stream ═══ The application can pass/get the encoded/decoded data to/from GenE/D routines in pieces. In this way the application can easily encode/decode very long data streams irrespective of the limits of the input/output buffer length. ═══ 5.11. Input/Output independence ═══ The application can choose where read or write the data streams. GenE/D is unaware of the data stream source/sink devices. ═══ 5.12. Common Metatable and Symbol Table for both encode/decode ═══ The protocol specification is translated by the ASN.1 compiler into a single Metatable and Symbol Table, so that one definition can be used for both encoding/decoding processes. This reduces coding effort and increases integrity. ═══ 5.13. Read-only Metatable and Symbol Table ═══ The same copy of the Metatable and Symbol Table can be used by several applications running concurrently. ═══ 5.14. Runtime readable Metatable and Symbol Table ═══ The Metatable and Symbol Table can be read at runtime. This makes the User Application Program independent from the protocol used (it could not be needed to recompile and link the application program if the Metatable and Symbol Table is changed). It means that general encoders/decoders can be implemented that can run with any Metatable and Symbol Table. ═══ 5.15. Test Tool ═══ A test tool is part of the GenE/D package. This test tool automatically encodes/decodes data streams and checks the results, executing a predefined set of scenarios. A scenario contains the ASN.1 specification of the protocol and the data that must be encoded. ═══ 6. Using the GenE/D System ═══ This chapter gives an example of use of the GenE/D system. If you have to implement an encoder or decoder that encodes or decodes data streams following a specific protocol, the GenE/D system can reduce most of your effort. The following are the steps you have to follow using the GenE/D system: 1. Edit the ASN.1 specification of the protocol, using your ordinary text editor (click here for the description of ASN.1 notation). 2. Compile the ASN.1 source file, edited in the first step, with the GDSASN1 compiler (click here for a description of the GDSASN1 compiler). Repeat this step until no errors are found in the ASN.1 source. 3. Translate the system-independent format of the Symbol Table and Metatable, generated by the GDSASN1 Compiler, into a system-dependent one, using the GDSTABLE translator (click here for a description of the GDSTABLE translator). 4. Edit the C modules of your encoder/decoder, which include the C headers file of GenE/D and contain the invocation to the GDSEDLIB run-time library routines (click here for the description of these routines). 5. Compile the C modules with your C compiler. 6. Link your objects specifying that the GDSEDLIB dynamic library is used. ═══ 6.1. ASN.1 source file ═══ The following is an example of ASN.1 source. It contains only one module. The ASN.1 keywords used in this example are DEFINITIONS, IMPLICIT, TAGS, BEGIN SEQUENCE, PrintableString, SET, OCTET STRING, INTEGER and OPTIONAL. --**********************************-- --* This is the file myasn1.asn *-- --**********************************-- MyModule DEFINITIONS -- module name IMPLICIT TAGS ::= -- default tagging is IMPLICIT BEGIN -- the module starts here MyType1 ::= SEQUENCE{ -- definition of Mytype as SEQUENCE item1 PrintableString, -- first component of MyType1 item2 [2] MyType2 OPTIONAL -- second component of MyType1 } -- end of the type definition MyType2 ::= SET{ -- definition of MyType2 as SET item3 OCTET STRING, -- first component of MyType2 item4 INTEGER -- second component of MyType2 } -- end of the type definition END -- end of the module To compile the myasn1.asn and produce the myasn1.tbl file, containing the Symbol Table and Metatable, use the following command: GDSASN1 myasn1.asn -tmyasn1.tbl ═══ 6.2. The Symbol Table and Metatable File in System-Independent Format ═══ The following is the myasn1.tbl text file generated by the GDSASN1 compiler after the compilation of the ASN.1 source file. GenE/D version 1.00 - 5648-075 symbol table len: 130 symbol table name: MyModule GLOBAL-MODULE MyModule MyType1 MyType2 PrintableString item1 DEFAULT IMPLICIT item2 SEQUENCE OCTET STRING item3 INTEGER item4 SET module: MyModule number of elements: 15 -2 type: MyType1 2 23 11 84 0 7 15 4 25 55 19 16 7 0 78 0 2 -1 2 7 23 31 8 18 -2 type: MyType2 2 31 13 126 2 14 15 12 10 106 15 14 3 120 14 18 -1 types/values/tables: 2 0 8 imports: 0 exports: 0 Module: MyModule 14 implicit The myasn1.tbl file is system independent. It can be generated on an OS/2 workstation and then ported to an AIX/6000 workstation (or viceversa) and translated with the GDSTABLE translator. ═══ 6.3. Translating the .TBL file ═══ To translate the Symbol Table and Metatable into a format usable by the routines of the GDSEDLIB runtime library, use the following command: GDSTABLE -tmyasn1.tbl -dmyasn1.dat -hmyasn1.h The myasn1.dat file contains the Symbol Table and Metatable and can be loaded at runtime by a specific GDSEDLIB routine (click here for a description of this routine). The myasn1.h C header file contains macro definitions of symbol names that can be used by your program to refer to the items defined in the Metatable: /* Defined constants for the types and values in module MyModule */ /* type: MyType1 of the module: MyModule */ #define MyModule_MyType1 0 #define MyModule_MyType1_SEQUENCE 4 #define MyModule_MyType1_SEQUENCE_item1_CharacterString 16 /* type: MyType2 of the module: MyModule */ #define MyModule_MyType2 57 #define MyModule_MyType2_SET 61 #define MyModule_MyType2_SET_item3_OCTET_STRING 73 #define MyModule_MyType2_SET_item4_INTEGER 81 ═══ 6.4. The C User Program ═══ The following is a sample of the user program implementing the BER encoder/decoder for the protocol defined in the myasn1.asn ASN.1 source file. /***********************************************************************/ /* encoder/decoder sample program for myasn1 protocol */ /***********************************************************************/ /********************************************************************* * The following header files are needed to compile this program. * Note that the order of the header files is important. ********************************************************************* */ #include #include #include #include #include "gdstypes.h" /* GDSEDLIB types declarations */ #include "gdsrcods.h" /* return codes of GDSEDLIB routines */ #include "gdsproto.h" /* prototypes of the GDSEDLIB routines */ #include "myasn1.h" /* definitions generated by GDSTABLE */ /************************* * PROTOTYPES ************************* */ /* the following is the prototype of the user writing routine */ unsigned long mywrite(char *buf, unsigned long buflen, void *usrparms); /* the following is the prototype of the user reading routine */ unsigned long myread(char *buf, unsigned long buflen, void *usrparms); main(void) { int rc; void *Mod, *env; unsigned short Typ; struct gds *p1; unsigned long EncBytes, DecBytes; FILE *trace_enc; FILE *trace_dec; FILE *EncStream; /* input-output file */ static char *dummy = "dummy"; unsigned char *hex_string, *int_cont, *out_buff, *in_buff, alldata; long lencont; struct contents_str *cont_array_ptr; struct gds **gds_tree_ptr; /* * Call the library routine, GDSinitEnvironment, to initialize the environment. * Each User Application Program should do this before calling any routine to * read .dat files, encode or decode data streams. */ rc = GDSinitEnvironment(&env); /* initialize environment for modules */ if (rc != INIT_ENV_OK) { printf("GDSinitEnvironment return code: %i\n", rc); return rc; } /* * Call the library routine, GDSreaddatfile, to read the myasn1.dat file * containing the Metatable and Symbol Table for the MyModule ASN.1 module. */ rc = GDSreaddatfile("myasn1.dat", env); if (rc != READ_DAT_OK) { printf("GDSreaddatfile return code: %i\n", rc); return rc; } /* * Call the library routine, GDSresolveallimports, to resolve imports and * exports in the myasn1.dat file. Note that if more than one .dat file had * been read in with multiple calls to GDSreaddatfile, this call should be * deferred as late as possible to maximize performance. Multiple calls * to GDSresolveallimports are allowed, however. * In our case no imports or exports are resolved because MyModule doesn't * contain imported or exported symbols. */ rc = GDSresolveallimports(env); if (rc != RESOLVE_IMPORTS_OK) { printf("GDSresolveallimports return code: %i\n", rc); /* * Call the library routine, GDSPrintUnresolvedImports, to print the * unresolved imports on standard output. */ GDSPrintUnresolvedImports(stdout, env); return rc; } /* * Call the library routine GDSsetUsrWrite, to set the user-exit routine for * writing buffer. */ GDSsetUsrWrite(mywrite, env); /* * Call the library routine GDSsetUsrRead, to set the user-exit routine for * reading buffer. */ GDSsetUsrRead(myread, env); /* * Call the library routine GDSfindmodule, to find the module structure * corresponding to MyModule. */ Mod = GDSfindmodule("MyModule", env); if (Mod == NULL) { /* if module not found */ printf("\nModule not found\n"); return(-1); } /* * Call the library routine GDSallocateContentsArray to allocate * the array of contents pointers for the specified module. * This function returns a pointer to the first location of the array. */ rc = GDSallocateContentsArray(Mod, &cont_array_ptr); if (rc == ALLOCATECONT_NO_ENOUGH_STORAGE) { printf("no enough storage for contents pointers array\n"); return(-1); } /* * Load the contents data in the contents-array */ /* fill the content, the content length and the storage class for item1 */ (cont_array_ptr[MyModule_MyType1_SEQUENCE_item1_CharacterString]).content = "item1"; (cont_array_ptr[MyModule_MyType1_SEQUENCE_item1_CharacterString]).len = 5; (cont_array_ptr[MyModule_MyType1_SEQUENCE_item1_CharacterString]).contstg = allocd; /* inform the encoder that the OPTIONAL item2 field must be encoded */ (cont_array_ptr[MyModule_MyType2_SET]).content = dummy; /* allocate storage for hexadecimal string */ hex_string = (unsigned char *) malloc(4*sizeof(unsigned char)); /* * Call the library routine GDSstr2hex to convert the printable form of * the hexadecimal string: '0011AABB'H into an hexadecimal form. */ GDSstr2hex(hex_string, 4, "0011AABB", 8); /* fill the content, the content length and the storage class for item3 */ (cont_array_ptr[MyModule_MyType2_SET_item3_OCTET_STRING]).content = hex_string; (cont_array_ptr[MyModule_MyType2_SET_item3_OCTET_STRING]).len = 4; (cont_array_ptr[MyModule_MyType2_SET_item3_OCTET_STRING]).contstg = allocd; /* allocate storage for INTEGER */ int_cont = (unsigned char *) malloc(sizeof(long)); /* * Call the library routine GDSlongtoINTEGER to convert the C long constant * 1 into a BER encoded INTEGER. */ GDSlongtoINTEGER(1L, int_cont, &lencont); /* fill the content, the content length and the storage class for item4 */ (cont_array_ptr[MyModule_MyType2_SET_item4_INTEGER]).content = int_cont; (cont_array_ptr[MyModule_MyType2_SET_item4_INTEGER]).len = lencont; (cont_array_ptr[MyModule_MyType2_SET_item4_INTEGER]).contstg = allocd; /* * Call the library routine GDSencode, to create one or more GDS structures * that represent a value for MyModule. These GDS structures make a GDS * structure tree. Note that the GDSencode function does *not* create the * BER encoded data. The GDS structure tree contain the information needed to * encode the data, but the actual encoding is a secondary step. This * allows other encoding techniques besides BER to be used. */ Typ = MyModule_MyType1; /* encode MyType1 */ rc = GDSencode(Mod, /* module where type occurs */ &Typ, /* metatable index where type occurs */ cont_array_ptr, /* pointer to Contents Array */ &p1, /* returned GDS structure */ ber, /* type of encoding */ env, /* environment */ NULL /* user defined parameter, * not used in this case */ ); if (rc != ENCODE_MATCH) { /* if the encoding failed */ printf("\nGDSencode return code: %i\n", rc); printf("\nMetatable type index where error occurred: %i\n", Typ); GDSfreegds(p1, env); /* reclaim space for the GDS structure tree */ return(-1); } /* open the output file that will contain the encoded data stream */ EncStream = fopen("stream.out","wb"); if (EncStream == NULL) { /* open file failed */ printf("open output file failed\n"); exit(-1); } /* endif */ /* * Call the library routine, GDSencber, to encode the GDS structure tree * using BER rules. */ rc = GDSencber(&p1, /* the GDS structure tree to be encoded */ 150, /* the length of the output buffer */ &out_buff, /* output buffer */ &EncBytes, /* the number of encoded bytes */ 0, /* definite length form */ env, /* environment */ (void *) EncStream /* user parameter: it will be passed * by GDSencber to the writing user-exit */ ); if (rc != ENCBER_OK) { /* if encoding was unsuccessful */ printf("\nGDSencber return code: %i\n", rc); printf("module name: %s\n", p1->modname); printf("type name: %s\n", p1->name); GDSfreegds(p1, env); /* reclaim space for the GDS structure tree */ return(-1); } /* endif */ printf("\nnumber of encoded bytes: %lu\n", EncBytes); /* open the trace file for encoding gds tree */ trace_enc = fopen("trace1.out","w"); if (trace_enc == NULL) { /* open file failed */ printf("open enc trace file failed\n"); return(-1); } /* endif */ /* * Call the library routine, GDSprintgds, to print the GDS structure tree * in a readable format. */ rc = GDSprintgds(p1, /* ptr to root GDS structure */ 0, /* number of spaces to indent */ 400, /* max content length */ 79, /* number of characters for row */ trace_enc, /* GDS tree trace file */ ber /* type of encoding */ ); if (rc != PRINT_GDS_OK) { /* if the printing failed */ printf("\nGDSprintgds return code: %i\n", rc); GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */ return(-1); } /* endif */ fclose(trace_enc); /* close the trace file */ fclose(EncStream); fopen("stream.out", "rb"); /* reopen the file for reading */ if (EncStream == NULL) { /* open file failed */ printf("\nopen input file failed\n"); return(-1); } /* endif */ /* * Call the library routine, GDSfreegds, to reclaim the storage occupied by * the GDS structures headed by p1 which are marked as allocated. Note * that some GDSs may be marked as static, which prevents them from * being freed. */ GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */ if (out_buff |= NULL) free(out_buff); /* * Call the library routine, GDSdecber, to decode encoded data in the * buffer we just built. The result should be a tree of GDS structures * topped by p1 which matches the original structure created by the * encode library routine. */ alldata = 0; in_buff = &alldata; rc = GDSdecber(&p1, /* pointer to the root of the GDS tree */ 150, /* the length of the input buffer */ &DecBytes, /* number of decoded bytes */ &in_buff, /* data buffered indicator */ env, /* environment */ (void *) EncStream /* user parameter: it will be passed * by GDSdecber to the reading user-exit */ ); if (rc != DECBER_OK) { /* if decoding failed */ printf("\nGDSdecber return code: %i\n", rc); printf("\nnumber of decoded bytes: %u\n", DecBytes); GDSfreegds(p1, env); return(-1); } printf("\nnumber of decoded bytes: %u\n", DecBytes); /* * Call the library routine, GDSAllocateGdsTreeArray to allocate an * array of pointers to GDS structures. This array can be passed to * the GDSdecode routine that filles it with the addresses of the * GDS structures inside the decoded GDS structure tree. Then the * User Application Program can access this array, using as indexes * the symbol names defined in the myasn1.h file, to get directly * the pointers to the corresponding GDS structures. */ rc = GDSallocateGdsTreeArray(Mod, &gds_tree_ptr); if (rc == ALLOCATEGDSTREE_NO_ENOUGH_STORAGE) { printf("no enough storage for gds-tree pointers array\n"); return(-1); } /* * Call the library routine, GDSdecode, to match the GDS structure tree * created by GDSdecber with an ASN.1 type referenced by Mod and Typ. * If successful, the GDS structures will have name information set. */ rc = GDSdecode(Mod, /* module where type occurs */ &Typ, /* Metatable index where type occurs */ &p1, /* root of GDS structure tree */ gds_tree_ptr, /* pointer to the GDS tree pointers array */ env, /* environment */ NULL /* user parms, not used in this case */ ); if (rc != DECODE_MATCH) { /* if decoding didn't go ok */ printf("\nGDSdecode return code: %i\n", rc); printf("Metatable type index where error occurred: %i\n", Typ); printf("module name: %s\n", p1->modname); printf("type name: %s\n", p1->name); GDSfreegds(p1, env); return(-1); } /* endif */ /* open the trace file for decoding gds tree */ trace_dec = fopen("trace2.out","w"); if (trace_dec == NULL) { /* open file failed */ printf("open dec trace file failed\n"); exit(-1); } /* endif */ /* * Call the library routine, GDSprintgds, to print the structure and * content of the decoded GDS. */ rc = GDSprintgds(p1, /* ptr to root GDS structure */ 0, /* number of spaces to indent */ 400, /* max content length */ 79, /* number of characters for row */ trace_dec, /* GDS tree trace file */ ber /* type of encoding */ ); if (rc != PRINT_GDS_OK) { /* if the printing failed */ printf("\nGDSprintgds return code: %i\n", rc); GDSfreegds(p1, env); return(-1); } /* endif */ fclose(trace_dec); /* close the trace file */ /* as example we print the content of item1 only */ printf("item1: %s\n", (gds_tree_ptr[MyModule_MyType1_SEQUENCE_item1_CharacterString])->contents); /* * Call the library routine GDSfreegds to free the GDS structures in * the tree rooted by *p1. */ GDSfreegds(p1, env); /* * Call the library routine GDSfreeGdsTreeArray to free the storage * allocated for the array of GDS structures pointers. */ GDSfreeGdsTreeArray(gds_tree_ptr); /* * Clean up the environment by unloading all modules by calling * GDSunloadmodule for each module in the environment. NOTE: * the GDSunloadmodule function should only be called for modules which * were loaded by the GDSreaddatfile function or which have allocated * storage in the heap like the GDSreaddatfile function. */ for (GDSfirstmodule(&Mod, &dummy, env); Mod != NULL; GDSfirstmodule(&Mod, &dummy, env)) { GDSunloadmodule(Mod, env); } /* endfor */ /* * Call the library routine GDSfreeEnvironment to free the * environment storage */ GDSfreeEnvironment(env); return 0; } /* end main */ /* * User-exit for flushing the output buffer. It writes the content of * the buffer in a file. */ unsigned long mywrite(char *buf, unsigned long buflen, void *usrparms) { FILE *EncStream; EncStream = (FILE *) usrparms; return (unsigned long) (fwrite(buf,sizeof(unsigned char),buflen,EncStream)); } /* * User-exit for loading the input buffer. It reads the content of the * buffer from a file. */ unsigned long myread(char *buf, unsigned long buflen, void *usrparms) { FILE *EncStream; EncStream = (FILE *) usrparms; return (unsigned long) (fread(buf,sizeof(unsigned char),buflen,EncStream)); } ═══ 7. The GDSASN1 Compiler ═══ The role of the GDSASN1 compiler is to ensure the correctness of the abstract syntax and to optionally translates the ASN.1 specification of the data stream syntax in a Metatable and Symbol Table corresponding to the ASN.1 source file. The Metatable and Symbol Table are contained in a .TBL file. The ASN.1 compiler produces an error file too. This file lists errors and warning and informational messages about the ASN.1 compilation. ═══ 7.1. Invoking the Compiler ═══ This section describes how to invoke the GDSASN1 compiler on different systems. ═══ 7.1.1. AIX/6000 Version ═══ The syntax for invoking the ASN.1 compiler from an AIX* command line is: ┌─────────────────────┐  │ >>────── GDSASN1 ─────┬────────────────┬─┴─────>< │ │ └───┤ option ├───┘ ═══ 7.1.2. GDSASN1 - AIX Options ═══ The options may appear in any order. The characters in the option keywords are case insensitive. An option may be specified more than once, in which case the last specification overrides previous specifications. ├───┬─┬─────┬── ? ──────────────────────────────────────┬──┤ │ └─ - ─┘ │ │ │ ├─ source-file ─────────────────────────────────────┤ │ │ ├─ - ─┬─ E ─┬────┬──────────────┬───────────────────┤ │ └─ e ─┘ └─ error-file ─┘ │ │ │ ├─ - ─┬─ T ─┬────── tbl-file ───────────────────────┤ │ └─ t ─┘ │ │ │ ├─ - ─┬─ SCRIPT ─┬──────────────────────────────────┤ │ └─ script ─┘ │ │ │ ├─ - ─┬─ NOSCRIPT ─┬────────────────────────────────┤ │ └─ noscript ─┘ │ │ │ ├─ - ─┬─ GDSD ─┬────────────────────────────────────┤ │ └─ gdsd ─┘ │ │ │ ├─ - ─┬─ NOGDSD ─┬──────────────────────────────────┤ │ └─ nogdsd ─┘ │ │ │ ├─ - ─┬─ W ─┬────── warn-level ─────────────────────┤ │ └─ w ─┘ │ │ │ └─ - ─┬─ D ─┬────┬──────────────┬───────────────────┘ └─ d ─┘ └─ debug-file ─┘ ═══ 7.1.3. OS/2 Version ═══ The syntax for invoking the ASN.1 compiler from an OS/2 command line is: ┌─────────────────────┐  │ >>────── GDSASN1 ─────┬────────────────┬─┴─────>< │ │ └───┤ option ├───┘ ═══ 7.1.4. GDSASN1 - OS/2 Options ═══ The options may appear in any order. The characters in the option keywords are case insensitive. An option may be specified more than once, in which case the last specification overrides previous specifications. ├───┬─┬─────┬── ? ────────────────────────────────────────┬──┤ │ ├─ / ─┤ │ │ └─ - ─┘ │ │ │ ├── source-file ──────────────────────────────────────┤ │ │ ├┬─ / ─┬┬─ E ─┬────┬──────────────┬───────────────────┤ │└─ - ─┘└─ e ─┘ └─ error-file ─┘ │ │ │ ├┬─ / ─┬┬─ T ─┬────── tbl-file ───────────────────────┤ │└─ - ─┘└─ t ─┘ │ │ │ ├┬─ / ─┬┬─ SCRIPT ─┬──────────────────────────────────┤ │└─ - ─┘└─ script ─┘ │ │ │ ├┬─ / ─┬┬─ NOSCRIPT ─┬────────────────────────────────┤ │└─ - ─┘└─ noscript ─┘ │ │ │ ├┬─ / ─┬┬─ GDSD ─┬────────────────────────────────────┤ │└─ - ─┘└─ gdsd ─┘ │ │ │ ├┬─ / ─┬┬─ NOGDSD ─┬──────────────────────────────────┤ │└─ - ─┘└─ nogdsd ─┘ │ │ │ ├┬─ / ─┬┬─ W ─┬────── warn-level ─────────────────────┤ │└─ - ─┘└─ w ─┘ │ │ │ └┬─ / ─┬┬─ D ─┬────┬──────────────┬───────────────────┘ └─ - ─┘└─ d ─┘ └─ debug-file ─┘ ═══ 7.2. GDSASN1 Compiler Input ═══ The input of the GDSASN1 compiler is a text file containing the ASN.1 specification of the data stream structure (for a description of the ASN.1 notation click here). If a source file is not specified, the GDSASN1 compiler reads its input from standard input, which is normally the console. To facilitate use of ASN.1 definitions within IBM Script and BookMaster documents, the compiler provides the SCRIPT option. With the SCRIPT option in effect: o The compiler skips all source lines outside of ASN.1 sections. An ASN.1 section is introduced with a source line of the form .* asn.1 on". The .* must begin in columns one and two, asn.1 and on are separated by one or more spaces and may be uppercase or lowercase. An ASN.1 section is terminated with a source line of the form .* asn.1 off. Note that these two lines appear as comments to the Script or BookMaster processor. A source file can have multiple ASN.1 sections with no importance placed on where the section breaks occur with respect to the ASN.1 definitions. o Within an ASN.1 section, the following symbols are allowed, but not required, in place of their single character equivalents: - &lbrc. or &lbrace. for { - &rbrc. or &rbrace. for } - &lbrk. or &lbracket. for [ - &rbrk. or &rbracket. for ] - &gml. for : - &colon. for : - &period. or &dot. for . - &eq. or &equals. or &eqsym. for = - &percent. for % - &tab. or &rbl. for a space - &us. for _ (underscore) o The above substitutions are made inside character string constants, but are not made within ASN.1 comments. o Within an ASN.1 section, the compiler will ignore any line that begins with a period or a colon in column one. If you absolutely need to begin a line with a period or a colon that is part of an ASN.1 symbol, use &period. or &colon. to avoid having the compiler ignore the line. Note that the above facilities are only in effect when the SCRIPT option is invoked. Otherwise, the source file is assumed to contain only valid ASN.1 statements without script symbols and ASN.1 sections. ═══ 7.3. GDSASN1 Compiler Output ═══ The ouput of the GDSASN1 compiler consists of: o GDSASN1 compiler return codes and messages o Symbol table and Metatable file (.TBL file) o GDSASN1 compiler debugging information ═══ 7.3.1. GDSASN1 Compiler Return Codes and Messages ═══ If the error-file option is not specified, the error output is directed to the standard output file, which is normally the console. The error ouput file is a file containing the errors and warning and informational messages about the ASN.1 compilation. For each message the following information are listed: o The number of line in the source file where the error has been found o The number of column inside the line where there is the item in error o The code of the error and its level of severity o A brief description of the error (Click here for a list of all the messages.). The message severity ranges from 1 to 4: o Level 1 messages are informational in nature o Level 2 messages are warnings that indicate run-time limitations o Level 3 messages are warnings that indicate questionable use of the ASN.1 language o Level 4 messages are errors in the ASN.1 source or internally detected compiler errors ═══ 7.3.2. Symbol Table and Metatable File (.TBL file) ═══ This is a text file in a specific format, which from now will be called TBL format (for a detailed description of the format of .TBL file click here). The .TBL file contains a Metatable and Symbol Table definitions corresponding to the compiled ASN.1 source file. The TBL format is character data that is intended to be portable. In fact, machine independence is gained by only using character forms for all data types, including those for decimal numbers and some special types, such as for object identifier values. In this way the TBL format represents an intermediate form: it is more compact and has more embedded information than the original ASN.1 source, but it is still as machine-independent as is possible. This allows the GDSASN1 Compiler to be hosted on one type of computer to generate Metatable and Symbol Table information for use by the user application on a different system. The translation of .TBL file into a format readable by run-time routines is performed by the GDSTABLE program. The Symbol Table contains the names defined in all the modules of the ASN.1 source. The Metatable represents the syntactic structure of the ASN.1 definitions. In fact the structure of the Metatable is directly related to the ASN.1 statements from which it is derived. A Metatable is produced for each ASN.1 module defined in the source. ═══ 7.3.3. GDSASN1 Compiler Debugging Information ═══ If the -d option is specified, the GDSASN1 compiler produces debugging information consisting of a trace of the operation performed during the parsing process. If a debug-file is not specified, the debugging output is directed to the standard output. ═══ 8. Metatable and Symbol Table Translator ═══ The Metatable and Symbol Table translator (GDSTABLE program) translates the .TBL file (generated by the GDSASN1 Compiler) into two other files, containing the same information as the .TBL file: a .DAT file, a .C file or both. This translation is needed because the .TBL file format is not efficient for the runtime environment. Moreover, this translation provides the bridge between the compilation environment for the ASN.1 syntax and the execution environment of the User Application Program, which must perform encoding and decoding operations per ASN.1 specifications. The .DAT file and .C file contain the same information, structured in the same manner. The difference between .DAT file and .C file consists of their format and of how they are used by the User Application Program. In fact, the UAP can read at runtime the .DAT file, it can include the .C file, or it can be linked together with the compiled .C file. For the details of the .DAT file structure click here ═══ 8.1. Invoking the Translator ═══ This section describes how to invoke the GDSTABLE translator on different systems. ═══ 8.1.1. AIX/6000 Version ═══ The syntax for invoking the Metatable and Symbol Table translator from an AIX command line is: >>─── GDSTABLE ─── tblfile ── datfile ────> >─┬─ / ─┬─┬─ C ─┬── c-file ──────────────> └─ - ─┘ └─ c ─┘ >─┬─ / ─┬─┬─ H ─┬── h-file ──────────────> └─ - ─┘ └─ h ─┘ >─┬─ / ─┬─┬─ E ─┬── error-file ──────────> └─ - ─┘ └─ e ─┘ >─┬─ / ─┬─┬─ S ─┬── test-tool-inp-file───>< └─ - ─┘ └─ s ─┘ ═══ 8.1.2. OS/2 Version ═══ The syntax for invoking the Metatable and Symbol Table translator from an OS/2 command line is: ┌─────────────────────────────────────────┐  │ >>── GDSTABLE ──┬┬─ / ─┬┬─ T ─┬─ tblfile ─────────────┬──┴────>< │└─ - ─┘└─ t ─┘ │ │ │ ├┬─ / ─┬┬─ D ─┬─ datfile ─────────────┤ │└─ - ─┘└─ d ─┘ │ │ │ ├┬─ / ─┬┬─ C ─┬─ c-file ──────────────┤ │└─ - ─┘└─ c ─┘ │ │ │ ├┬─ / ─┬┬─ H ─┬─ h-file ──────────────┤ │└─ - ─┘└─ h ─┘ │ │ │ ├┬─ / ─┬┬─ E ─┬─ error-file ──────────┤ │└─ - ─┘└─ e ─┘ │ │ │ └┬─ / ─┬┬─ S ─┬─ test-tool-inp-file ──┘ └─ - ─┘└─ s ─┘ ═══ 8.2. GDSTABLE Translator Input ═══ The input of the GDSTABLE translator consists of the .TBL file generated by the GDSASN1 compiler. ═══ 8.3. GDSTABLE Translator Output ═══ The output of the GDSTABLE translator consists of: o .DAT file o .C file o .H file o Return codes and messages o Test tool preformatted input file ═══ 8.3.1. .DAT File ═══ The .DAT file is a binary file containing, in a specific format, the Symbol Table and the Metatable defined in the .TBL file. The .DAT file can be read at runtime by the GDSreaddatfile ═══ 8.3.2. .C File ═══ The .C file is a C language source file containing data structure definitions. These data structures implement the Symbol Table and the Metatable defined in the .TBL file. They are used by the runtime routines of the GDSEDLIB library, or they can be used by ad-hoc user-written functions. The generation of the .C file is regulated by the -c option. ═══ 8.3.3. .H File ═══ The .H file is a C language header file containing define preprocessor directives for each ASN.1 type or value defined in the compiled ASN.1 source file. These #defines assign a self-describing symbolic name to each Metatable index corresponding to each ASN.1 statement for which the User Application Program has to do encoding/decoding actions. On the other hand, the runtime GDSEDLIB library has search routines (GDSfindtype and GDSfindval) providing the indexes in the Metatable of the ASN.1 types or values corresponding to the symbolic names passed to them, but this approach is more time consuming than using directly the symbolic names defined in the .H file. Note that the .H file can be included by the User Application Program regardless of whether the Metatable is part of the UAP (.C file) or it is loaded at run time (.DAT. file). The generation of the .H file is regulated by the -h option. ═══ 8.3.4. Return Codes and Messages ═══ Return codes and messages by default are directed to the standard output. Use the -e option to specify a different output file. ═══ 8.3.5. Test Tool Preformatted Input File ═══ Use the option -s to generate a text file useful for testing. This file contains blocks of tags. It must be filled with an editor and passed to the test tool (for a description of the test tool click here). ═══ 9. ASN.1 Syntax ═══ For details of the ASN.1 syntax, including the extensions to the syntax and the features supported by the GDSASN1 compiler, see the General Data Stream Encoder/Decoder User's and Programmer's Guide manual. The ASN.1 is defined by the standard ISO/IEC 8824 Information Processing - Open Systems Interconnection - Specification of Abstract Syntax Notation One (ASN.1) (April 1990). ═══ 10. Encoding Rules ═══ See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the format of the encoded data. ═══ 10.1. Basic Encoding Rules ═══ Basic Encoding Rules defines the format of the encoded data that the GDSencber routine of the GDSEDLIB runtime library returns to the User Application Program after encoding, and that the User Application Program passes to the GDSdecber routine of the GDSEDLIB runtime library for decoding. This format is defined by the standard ISO/IEC 8825 Information Processing - Open Systems Interconnection - Specifications of Abstract Syntax Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1) (April 1990). ═══ 10.2. IBM General Data Stream Definition ═══ This section describes the IBM General Data Stream (GDS), which is used in a variety of ways by SNA products. The basic structural unit in GDS is the structured field, a string of bytes beginning with a length and followed by a GDS identifier (ID), also defined TYPE, that defines the structure of the remainder of the field. However the GDSencgdsd encoding routine and the GDSdecgdsd decoding routine of the GDSEDLIB runtime library support a more general form of the GDS variable, whose LENGTH field and IDENTIFIER field can be 0, 1, 2, 3, or 4 bytes long. ═══ 11. GDSEDLIB Runtime Library ═══ The runtime routines of the GDSEDLIB library are used by the User Application Program to: o Encode and decode the data streams defined with ASN.1 o Convert between transfer syntax and local forms o Format data for printing or displaying o Access the Symbol Table and Metatable The GDSEDLIB runtime routines can be grouped into these categories: o Initialization/Termination o Searching/Accessing o Data Conversion o Encoding/Decoding o Data Formatting ═══ 11.1. Initialization and Termination ═══ GDSaddmodule Adds an ASN.1 module to the list of modules in the runtime environment. GDSallocateContentsArray Allocates an array of structures useful to pass data to encoding functions. GDSallocateContListArray Allocates an array of structures useful to pass data to encoding functions for SET OF and SEQUENCE OF type. GDSallocateGdsTreeArray Allocates an array useful to access the decoded GDS structure tree. GDSfreeContentsArray Frees the contents-array allocated with GDSallocateContentsArray. GDSfreeEnvironment Frees the storage of the environment allocated with GDSinitEnvironment routine. GDSfreegds Frees a GDS structure tree. GDSfreeGdsTreeArray Frees the storage of the array of GDS structures pointers allocated by GDSallocateGdsTreeArray routine. GDSnewgds Creates and initializes a GDS structure tree node. GDSreaddatfile Reads a DAT file into the runtime environment. GDSresolveallimports Resolves the imported symbols in each of the active modules in the runtime environment. GDSresolveimports Resolves the imported symbols for one module. GDSsetUsrDec Sets the user decoding function address. GDSsetUsrEnc Sets the user encoding function address. GDSsetUsrRead Sets the user reading function address. GDSsetUsrWrite Sets the user writing function address. GDSunloadmodule Unloads a module from memory. ═══ 11.2. Searching and Accessing ═══ GDSbasetype Determines the base type of an ASN.1 type. GDSfindmodule Finds a module by name among the active modules. GDSfindtype Finds a type definition in a module given its type name. GDSfindval Finds a value definition in a module given its value name. GDSfindtbl Finds a table definition in a module given its table name. GDSfirstmodule Returns the first module in the list of active modules in the runtime environment. ═══ 11.3. Data Conversion ═══ GDShex2str Converts a binary or hexadecimal string into a printable character string. GDSINTEGERtolong Converts an ASN.1 INTEGER into a long int. GDSlngs2OID Converts an array of longs to an object identifier value. GDSlongtoINTEGER Converts a long int into an ASN.1 INTEGER. GDSOIDtolngs Converts an obect identifier to an array of long integers. GDSstr2hex Converts a printable character string into a binary or hexadecimal string. ═══ 11.4. Encoding/Decoding ═══ GDSdecber Decodes a BER-formatted data stream into a GDS structure tree. GDSdecgdsd Decodes a GDSD-formatted data stream into a GDS structure tree, and decodes the GDS structure tree according to the ASN.1 type defining the the data stream syntax. GDSdecode Decodes a GDS structure tree according to an ASN.1 type. GDSencber Encodes a BER-formatted data stream from a GDS structure tree. GDSencgdsd Encodes a GDSD-formatted data stream from a GDS structure tree. GDSencode Encodes a GDS structure tree according to an ASN.1 type. ═══ 11.5. Formatting ═══ GDSprintgds Prints a formatted version of a GDS structure tree. GDSPrintUnresolvedImports Prints unresolved imported symbols. GDStypestr Converts an ASN.1 type to a printable string. ═══ 11.6. Using the GDSEDLIB Library ═══ This section describes how the User Aplication Program can use the GDSEDLIB library. ═══ 11.6.1. AIX/6000 Version ═══ The GDSEDLIB library consists of a shared library (GDSEDLIB.O). To use this shared library, the User Application Program has to include the following header files: o GDSTYPES.H, containing the type definitions used by the routines of the GDSEDLIB library. o GDSPROTO.H, containing the prototypes of the routines of the GDSEDLIB library. o GDSRCODS.H, containing the return codes of the routines of the GDSEDLIB library. Then the UAP must be compiled and linked passing the information about the shared library (see your AIX General Programming Concepts manual to see how it can be done). ═══ 11.6.2. OS/2 Version ═══ The GDSEDLIB library consists of a dynamic link library (GDSEDLIB.DLL). To use this DLL the User Application Program has to include the following header files: o GDSTYPES.H, containing the types definitions used by the routines of the GDSEDLIB library. o GDSPROTO.H, containing the prototypes of the routines of the GDSEDLIB library. o GDSRCODS.H, containing the Return Codes of the routines of the GDSEDLIB library. Then, in the linking phase, there are two ways to communicate to the linker that a DLL is used: o Pass the GDSEDLIB.LIB to the linker (see your C Compiler user's guide to see how it can be done). o Pass the GDSEDLIB.DEF to the linker (see your C Compiler user's guide to see how it can be done). Moreover the GDSEDLIB.DLL must be in a directory listed in LIBPATH environment variable. ═══ 11.7. How the Encoding\Decoding Routines Work ═══ In order to use correctly the routines of the GDSEDLIB library the user has to understand the main steps performed by those during the encoding and decoding processes. ═══ 11.7.1. Encoding Process ═══ The encoding process is performed in two steps. 1. Invoke the GDSencode function to construct the GDS structure tree. The GDS structure tree is an internal representation of the structure of the encoded data stream. Each node of this tree is a GDS structure. The GDSencode allocates a GDS structure for each ASN.1 type defined in the Metatable. The UAP passes the content data that must be encoded. The content data can be passed in two different ways: o With an encoding user exit that the GDSencode routine calls each time it encodes a primitive ASN.1 type. o Setting a specific contents-array before calling the GDSencode routine. 2. The GDSencber or the GDSencgdsd routine must be invoked, depending on the type of transfer syntax (BER or GDSD) used. These two routines read the GDS structure tree and produce the encoded data stream in an output buffer. ═══ 11.7.2. Decoding Process ═══ The transfer syntaxes defined by BER and IBM GDSD are quite different. The BER defines a specific tag value for each built-in ASN.1 type. So the BER-encoded data contains all the information related to the structure of the data itself. It means that in the decoding phase it is possible to construct the GDS structure tree corresponding to the decoded data stream without knowing the corresponding ASN.1 specifications (the Metatable). In the case of GDSD this is not possible. In fact the GDSD does not define specific tag values for each ASN.1 built-in type. All the IDENTIFIERs of the GDS variables must be explicitly specified, and the built-in types defining complex structure (SET, SET OF, SEQUENCE, SEQUENCE OF) do not have corresponding implicit tag values. This means that for decoding a GDSD-formatted data stream it needs to know the data stream structure; that is, it needs the Metatable. Because of this the decoding process consists of two steps (GDSdecber and GDSdecode routines) in case of BER, and one step (GDSdecgdsd routine) in case of GDSD. ═══ 11.7.3. GDS Structure Tree ═══ The following is the C declaration of the GDS structure: struct gds { enum tagclass cls; unsigned long id; enum frm form; long loc; long log; int basetype; char *modname; char *name; char *sop; char *contents; struct gds *next; struct gds *contains; struct gds *parent; enum stg gdsstg; enum stg contstg; enum setstat sstat; unsigned long id_seg_len; int (*usrcontent) (char **, long *, enum lastflag *) struct segment *seg_list; }; To understand the meanings of the GDS structure fields consider the GDS structure tree generated after the encoding of the following ASN.1 specifications: MyModule DEFINITIONS IMPLICIT TAGS ::= BEGIN MyType1 ::= SEQUENCE{ item1 PrintableString, item2 [2] IMPLICIT MyType2 } MyType2 ::= SET{ item3 OCTET STRING, item4 INTEGER } END The figure GDS structure tree shows the corresponding GDS structure tree. GDS structure tree The GDS structure fields have the following meanings: o cls is the tag class of the type corresponding to this GDS structure. The tag class is UNIVERSAL if the type is not tagged. Otherwise, it is one of the GDSD or BER tag classes. In our example the GDS structures: MyType1, item1, item3, and item4 have the tag class UNIVERSAL, the GDS structure item2 has tag class CONTEXT-SPECIFIC. o id is the IDENTIFIER value of the type corresponding to this GDS structure. If the type is not tagged, this value is the one defined by the ISO/IEC 8824 standard. In this case the IDENTIFIER value is encoded only by BER encoding and ignored by GDSD encoding. If the type is tagged, the IDENTIFIER value is the tag number. In the example, the GDS structure MyType1, item1, item2, item3, and item4 have, respectively, IDENTIFIER value 16, 19, 2, 4, and 2. o form indicates the form (primitive or constructed) of the type corresponding to this GDS structure. Primitive form means that this type does not contain other subtypes; that is, the GDS structure contains pointer is NULL. Constructor form means that this type contains other subtypes (for example, SET and SEQUENCE are always encoded in constructed form), that is the GDS structure contains pointer is the address of the root of a GDS structure subtree. In the example, the GDS structure MyType1 and item2 have constructed form, the others have primitive form. o loc is the length of contents field. o log is the length of the GDS structure; that is, the length of the contained GDS structure subtree (if there is one) or the length of contents (if there is one) plus the length of IDENTIFIER and LENGTH field. o basetype indicates the base type of this GDS structure. The base type is one of the ASN.1 built-in type. In the example the GDS structure MyType1, item1, item2, item3, and item4 have, respectively, the base type SEQUENCE, PrintableString, SET, OCTET STRING and INTEGER. o modname is the name of the ASN.1 module that contains the definitions of the type corresponding to this GDS structure. In the example, all GDS structures have the same module name: MyModule. o name is the name of the type corresponding to this GDS structure. o sop is a pointer inside the input/output buffer containing the data stream. It points to the first byte of the encoded data for the type corresponding to this GDS structure. This pointer is significant if: - After encoding, all the encoded data fits in the output buffer (that is the buffer writing user exit has been called just one time, click here for details) - After decoding, all the read data fits in the input buffer (that is, the buffer reading user exit has been called just one time, click here for details) o contents is the pointer to the content data, significant if the form is primitive. o next is the pointer to the next sibling GDS structure. o contains is the pointer to the GDS structure subtree contained in this GDS structure, significant if the form of the type is constructed. o parent is the pointer to the parent GDS structure. o gdsstg indicates the storage class of the GDS structure, that is if the structure has been allocated at runtime or statically. The encoding and decoding routines of the GDSEDLIB library always allocate dynamically the GDS structures, but an encoding user exit of some User Application Programs could pass to the GDSencode routine a statically allocated GDS structure. This information is necessary when the GDS structure tree storage is freed by the GDSfreegds routine. o contstg indicates the storage class of the contents data; that is, if the buffer pointed to by contents has been allocated at run time or statically. This information is necessary when the GDS structure tree storage is freed by the GDSfreegds routine. o sstat is used by GDSdecode routine to flag the matched GDS structures inside a SET type. It is not significant from the User Application Program point of view. o id_seg_len is used by GDSencgdsd routine to find out the IDENTIFIER length or the segment length. It is not significant from the User Application Program point of view. o int (*usrcontent) (char **, long *, enum lastflag *) is the pointer to a user exit called by the GDSencgdsd and GDSencber routines if the contents field, of the GDS structure with primitive form that is being encoded, is NULL. The user exit name must be passed to the GDSencode by the User Application Program. In this way it is possible to avoid the content data being duplicated in the storage: in the GDS structure tree and in the output buffer. The content user exit must return in the order: the pointer to the data buffer, the length of the buffer, and an indication (YES or NO) if it is the last piece of data or not. For details on data passing to GDSencode click here. o seg_list is a pointer to a chain of segments. It is filled by the GDSdecgdsd routine if the User Application Program does not use a decoding user exit and a segmented data stream has been decoded. Each segment in the chain corresponds to a decoded segment. For details on segmentation click here. ═══ 11.7.4. Segmentation ═══ There are two segmentation algorithms supported by GDSencgdsd and GDSdecgdsd routines: LL algorithm With the LL technique, the high-order bit of a 2-bytes long field (LL) is set on, if the segment is not the last segment. With this technique only the first segment can contain two or three bytes of the IDENTIFIER field, the following segments contain only the LL bytes. LL Segments Encoding The encoding logic is to always generate a segment prefix for the GDSSEGLL tagged types. The segment prefix consists of 2 bytes of the LENGTH field (LL), optionally followed by 2 or 3 bytes of the IDENTIFIER field (ID). When a segment has been encoded, its length equal to the specified maximum segment length, another segment prefix is generated, and reinitialized to begin the next segment. Finally, when GDSencgdsd processes the last piece of data, the not-last bit in the LL field is turned off. LL Segments Decoding The decoding logic consists of discarding the segments prefix before decoding the segment content. If the segmented type (the GDSSEGLL tagged type) is a primitive type, a type with content data, the segment content data can be passed to the User Application Program in two different ways: o Using the decoding user exit, which is called by the GDSdecgdsd routine each time a new segment has been decoded. o Using the segment chain, which the GDSdecgdsd routine generates during the decoding of the segmented content data, and that is pointed by the seg_list field of the GDS structure corresponding to the segmented type. Each element of the segment chain is a segment structure. The C declaration of the segment structure is the following: struct segment { unsigned long seg_len; /* length of the segment */ char *seg_content; /* segment content data */ struct segment *next_seg; /* pointer to the next segment. * NULL if it is the last */ }; LLIDFISS algorithm With the LLIDFISS technique, the high-order bit of the F byte is set on if the ISS extension follows, and the third bit, from the left, of the I byte indicates not-last if set (1) or last if reset (0). The SS two bytes contains the segment sequence number. With the LLIDFISS technique all the segments contain the IDFISS bytes. LLIDFISS Segments Encoding The encoding logic is to always generate a segment prefix for the GDSSEGISS tagged types. The segment prefix consists of two bytes of the LENGTH field (LL), followed by three bytes of the IDENTIFIER and F fields (IDF), optionally followed by other three bytes of the ISS field (in this case the high-order bit of F is on). When a segment has been encoded, i.e. its length is equal to the specified maximum segment length, another segment prefix is generated, and reinitialized to begin the next segment. Finally, when GDSencgdsd processes the last piece of data, the "not-last" bit in the I field is turned off. LLIDFISS Segments Decoding The decode processing is essentially the inverse of the encoding logic with one exception. That is, the LLIDF can appear without the ISS following. That is, some User Application Program cannot use segmentation even though it is permitted. In this case GDSdecgdsd discards the LLIDF but saves LL-5 as length of the type. Except this particular case the process is equal to one of LL segmentation. Note: It is illegal to have more than one level of segmentation at a time. That is, there can be no GDSSEGISS or GDSSEGLL tagged type that is subordinate to another GDSSEGISS or GDSSEGLL tagged type. Furthermore, a GDSSEGISS or GDSSEGLL tagged type cannot occur as a component of any other type with a specified length (types that are tagged with GDSLT, GDSTL, GDSFLEN, GDSLENGTH, GDSUNKNLT (with specified ID)). Note: When a .primitive type is segmented (tagged with GDSSEGLL or GDSSEGISS), it is possible to postpone the passing of the content data at the second step of the encoding process (the step performed by the GDSencgdsd routine) and to pass the content data in piececes. This operation can be realized using a content user exit. Moreover, because the segmentation is useful also when the length of content data is not known before encoding it, it is possible, if content user exit is used, to set the content length field (loc) of the GDS structure to undefined length value (that is: -1). ═══ 11.8. GDSEDLIB Routines ═══ The GDSEDLIB runtime library routines are described in the following sections. For each routine the following is specified: o The syntax of the function o The input and output parameters o The results of the function o A description of the function ═══ 11.8.1. GDSaddmodule ═══ int GDSaddmodule(struct void * module_ptr, void *environment) module_ptr Address of the module definition to be added to the list of active modules in the runtime environment. environment Address of the runtime environment allocated for the UAP. Results ADDMODULE_OK The module was successfully added. ADDMODULE_DUP_MODULE Another module with the same name already exists in the list of active modules in the runtime environment. Purpose The GDSaddmodule routine is used to add an ASN.1 module to the list of active modules in the runtime environment. It does not resolve external references. ═══ 11.8.2. GDSallocateContentsArray ═══ int GDSallocateContentsArray(void *module_ptr, struct contents_str **content_array_ptr); module_ptr Address of the module definition for which the contents-array is allocated. content_array_ptr Address of the allocated contents-array. Results ALLOCATECONT_OK The contents-array was successfully allocated. ALLOCATECONT_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. ALLOCATECONT_INVALID_MODULE The module is invalid. Purpose The GDSallocateContentsArray routine is used to allocate a contents-array for the module. A contents-array is an array where each entry is a structure so declared: struct contents_str { char *content; /* content data */ int (*usrcontent) (char **, long *, enum lastflag *); /* content user exit */ struct content_str *contlist; /* list of contents, used for SET OF * and SEQUENCE OF types */ enum stg contstg; /* storage class */ long len; /* content length or number of * contents structure in contlist */ }; The contents-array must be used if the encoding user exit is not used. The User Application Program can use the contents-array to pass the content data to the GDSencode routine and to do some encoding decisions. There is a one-to-one correspondence between each entry of the array and each metatoken in the Metatable. The User Application Program can index the contents-array entries using the symbol names defined in the .H file generated by the GDSTABLE translator. If the UAP wants to encode a constructed type that is an OPTIONAL or DEFAULT component of a constructed parent type, it has to set the content field with a not NULL value in order to inform the GDSencode routine that the specific component must be encoded. The same operation must be done if the OPTIONAL or DEFAULT component type is a NULL type. In both cases the value in the content field is only checked by GDSencode routine; it is not used at all. The contlist field must be filled in if the contents-array is used to pass the content data for SET OF or SEQUENCE OF elements. In this case the User Application Program has to: o Allocate a contlist-array (calling the GDSAllocateContListArray) o Fill the contlist-array with the content data. Each element of the contlist-array corresponds to an occurrence of the SET OF or SEQUENCE OF element o Fill the contlist field with the pointer to the contlist-array o Fill the len field with the number of occurrences of the SET OF or SEQUENCE OF elements. For example, consider the following ASN.1 specification: MyModule DEFINITIONS IMPLICIT TAGS ::= BEGIN Mytype ::= SEQUENCE{ item1 PrintableString, item2 SEQUENCE OF PrintableString, item3 Item3 OPTIONAL } Item3 ::= SET{ item4 PrintableString, item5 PrintableString } END The .H file generated by the GDSTABLE translator contains the following macro definitions: #define MyModule_Mytype_SEQUENCE_item1_CharacterString #define MyModule_Mytype_SEQUENCE_item2_SEQUENCE_OF_ #define MyModule_Mytype_SEQUENCE_item2_SEQUENCE_OF_CharacterString #define MyModule_Item3_SET_item4_CharacterString #define MyModule_Item3_SET_item5_CharacterString The User Application Program can use these symbol names to index the contents-array. If cont_array_ptr is the contents-array pointer (allocated with GDSAllocateContentsArray routine) and contlist_array_ptr is the contlist-array pointer (allocated with GDSAllocateContListArray routine): /* fill the content and the content length for item1 */ (cont_array_ptr[MyModule_Mytype_SEQUENCE_item1_CharacterString]).content = "item1"; (cont_array_ptr[MyModule_Mytype_SEQUENCE_item1_CharacterString]).len = 5; /* we want to encode 2 occurrences of PrintableString of item2 */ (cont_array_ptr[MyModule_Mytype_SEQUENCE_item2_SEQUENCE_OF]).len = 2; /* fill the contlist-array */ (contlist_array_ptr[0]).content = "occurrence1 of item2 element"; (contlist_array_ptr[0]).len = 27; (contlist_array_ptr[1]).content = "occurrence2 of item2 element"; (contlist_array_ptr[1]).len = 27; /* fill the contlist field for item2*/ (cont_array_ptr[MyModule_Mytype_SEQUENCE_item2_SEQUENCE_OF_CharacterString]) .contlist = contlist_array_ptr; /* inform the encoder that the OPTIONAL item3 field must be encoded */ (cont_array_ptr[MyModule_Item3_SET]).content = "dummy"; /* pass the content data of the Item3 elements */ (cont_array_ptr[MyModule_Item3_SET_item4_CharacterString]).content = "item4"; (cont_array_ptr[MyModule_Item3_SET_item4_CharacterString]).len = 5; (cont_array_ptr[MyModule_Item3_SET_item5_CharacterString]).content = "item5"; (cont_array_ptr[MyModule_Item3_SET_item5_CharacterString]).len = 5; Note: This method of passing the content data to the GDSencode routine has the following limits: o You cannot encode OCTET STRING and character string types in constructed form as BER allows. o You cannot encode nesting of SET OF and SEQUENCE OF (SET OF or SEQUENCE OF types nested inside SET OF or SEQUENCE OF types). o If the same type is referred to more than one time, the contents-array can be used only if each referring type is encoded separately, filling the contents array before each invocation of the GDSencode routine. In the listed preceding example the encoding user exit can be used. Note: When an ANY or ANY DEFINED BY type must be encoded, and the contents-array mechanism is used for passing the content data, the Metatable index of the actual type must be passed in the len field of the contents-array element corresponding to the ANY or ANY DEFINED BY type. ═══ 11.8.3. GDSallocateContListArray ═══ int GDSallocateContListArray(long num_of_items, struct content_str **cont_list_ptr); num_of_items Number of occurrences of the elements inside the SET OF or SEQUENCE OF type. cont_list_ptr Address of the allocated contlist-array. Results ALLOCATECONTLIST_OK The array was successfully allocated. ALLOCATECONTLIST_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. Purpose The GDSallocateContListsArray routine is used to allocate a contlist-array to pass the content data of occurrences of SET OF or SEQUENCE OF elements (click here for an example). A contlist-array is an array where each entry is a structure so declared: struct content_str { char *content; /* content data */ int (*usrcontent) (char **, long *, enum lastflag *); /* content user exit */ enum stg contstg; /* storage class */ long len; /* content length */ }; ═══ 11.8.4. GDSallocateGdsTreeArray ═══ int GDSallocateGdsTreeArray(void *module_ptr, struct gds ***gds_ptr); module_ptr Address of the module definition for which the array of pointers to GDS structures is allocated. gds_ptr The pointer to the array of GDS structures pointers. Results ALLOCATEGDSTREE_OK The array was successfully allocated. ALLOCATEGDSTREE_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. ALLOCATEGDSTREE_INVALID_MODULE The module is invalid. Purpose The GDSallocateGdsTreeArray routine is used to allocate an array of pointers to the GDS structures inside the tree. This array must be used if the decoding user exit is not used. It is filled in by the GDSdecode routine (in case of BER) or by GDSdecgdsd routine (in case of GDSD) with pointers to the GDS structures inside the decoded GDS tree. There is a one-to-one correspondence between each entry of the array and each metatoken in the Metatable. The User Application Program can index the contents-array entries using the symbol names defined in the .H file generated by the GDSTABLE translator. In this way the User Application Program can address directly the GDS structures of the decoded types. Note: This method of accessing the GDS structures and its data inside the tree has the following limits: o It can be used if each type is referred to only one time in the ASN.1 specification. In fact, if it is referred to more than one time, the corresponding entry in the array of pointers to GDS structure will address the GDS structure corresponding to the last reference. o If the ASN.1 specification contains SEQUENCE OF or SET OF types, the entries of the array, corresponding to the elements of these types, will point to the last occurrences. ═══ 11.8.5. GDSbasetype ═══ int GDSbasetype(void **module_ptr, unsigned short *table_index, enum basetypes *base_type); module_ptr Address of a pointer to a module structure. As an input parameter, this points to the module containing the type to be resolved. As an output pointer, it is updated to the module containing the base type. table_index Address of a Metatable index. As an input parameter, it refers to the type to be resolved. As an output parameter, it is updated to refer to the base type specification in the Metatable. base_type The base type of the given type. It is set by this routine. Results BASETYPE_OK The base type was successfully found. BASETYPE_WRONG_TOKEN In searching for the base type, a metatoken was encountered that should not have been there, indicating a structural problem with the Metatable. BASETYPE_UNRESOLVED_EXTERN_REF In searching for the base type, an unresolved external reference was encountered. Purpose The GDSbasetype routine determines the base type of a given type according to these rules: o base(tagged type) = base(type being tagged) o base(typereference) = base(referenced type) o base(selection type) = base(choice alternative selected) o base(something else) = something else ═══ 11.8.6. GDSdecber ═══ int GDSdecber(struct gds **gds_tree_ptr, long buflen, long octetsnum, char **alldata, void *environment, void *usrparms); gds_tree_ptr Address of a pointer to the GDS structure tree created by decoding the data stream in the buffer; the pointer is set by this routine. buflen The length of the input buffer; it must be longer than 150 bytes. octetsnum The number of the decoded octets; the parameter is set by this routine. alldata As input parameter it contains a flag indicating if the whole data stream will be loaded in the buffer, significant only if the User Application Program has to print the generated GDS structure tree. 0 means that the data stream will be passed by the reading user exit in pieces; 1 means that the whole data stream will be passed by the reading user exit in one time. As output parameter, if the input value is 1, it contains the pointer to the input buffer containing the whole data stream, if the input value is 0, it contains NULL. environment Address of the runtime environment allocated for the UAP. usrparms Address of a user-defined parameter which is passed to the reading user exit routine during the decoding process. Results DECBER_OK The decoding process was successful. DECBER_SYNTAX_ERROR A syntax error was encountered in the buffer. DECBER_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. DECBER_BUFFER_EMPTY The input buffer is empty. Probably the data stream is not complete. DECBER_BUFFER_TOO_SMALL The input buffer is too small. It must be at least 150 bytes long. Purpose The GDSdecber routine allocates an input buffer with the length specified by the buflen Then it calls the reading user exit routine set by the GDSsetUsrRead routine, passing to it the pointer to the buffer and the length. The reading user exit routine can load in the buffer the whole data stream (in this case the User Application Program should set the alldata parameter on) or a part of it. Then the GDSdecber routine decodes the BER-formatted data contained in the buffer, calling the reading user exit each time all the data in the buffer has been decoded, but the end of the data stream is not reached. The result is a GDS structure tree, a pointer to which is set in gds_tree_ptr. This GDS structure tree cannot be read by the User Application Program, because, even if it contains the whole decoded data stream and reflects its structure, the names of the ASN.1 types and their base types are still missing. The GDSdecode routine must be called in order to match the GDS structure tree with the ASN.1 specifications defined in the Metatable. The usrparms is a parameter passed to the reading user exit. It is a user-defined parameter whose contents are not examined by the GDSdecber routine. The User Application Program can use this to pass local parameters to the reading user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. Note: If the reading user exit routine loads the whole data stream in the input buffer, the GDSdecber routine does not free the storage allocated for the input buffer because it could be used by the GDSprintgds routine. It is responsibility of the UAP to free this storage. ═══ 11.8.7. GDSdecgdsd ═══ int GDSdecgdsd(struct gds **gds_tree_ptr, long buflen, long bytesnum, void *module_ptr, unsigned sort *metaindex, struct gds **gds_ptr, struct errdata *err_data void *environment, void *decusrparms, void *usrparms); gds_tree_ptr Address of a pointer to the GDS tree created by decoding the data stream in the buffer; the pointer is set by this routine. buflen The length of the input buffer; it must be longer than 300 bytes. bytesnum The number of the decoded bytes; the parameter is set by this routine. module_ptr Address of the definition structure of the module containing the ASN.1 type to be decoded. metaindex Metatable index for the ASN.1 type to be decoded. IF an error occurs, it contains the index of the type where the error occurred. gds_ptr Pointer to the array of pointers to the GDS structures inside the tree. If decoding user exit is used it must be NULL. err_data If an error occurred this parameter contains the following information: o A pointer to the bytes of the item in error o The length (max 4) of the item in error environment Address of the runtime environment allocated for the UAP. decusrparms Address of a user-defined parameter that is passed to the decoding user exit routine during the decoding process. usrparms Address of a user-defined parameter that is passed to the reading user exit routine during the decoding process. Results DECGDSD_NO_MATCH The decoded type does not match the decoded data. DECGDSD_MATCH The decoded type matches the decoded data. DECGDSD_SYNTAX_ERROR A syntax error was encountered in the data. DECGDSD_INTERNAL_ERROR An internal programming error occurred. Probably something is wrong in the Metatable. DECGDSD_UNRESOLVED_REFERENCE An unresolved external reference was encountered. DECGDSD_BUFFER_EMPTY Other data must be decoded but the reading user exit does not load other data in the buffer. DECGDSD_INVALID_ID The decoded IDENTIFIER value does not match the correct value. DECGDSD_INVALID_UNIQUE_ITEM The decoded unique item value does not match the correct value. DECGDSD_INVALID_LENGTH The length of decoded data does not match the correct value. DECGDSD_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. DECGDSD_INVALID_SEG_ID_PREFIX The decoded LL segment prefix does not match the correct value. DECGDSD_INVALID_SEG_SEQ_NUM The decoded segment sequence number is not correct. DECGDSD_INVALID_SEG_IDF_PREFIX The decoded LLIDFISS segment prefix does not match the correct value. DECGDSD_LAST_SEG_BEFORE_EOD Content data are segmentated and the last segment indicator indicates that this is the last segment, but not all the content data have been decoded. DECGDSD_MISSING_MANDATORY_ELEMENT A mandatory element of SET or SEQUENCE type is missing. DECGDSD_BUFFER_TOO_SMALL The input buffer is too small. It must be at least 300 bytes long. DECGDSD_USR_DEC_FUN_FAILED The decoding user exit failed. DECGDSD_SUBTYPE_CONSTRNTS_NO_MATCH Decoded content data does not match a subtype constraint Purpose The GDSdecgdsd routine allocates an input buffer with the length specified by the buflen Then it calls the reading user exit routine set by the GDSsetUsrRead routine, passing to it the pointer to the buffer and the length. This routine loads in the buffer the whole data stream or a part of it. Then the GDSdecgdsd routine decodes the IBM GDSD-formatted data contained in the buffer, calling the reading user exit each time all the data in the buffer is decoded, but the end of the data stream is not reached. Each time a type has been decoded, the corresponding GDS structure is added to the GDS structure tree and, if the array of GDS structures pointers is used, the entry corresponding to the type is filled with the pointer to the GDS structure. When a primitive type is decoded, and if the decoding user exit is used, the decoding user exit is called passing to it: o The Metatable index of the decoded type o The pointer to the GDS structure corresponding to the type o The content data o The length of content data The decoding user exit is called also when a type definition is decoded. That permits the UAP to make various decoding decisions (for example, changing the current decoding user exit) when a new occurrence of the specific type is decoded. After the specific type has been decoded, the current decoding user exit is restored. At the end of the decoding process, the pointer to the root of the GDS structure tree is returned in the gds_tree_ptr parameter. If segmentation is used, the GDSdecgdsd routine discards the segment header bytes (LLID or LLIDFSS) without allocating any GDS structure for the segments (for the segmentation algorithms click here). The decusrparms is a parameter passed to the decoding user exit. It is a user-defined parameter whose contents are not examined by the GDSdecgdsd routine. User Application Program can use this to pass local parameters to the decoding user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. The decusrparms and usrparms parameters are passed to the decoding user exit. It is a user defined parameter whose contents are not examined by the GDSdecgdsd routine. The User Application Program can use this routine to pass local parameters to the decoding user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. ═══ 11.8.8. GDSdecode ═══ int GDSdecode(void *module_ptr, unsigned short *metaindex, struct gds **gds_tree_ptr, struct gds **gds_ptr, void *environment, void *usrparms); module_ptr Address of the definition structure of the module that contains the ASN.1 type to be decoded. metaindex Metatable index for the ASN.1 type to be decoded. If an error occurs, it contains the index of the type where the error occurred. gds_tree_ptr Address of the root of the GDS structure tree that must be matched with the ASN.1 type. If an error occurs, this parameter contains the pointer to the GDS structure where the error has been found. gds_ptr Pointer to the array of pointers to the GDS structures inside the tree. If the decoding user exit is used, it must be NULL. environment Address of the runtime environment allocated for the UAP. usrparms Address of a user-defined parameter which is passed to the decoding user exit routine during the decoding process. Results DECODE_MATCH The GDS structure tree matches the ASN.1 type. DECODE_NO_MATCH The GDS structure tree does not match the ASN.1 type. DECODE_SYNTAX_ERROR The GDS structure tree does not match the ASN.1 type and furthermore, some syntax error has been detected, such as a constructed INTEGER value. DECODE_INTERNAL_ERROR An internal programming error occurred. Probably something is wrong in the Metatable. DECODE_UNRESOLVED_REFERENCE An unresolved external reference was encountered. DECODE_USR_DEC_FUN_FAILED The decoding user exit failed. DECODE_SUBTYPE_CONSTRNTS_NO_MATCH Decoded content data do not match a subtype constraint Purpose The GDSdecode routine attempts to match an ASN.1 type with a value. The value is represented by a GDS structure tree, and the type is represented by a reference into the Metatable. The GDS structure tree is updated to indicate the features of the matched type, e.g. the name and base type. Each time a type has been matched, the corresponding GDS structure is updated and, if the array of GDS structures pointers is used, the entry corresponding to the type is filled with the pointer to the GDS structure. When a primitive type is decoded, and if the decoding user exit is used, the decoding user exit is called passing to it: o The Metatable index of the decoded type o The pointer to the GDS structure corresponding to the type o The content data o The length of content data Note: The pointer to the content data, passed to the decoding user exit, is NULL if the type is a PrintableString or an OCTET STRING and it is encoded in constructed form. The decoding user exit is called also when: o A type definition is decoded. That permits the UAP to make various decoding decisions (for example, changing the current decoding user exit) when a new occurrence of the specific type is decoded. After the specific type has been decoded, the current decoding user exit is restored. o An ANY (or ANY DEFINED TYPE) is decoded. That permits the UAP to call recursively the GDSdecode routine on the GDS structure subtree pointed by the passed GDS structure pointer, in order to match this subtree with the actual encoded type. The GDSdecode routine must be called after the GDSdecber routine, in order to fill the GDS structure tree with all the missing information. In the case of GDSD, the GDSdecgdsd The decusrparms is a parameter passed to the decoding user exit. It is a user-defined parameter whose contents are not examined by the GDSdecode routine. The User Application Program can use this routine to pass local parameters to the decoding user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. ═══ 11.8.9. GDSencber ═══ int GDSencber(struct gds **gds_tree_ptr, unsigned long buflen, unsigned char **out_buffer, unsigned long *bytesnum, int indef_length, void *environment, void *usrparms); gds_tree_ptr As input parameter it contains the pointer to the root of the GDS structure tree. If an error occurs, it is used as an output parameter to contain the pointer to the GDS structure where the error occurred. buflen The length of the output buffer. It must be longer than 150 bytes. out_buffer If the output buffer can contain the whole encoded data stream, this parameter contains the pointer to the buffer. Otherwise, if the output buffer length is lower than the encoded data stream length, this parameter contains NULL. bytesnum The number of the encoded bytes; the parameter is set by this routine. indef_length A flag indicating the length form: 0 for definite length form, 1 for indefinite length form. environment Address of the runtime environment allocated for the UAP. usrparms Address of a user-defined parameter that is passed to the writing user exit routine during the encoding process. Results ENCBER_OK The encoding process was successful. ENCBER_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. ENCBER_GDSUSRWRT_FAILED The writing user exit failed. ENCBER_USER_EXIT_FAILED The content user exit failed ENCBER_PRIM_TYPE_CONTENT_MISSING No content data or incomplete content data has been passed for the primitive type. ENCBER_INTERNAL_ERROR An internal programming error occurred. ENCBER_UNDEFLEN_NOT_PERMITTED Indefinite length used for primitive type. ENCBER_BUFFER_TOO_SMALL The output buffer is too small. It must be at least 150 bytes long. Purpose The GDSencber routine allocates an output buffer with the length specified by the buflen Then it starts to encode in the output buffer the BER-encoded data stream from the GDS structure tree. When the output buffer is full, it calls the writing user exit routine set by GDSsetUsrWrite routine, passing to it the pointer to the buffer and the length. The writing user exit routine has to flush the buffer containing the BER-encoded data. It is called by the GDSencber routine each time the buffer is full, but not all the GDS structure tree has been encoded. If the passing of the content data has been postponed, for example, if a GDS structure with the usrcontent field not NULL is found (for details on the postponing of the content data passing during encoding click here), the GDSencber routine calls the content user exit pointed by the specific field of the GDS structure. This content user exit has to return a pointer to the data buffer, the length of the buffer and an indication if the data are the last or not. The GDSencber makes a call to this user exit until the last indicator is on, or the length of the whole content data (passed by the content user exit) is equal to the specified content length (field loc of the GDS structure). An error is produced if the last indicator is on before the content data has been passed. The usrparms is a parameter passed to the writing user exit. It is a user-defined parameter whose contents are not examined by the GDSencber routine. User Application Program can use this to pass local parameters to the writing user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. Note: If the whole encoded data stream fits in the output buffer, the GDSencber routine fills the sop fields of the encoded GDS structures with pointers inside the buffer. Note: If the output buffer can contain the whole encoded data stream, the GDSencber routine does not free the storage allocated for the buffer because it could be used by the GDSprintgds routine. It is responsibility of the UAP to free this storage. ═══ 11.8.10. GDSencgdsd ═══ int GDSencgdsd(struct gds **gds_tree_ptr, unsigned long buflen, unsigned long *bytesnum, useLLIDFISS use_segmentation, void *environment, void *usrparms); gds_tree_ptr As an input parameter it contains the pointer to the root of the GDS structure tree. If an error occurs, it is used as output parameter to contain the pointer to the GDS structure where the error occurred. buflen The length of the output buffer. bytesnum The number of the encoded bytes; the parameter is set by this routine. use_segmentation A flag indicating if the User Application Program wants to use the LLIDFISS segmentation or not (use or nouse). environment Address of the runtime environment allocated for the UAP. usrparms Address of a user-defined parameter which is passed to the writing user exit routine during the encoding process. Results ENCGDSD_OK The encoding process was successful. ENCGDSD_INTERNAL_ERROR An internal programming error occurred. Probably something is wrong in the GDS structure tree. ENCGDSD_BUFFER_TOO_SMALL The output buffer is too small, it must be at least 9 bytes long. ENCGDSD_GDSUSRWRT_FAILED The writing user exit failed. ENCGDSD_INVALID_CLASS An invalid GDSD tag class was found in a GDS structure. ENCGDSD_INVALID_FIXED_ITEM_LENGTH An invalid length value was found in the GDS structure corresponding to a GDSFLEN tagged type. ENCGDSD_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. ENCGDSD_INVALID_LENGTH An invalid length value was found in the GDS structure corresponding to a GDSLENGTH tagged type. ENCGDSD_INVALID_LL_LENGTH An invalid length value of the LENGTH field was found in the GDS structure corresponding to a GDSLENGTH type. ENCGDSD_UNDEFLEN_NOT_PERMITTED A GDS structure with undefined length was found, but segmentation is not used. ENCGDSD_SEGMENT_TOO_SHORT LLIDFISS segmentation is used with a too short segment. ENCGDSD_PRIM_TYPE_CONTENT_MISSING No content data or incomplete content data has been passed for the primitive type. ENCGDSD_USER_EXIT_FAILED The content user exit failed ENCGDSD_NESTED_SEGMENT Nesting of segmentated types has been found. Purpose The GDSencgdsd routine allocates an output buffer with the length specified by the buflen Then the GDSencgdsd routine starts to encode in the output buffer the GDSD-encoded data stream from the GDS structure tree. When the output buffer is full, it calls the writing user exit routine set by GDSsetUsrWrite routine, passing to it the pointer to the buffer and the length. This routine has to flush the buffer containing the GDSD-encoded data. It is called by the GDSencgdsd routine each time the buffer is full, but not all the GDS structure tree has been encoded. If the passing of the content data has been postponed, for example, if a GDS structure with the usrcontent field not NULL is found (for details on the postponing of the content data passing during encoding click here), the GDSencgdsd routine calls the content user exit pointed by the specific field of the GDS structure. This content user exit has to return a pointer to the data buffer, the length of the buffer and an indication if the data are the last or not. The GDSencgdsd makes a call to this user exit until the last indicator is on, or, if the content data length is not undefined, the length of the whole content data (passed by the content user exit) is equal to the specified content length (field loc of the GDS structure). An error is produced if the last indicator is on before the whole content data has been passed. The use_segmentation parameter permits the UAP to chooce to use the LLIDFISS segmentation or not. In fact the UAP could not use the LLIDFISS segmentation, even if it is allowed by the ASN.1 specification. The usrparms is a parameter passed to the writing user exit. It is a user-defined parameter whose contents are not examined by the GDSencgdsd routine. User Application Program can use this to pass local parameters to the writing user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. ═══ 11.8.11. GDSencode ═══ int GDSencode(void *module_ptr, unsigned short *metaindex, struct contents_str *cont_array_ptr, struct gds **gds_tree_ptr, enum TypOfEnc tenc, void *environment, void *usrparms); module_ptr Address of the definition structure of the module that containing the ASN.1 type to be encoded. metaindex Metatable index of ASN.1 type definition to be encoded. If an error occurs, it contains the index of the type where the error occurred. cont_array_ptr Pointer to the contents-array. It must be NULL if the user exit is used. gds_tree_ptr Address of a pointer to the encoded GDS structure tree resulting from the encoding process. This pointer is set by this routine. If an error occurs, the pointer points to an incomplete GDS structure tree. tenc Information about the type of encoding the User Application Program will use on the generated GDS structure tree. It can be ber, gdsd, or none. environment Address of the runtime environment allocated for the UAP. usrparms Address of a user-defined parameter which is passed to the encoding user exit routine during the encoding process. Results ENCODE_MATCH The encode operation concluded successfully. ENCODE_NO_MATCH The encoding operation terminated unsuccessfully due to a mismatch in the syntax of the value to be encoded and its related type. ENCODE_SYNTAX_ERROR The encoding operation terminated unsuccessfully due to a syntax error. ENCODE_INTERNAL_ERROR An internal programming error occurred. Something is wrong in the Metatable or the encoding user exit supplies an empty subtree. ENCODE_UNRESOLVED_REFERENCE An unresolved external reference was encountered. ENCODE_INVALID_GDSD_FIXED_LENGTH A GDS structure corresponding to a GDSFLEN tagged type has an invalid length value. ENCODE_INVALID_ENCODING_TYPE The encoding type specified is not valid (it can be: ber, gdsd or none). ENCODE_UNDEFLENGTH_NOT_PERMITTED Undefined length has been passed for types tagged with tag class requiring defined length. ENCODE_INVALID_LL_LENGTH A GDSLENGTH tagged type has an invalid length of the LENGTH field. ENCODE_INVALID_LENGTH A GDS structure has a length value that cannot be encoded in the allowed LENGTH field. ENCODE_INVALID_UNIQUE_ITEM_LENGTH A GDS structure corresponding to a GDSUNIQUE tagged type has an invalid length. ENCODE_INVALID_SEGMENT_LENGTH A GDS structure corresponding to a segmented type has an invalid segment length. ENCODE_INVALID_NUMBER_OF_SSOF_ITEMS The number of occurrences of the SET OF or SEQUENCE OF element, specified in the corresponding entry of the contents-array len field, is not valid. ENCODE_DEFAULT_FUNCTION The default encoding user exit has been invoked. ENCODE_MISSING_MANDATORY_ELEMENT A mandatory element of SET or SEQUENCE type has been not encoded. ENCODE_NO_ENOUGH_STORAGE A problem occurred during storage allocation. ENCODE_USER_EXIT_FAILED A problem occurred in the encoding user exit or it did not returned the correct parameters. Purpose The GDSencode routine is used to create a GDS structure tree that represents a value of the type referenced by the module_ptr and metaindex parameters. The encoding process can call the encoding user exit routine to supply individual values and to make various encoding decisions (such as passing an entire GDS structure subtree). Another mechanism for passing the content data is the use of the contents-array. The user exit mechanism could be more time consuming than the contents-array mechanism but it is more flexible and it does not have the limitation of former. The usrparms is one of the parameters passed to the encoding user exit. It is a user-defined parameter whose contents are not examined by the GDSencode routine. User Application Program can use this to pass local parameters to the encoding user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. Note that the encode function does not create the BER or GDSD encoded data. The GDS structure tree generated by the GDSencode routine contains the information needed to encode the data, but the actual encoding is a secondary step, performed by GDSencber or GDSencgdsd routines. The UAP can postpone the passing of the content data of the type it is encoding at the next encoding step (the GDSencgdsd or GDSencber call). To do this, the UAP has to set the usrcontent field of the GDS structure with a pointer to an user-defined content routine. This routine will be called by the GDSencgdsd or GDSencber routines when they encode the GDS structure. This mechanism of postponing the passing of the content data can be useful in case of segmentation or in case the content data is very large and it is not possible to load it in storage. (for the segmentation algorithms click here). Note: If GDSD encoding is used, the content user exit is used, and the content is segmented, the length of content field (loc) of the GDS structure can be set to undefined length value (this value is -1). If the length of content is set with a defined value and the content user exit is used, both the GDSencber and GDSencgdsd routines encode a number of content bytes equal to the specified length, despite the last indicator value returned by the content user exit. ═══ 11.8.12. GDSfindmodule ═══ struct moddef *GDSfindmodule(const char *module_name, void *environment); module_name Null-terminated name of the module to search for. environment Address of the runtime environment allocated for the UAP. Results The address of the module structure with the specified name, or NULL if no module is found with the specified name. Purpose The GDSfindmodule routine searches the active modules in the runtime environment for one with the name specified by the module_name parameter. ═══ 11.8.13. GDSfindtbl ═══ int GDSfindtbl(const void *module_ptr, const char *symbol_name, unsigned short *table_metaindex); module_ptr Address of the module structure containing the table to be found. symbol_name Address of the string containing the name of the symbol to be found. table_metaindex Address of a table index variable which will be set to the table definition in the Metatable, if the find operation is successful. If the find operation is not successful, the variable is unchanged. Results FIND_TABLE_OK The definition is found. FIND_TABLE_FAIL No definition is found. Purpose The GDSfindtbl routine is used to look up a table definition in a Metatable and return its index (for the description of TABLE definition click here). If the definition is not found FIND_TABLE_FAIL is returned. ═══ 11.8.14. GDSfindtype ═══ int GDSfindtype(const void *module_ptr, const char *symbol_name, unsigned short *type_metaindex); module_ptr Address of the module structure containing the type to be found symbol_name Address of the string containing the name of the symbol to be found type_metaindex Address of a table index variable which will be set to the type definition in the metatable, if the find operation is successful. If the find operation is not successful, the variable is unchanged. Results FIND_TYPE_OK The definition is found. FIND_TYPE_FAIL No definition is found. Purpose The GDSfindtype routine is used to look up a type definition in a Metatable and return its index. If the definition is not found, FIND_TYPE_FAIL is returned. ═══ 11.8.15. GDSfindval ═══ int GDSfindval(const void *module_ptr, const char *symbol_name, unsigned short *value_metaindex); module_ptr Address of the module structure containing the value to be found symbol_name Address of the string containing the name of the symbol to be found value_metaindex Address of a table index variable which will be set to the value definition in the Metatable, if the find operation is successful. If the find operation is not successful, the variable is unchanged. Results FIND_VALUE_OK The definition is found. FIND_VALUE_FAIL if no definition is found. Purpose The GDSfindval routine is used to look up a value definition in a Metatable and return its index. If the definition is not found, FIND_VALUE_FAIL is returned. ═══ 11.8.16. GDSfirstmodule ═══ int firstmodule(void **module_ptr, char **module_name, void *environment); module_ptr Address of a pointer to the first module definition in the active module list. The pointer is set by this routine. If the active list is empty, the pointer is set to NULL. module_name Address of a pointer to the first module name in the active module list. The pointer is set by this routine. If the active list is empty, the pointer is set to NULL. environment Address of the runtime environment allocated for the UAP. Results FIRST_MOD_OK The active module list is not empty and the module_ptr and the module_name pointers are not NULL. FIRST_MOD_FAIL The active module list is empty and the module_ptr and the module_name pointers are set to NULL. Purpose The GDSfirstmodule routine returns the first module of the list of active modules in the runtime environment. This function can be used in conjunction with the GDSunloadmodule routine to unload all the modules in the active list. ═══ 11.8.17. GDSfreeContentsArray ═══ void GDSfreeContentsArray(void *module_ptr, struct contents_str *contents_array_ptr); module_ptr Address of the module definition for which the contents-array has been allocated. contents_array_ptr Pointer to the contents-array that must be freed. Results None Purpose The GDSfreeContentsArray routine frees the contents-array storage and the storage of contlist-arrays that it points. The storage pointed by the contents field is not freed. ═══ 11.8.18. GDSfreeEnvironment ═══ void GDSfreeEnvironment(void *environment); environment Address of the runtime environment allocated for the UAP. Results None Purpose The GDSfreeEnvironment routine frees the storage of the runtime environment allocated for the UAP by the GDSinitEnvironment routine. ═══ 11.8.19. GDSfreegds ═══ void freegds(struct gds *gds_tree_ptr, void *environment); gds_tree_ptr Address of the GDS structure tree to be freed. environment Address of the runtime environment allocated for the UAP. Results None Purpose The GDSfreegds routine frees an entire GDS structure tree addressed by the gds_tree_ptr parameter. The contents fields that are marked allocd are freed (returned to the heap). Note that the GDS structures that are freed are chained to the freegds list rather than being returned to the heap. ═══ 11.8.20. GDSfreeGdsTreeArray ═══ void GDSfreeGdsTreeArray(struct gds **gds_tree_ptr); gds_tree_ptr Address of the array of GDS structures pointers. Results None Purpose The GDSfreeGdsTreeArray routine frees the storage of the array of GDS structures pointers allocated by the GDSallocateGdsTreeArray routine. ═══ 11.8.21. GDShex2str ═══ void GDShex2str(char *outbuf, long outlen, char *inbuf, long inlen); outbuf Address of the output buffer to contain the hex characters. outlen Length (in bytes) of the output buffer. inbuf Address of the input buffer containing the binary version of the hexadecimal string. inlen Length (in bytes) of the input buffer. Results None Purpose The GDShex2str routine converts a binary version of a hexadecimal string into a printable format. ═══ 11.8.22. GDSinitEnvironment ═══ void GDSinitEnvironment(void **environment); environment Address of the runtime environment allocated for the UAP. Results INIT_ENV_OK Allocation and initialization of runtime environment has been performed. INIT_ENV_FAILED Allocation and initialization of runtime environment failed, probably for some storage allocation problem. Purpose The GDSinitEnvironment routine initializes the runtime environment for processing ASN.1 modules. This routine should be called only once because it resets internal variables, some of which refer to dynamically allocated storage which will not be freed by GDSinitEnvironment. More than one runtime environment could be concurrently active in the same time, one for each UAP using the GDSEDLIB runtime library. ═══ 11.8.23. GDSINTEGERtolong ═══ int GDSINTEGERtolong(char *buffer, long loc, long *l); buf Address of the buffer containing the BER-formatted INTEGER. loc Length (in bytes) of the INTEGER. l Address of the long int which will hold the converted value. Results INTG2LNG_OK The conversion was successful. INTG2LNG_ERROR The conversion was unsuccessful. Purpose The GDSINTEGERtolong routine converts an ASN.1 INTEGER, formatted according to the basic encoding rules, into a long int. The buf parameter points to the contents of the INTEGER; it does not include the ID or length octets. ═══ 11.8.24. GDSlngs2OID ═══ int GDSlngs2OID(long *a, unsigned char *buf, int buflen, int *loc, int compress); a Address of an array of long integers, each element being one of the object identifier components. The array is terminated with a -1 value. buf Address of a buffer to hold the encoded object identifier value. buflen Length of the buffer in characters. loc Address of the integer which will be set to the length of the contents of the object identifier value (number of bytes used to encode the object identifier value). compress A flag to indicate whether the routine is supposed to compress the first two components into one subidentifier. A non zero value indicates compression. Results LNGS2OID_OK The conversion was successful. LNGS2OID_ERROR The conversion was unsuccessful. Reasons for failure include an inadequate output buffer or an invalid component. Purpose The GDSlngs2OID routine converts an array of object identifier components into an object identifier value according to the basic encoding rules. The array is terminated with a -1 value. The compress parameter indicates whether the first two components are compressed into a single subidentifier (as the basic encoding rules require). The complete object identifier value may be encoded by repeated calls to this routine; the first call (to build the prefix) would have the compress flag set to a non zero value, and subsequent calls (to build the suffixes) would indicate no compression with a zero value for compress. ═══ 11.8.25. GDSlongtoINTEGER ═══ int GDSlongtoINTEGER(long l, unsigned char *buf, long *loc); l The long integer that is to be converted. buf The buffer into which the converted ASN.1 INTEGER is placed. loc The length (in bytes) of the output buffer; it must be at least 4. As output parameter it contains the length of the encoded INTEGER. Results LONG2INTEGER_OK The conversion was successful. Purpose The GDSlongtoINTEGER routine converts a long int into an ASN.1 INTEGER value according to the basic encoding rules. ═══ 11.8.26. GDSnewgds ═══ int GDSnewgds(struct gds **gds_ptr, char *module_name, char *symbol_name, struct ietag *it, enum tagclass class, unsigned long id, enum frm form, char *contents, long loc, enum stg contstg, int (*usrcontent) (char **, unsigned long *, enum lastflag *), void *environment); gds_ptr The pointer to the allocated and initialized GDS structure tree. module_name Address of the module name for the type associated with this GDS structure. symbol_name Address of the symbol name for the type associated with this GDS structure. it Implicit tagging information address or NULL. class Class of the item being built into the GDS. id Identifier number of the item being built into the GDS. form Form of the item being built into the GDS. contents Address of the contents field for the GDS. loc Length of the contents field. contstg Storage class for the contents field. usrcontent The pointer to the content user exit called by GDSencgdsd or GDSencber routines to get the data that must be encoded inside the type. Its parameter are in the order: o The buffer containing the data o The length of the buffer o A flag indicating if the buffer returned is the last environment Address of the runtime environment allocated for the UAP. Results NEWGDS_OK The new GDS structure has been correctly allocated NEWGDS_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. Purpose The GDSnewgds routine creates a new GDS structure and initializes most of its fields. If the it parameter is not NULL, the information addressed by it overides the class and id parameters. The GDSnewgds routine uses an existing structure on the free GDS list, if one is available; otherwise, it will allocate one from the heap. The contstg parameter indicates whether the storage associated with the contents field (pointed to by contents) should be freed when the GDS structure is freed. The structure of the GDS is described here. ═══ 11.8.27. GDSOIDtolngs ═══ int GDSOIDtolngs(char *buf, int loc, long *a, int asize); buf Address of buffer containing the object identifier value contents. loc Length of the contents field. a Address of an array of long ints to hold the converted object identifier components. asize Maximum number of elements in the array. Results OID2LNGS_OK The conversion was successful. OID2LNGS_ERROR The conversion was unsuccessful. Purpose The GDSOIDtolngs routine converts the contents part of an object identifier value into an array of long ints, one object identifier component per array element. The array is terminated by an element containing -1. The asize parameter must be large enough to include the terminating -1 element. ═══ 11.8.28. GDSprintgds ═══ int GDSprintgds(struct gds *gds_tree_ptr, int indentcol, long max_content_len, long rowlen, FILE *tracefile, enum TypOfEnc tenc); gds_tree_ptr Address of the GDS structure tree to be printed. indent The number of spaces to indent each nesting level of the embedded GDS structures. max_content_len The maximum number of content characters that must be printed rowlen The maximum number of content characters that must be printed on a line tracefile The descriptor of the file where the trace must be printed tenc The type of encoding used during the generation of the GDS structure tree (ber or gdsd). Results PRINT_GDS_OK The print operation was successful. PRINT_GDS_ERROR The print operation was unsuccessful. PRINT_GDS_NO_ENOUGH_STORAGE Some problem occurred during storage allocation. Purpose The GDSprintgds routine is used to print a formatted representation of a GDS structure tree. The indent parameter is used to set the number of spaces with which to indent each nesting level of the embedded GDS structures. Other formatting decision can be made using the max_content_len and rowlen parameters. This routine can be called also to print an incomplete GDS structure tree. The tracefile parameter is assumed to be a descriptor for a file that is already open. This routine neither opens nor closes this file. ═══ 11.8.29. GDSPrintUnresolvedImports ═══ int GDSPrintUnresolvedImports(FILE *outfile, void *environment); outfile File descriptor for the report. environment Address of the runtime environment allocated for the UAP. Results PRTUNRES_OK The print operation was successful. PRTUNRES_BAD_FILE The print operation was unsuccessful because of a unusable file descriptor. Purpose The GDSPrintUnresolvedImports routine is used to print a formatted listing of the unresolved imported symbols in the current list of ASN.1 modules. Typically, you would use this routine to diagnose the cause of a bad return code from the GDSresolveallimports or the GDSresolveimports routines. The outfile parameter is assumed to be a descriptor for a file that is already open. This routine neither opens nor closes this file. ═══ 11.8.30. GDSreaddatfile ═══ int GDSreaddatfile(char *fn, void *environment); fn A null terminated string for the file name of the DAT file. environment Address of the runtime environment allocated for the UAP. Results READ_DAT_OK The DAT file was successfully read into the runtime environment. READ_DAT_OPEN An error occured in opening the file. READ_DAT_VERSION The DAT file has version number incompatible with the runtime library. ADDMODULE_DUP_MODULE A duplicate module was found already loaded into the runtime environment. Purpose The module definitions in the referenced file are read into the runtime environment and added to the list of active ASN.1 modules. Note that external references are not resolved by the GDSreaddatfile routine. ═══ 11.8.31. GDSresolveallimports ═══ int GDSresolveallimports(void *environment); environment Address of the runtime environment allocated for the UAP. Results RESOLVE_IMPORTS_OK All imported symbols were resolved. UNRESOLVED_REFERENCE One of the imported symbols could not be resolved amongst the active modules. Purpose The GDSresolveallimports routine resolves the imported symbols from each of the active modules in the runtime environment. This operation can be done after a number of modules have been added (with the GDSaddmodule or GDSreaddatfile routines), and it can be done subsequently after other modules have been added. ═══ 11.8.32. GDSresolveimports ═══ int GDSresolveimports(void *module_ptr, void *environment); module_ptr Address of the module structure whose imported symbols are to be resolved against the list of active modules in the runtime environment. environment Address of the runtime environment allocated for the UAP. Results RESOLVE_IMPORTS_OK All imported symbols were resolved. UNRESOLVED_REFERENCE One of the imported symbols could not be resolved amongst the active modules. Purpose The GDSresolveimports routine is used to resolve the imported symbols from the module addressed by the module_ptr parameter. ═══ 11.8.33. GDSsetUsrDec ═══ void GDSsetUsrDec(int (*gdsusdec) (unsigned short, struct gds *, char *, unsigned long, void *), void *environment); gdsusdec The address of an user-defined function with the prototype shown above. environment Address of the runtime environment allocated for the UAP. Results None Purpose The GDSsetUsrDec routine initializes a variable to point to a decoding user exit routine. This decoding routine is invoked during the decoding process by GDSdecode or by GDSdecgdsd routine to pass the decoded content data and to permit the UAP to make various decoding decisions. The parameter of this user decoding function are in the order: o The Metatable index of the decoded type o The pointer to the GDS structure corresponding to the type o The content data o The length of the content data o the user-defined parameter that the GDSdecode or GDSdecgdsd routine will pass to the decoding user exit during the decoding process. The decoding user exit is called by GDSdecode or by the GDSdecgdsd routine each time a new type definition is decoded (in this case no content data are passed) or an ASN.1 built-in primitive type is decoded (the GDSdecode routine calls it also for ANY or ANY DEFINED BY types, click here for details). The GDSsetUsrDec can be called anytime, even during a decode operation, to set or change the user decoding function. If the GDSsetUsrDec routine is called by the decoding user exit, called by decode routines before decoding a new type definition, to set another decoding user exit for the current type, the current decoding user exit will be active again when the decoding of that type is finished. This mechanism permits the UAP to set different decoding user exits for the different defined types. ═══ 11.8.34. GDSsetUsrEnc ═══ void GDSsetUsrEnc(int (*usrencfn) (struct encinh ia, struct encinhsyn *sa, enum tagclass cls, long id, enum frm form, char *encsubs), void *environment); usrencfn The address of a user-defined function with the prototype shown above. environment Address of the runtime environment allocated for the UAP. Results None Purpose The GDSsetUsrEnc routine initializes a variable to point to an encoding user exit routine. This user encoding routine is invoked during the encoding process to supply values and make various encoding decisions. The parameters of this user encoding function are in the order: o ia, a pointer to the inherited attributes structure. This structure contains information about the type that is going to be encoded: struct encinh { /* inherited attributes */ struct ietag *it; /* points to the structure containing * the information of implicit tagging if * the type is implicit tagged */ char *symname; /* name of the current item to encode */ char *modname; /* current module name */ struct moddef *m; /* module for type to encode */ void *usrparms; /* user parms */ char opt; /* TRUE if item is optional or defaulted, FALSE if mandatory */ }; Note: ietag contains information about the tagging. Note: The usrparms field consists of the user-defined parameter passed by the UAP to the GDSencode routine. It is passed by the GDSencode routine to the encoding user exit without examine its content. User Application Program can use this to pass local parameters to the encoding user exit routine. This is useful when the the UAP and the user exit routine must share data. The alternative is to make the shared data global, usually an undesirable programming practice. The ia information must be used by the encoding user exit to make its encoding decisions and to allocate, if necessary, a new GDS structure via the GDSnewgds routine. o sa, a pointer to the inherited and synthesized attributes structure. This structure contains information passed by GDSencode to the user exit (ndx, base) and information passed by the user exit to GDSencode (p). struct encinhsyn { /* inherited and synthesized attributes */ struct gds *p; /* the GDS structure allocated fo the type */ tbldex ndx; /* the Metatable index of type encoded */ enum basetypes base; /* base type of GDS */ long ssof_items_num; /* num of items inside a SET OF or SEQ OF */ }; Note: ssof_items_num is not used in this context. o tagclass, the tag class of the type to be encoded o id, the IDENTIFIER value of the type to be encoded o form, the form (constructed or primitive) of the type to be encoded. o encsubs, a flag, set by the user exit, indicating if the GDSencode has to encode the subtypes contained in the current type. In fact the encoding user exit could supply the entire subtree for the type that is going to be encoded, and in this case the GDSencode does not have to encode the contained subtypes. The encoding user exit is called by GDSencode routine each time a new type definition is encoded or an ASN.1 built-in type is encoded or an EXPLICIT tag is encoded. The GDSsetUsrEnc may be called anytime, even during an encode operation, to set or change the user encoding function. In the case the GDSsetUsrEnc routine is called by the encoding user exit, called by encode routine before encoding a new type definition, to set another encoding user exit for the current type, the current encoding user exit will be active again when the encoding of that type is finished. This mechanism permits the UAP to set different encoding user exits for the different defined types. If the encoding user exit is called for a type that is an OPTIONAL or DEFAULT component of a constructed type, and that particular occurrence of that type must not be encoded, then the encoding user exit has only to return the ENCODE_NO_MATCH return code to inform the GDSencode routine that the specific type must not be encoded. If the encoding user exit is called for an ANY or ANY DEFINED BY type, it has to call the GDSencode routine to encode the selected ASN.1 type. Note that GDSencode routine supports recursion, so it can be called recursively by the encoding user exit. If the encoding user exit is called for constructed types, it can pass the entire subtree to the GDSencode or it can allocate another GDS structure calling the GDSnewgds routine. In both the cases, the pointer to the subtree root or to the GDS structure must be returned in the field p of sa (i.e. sa->p). If the encoding user exit is called for primitive types it has to allocate another GDS structure (using the GDSnewgds routine, passing it the contents, and the other parameters passed by GDSencode), and to return the pointer in the field p of sa (i.e. sa->p). ═══ 11.8.35. GDSsetUsrRead ═══ void GDSsetUsrRead(int (*usrread) (char *buff, unsigned long buflen, void *usrparms), void *environment); usrread the address of an user-defined function with the prototype shown above. environment Address of the runtime environment allocated for the UAP. Results None Purpose The GDSsetUsrRead routine initializes a variable to point to an user-defined reading routine. This reading routine is invoked by the GDSdecber and GDSdecgdsd routines to load in the buffer the data that must be decoded. It has to load the buffer pointed by buff with buflen data bytes. The GDSsetUsrRead can be called anytime, even inside the reading user exit, to set or change the user reading function. If the UAP does not set the reading user exit, a default one is used. This reads buflen characters from standard input. ═══ 11.8.36. GDSsetUsrWrite ═══ void GDssetUsrWrite(int (*usrwrite) (char *buff, unsigned long buflen, void *usrparms), void *environment); usrwrite The address of a function with the prototype shown above. environment Address of the runtime environment allocated for the UAP. Results None Purpose The GDSsetUsrWrite routine initializes a variable to point to a user-defined writing routine. This writing routine is invoked by the GDSencber and GDSencgdsd routines to flush the buffer containing the encoded data. It has to flush buflen data bytes contained the buffer pointed by buff. The GDSsetUsrWrite can be called anytime, even inside the writing user exit, to set or change the user writing function. If the UAP does not set the writing user exit, a default one is used. This writes buflen characters on standard output. ═══ 11.8.37. GDSstr2hex ═══ void GDSstr2hex(char *outbuf, long outlen, char *inbuf, long inlen); outbuf Output buffer that will contain the bynary/hexadecimal string. outlen Output buffer length. inbuf Input buffer that contains the printable form of the hexadecimal string. inlen Input buffer length. Results None Purpose The GDSstr2hex routine converts a printable form of a hexadecimal string (for example: AA00EEFF) into a binary form. ═══ 11.8.38. GDStypestr ═══ char *GDStypestr(enum basetypes base); base The base that is to be converted. Results Returns a pointer to a character string that is a printable version of the value in base Purpose The GDStypestr routine returns a pointer to a character string that is a printable version of the value in base. ═══ 11.8.39. GDSunloadmodule ═══ int GDSunloadmodule(void *modptr, void *environment); modptr Address of the module structure to be unloaded. environment Address of the runtime environment allocated for the UAP. Results UNLOAD_MOD_OK The module was successfully unloaded. UNLOAD_MOD_NOT_FOUND The module was not found among the list of active modules. Purpose The GDSunloadmodule routine is used to remove a module from the active list of modules and free up dynamically allocated space associated with it. This routine should only be used for modules that are dynamically loaded by the GDSreaddatfile routine. Note that a single DAT file can contain many modules; to remove all of them, repeated calls the the GDSunloadmodule function are needed. When the last module of a DAT file is unloaded, the dynamic space for its symbol table is also freed. ═══ 12. The Structure of the TBL File ═══ The TBL file contains the metatable and symbol table definitions corresponding to the ASN.1 source file. The TBL format is character data that is intended to be portable. Machine independence is gained by using only character forms for all data types, including those for decimal numbers and some special types, such as for object identifier values. In this way the TBL format represents an intermediate form; it is more compact and has more embedded information than the original ASN.1 source, but it is still as machine-independent as is possible. This allows the ASN.1 compiler to be hosted on one type of computer to generate metatable and symbol table information for use by the user application on a different system. The structure of the metatable is directly related to the abstract syntax notation from which it is derived. The metatable represents the syntactic structure of the ASN.1 definitions. The symbol table contains the names defined in the ASN.1 source. Each ASN.1 module in the source file has a corresponding metatable, and one symbol table contains all the names used in all the modules. The following sections provide the details of both the TBL format and how they relate to the C language formats of the application environment. The TBL file contains the following structures, in order: 1. Version identifier 2. Symbol Table length 3. Symbol Table name 4. Symbol Table 5. Module definitions All the examples of the TBL file structures shown here are extracted from the TBL file corresponding to the ASN.1 source file shown in the example ASN.1 source file figure. The version identifier is a string, ending with a newline character, that is used to verify that the versions of the ASN1 program, which created the TBL file, and the GDSTABLE program are the same. An example version identifier is: GenE/D version 1.0 - 5684-075 The symbol table length specifies the number of characters in the symbol table. Its format is a series of characters, ending with a newline character, in the following form: symbol table len: 203 The symbol table name is used in constructing a name for a data structure in the C file format. It is not used for the DAT file format. The GDSASN1 Compiler uses one of the module reference identifiers for the symbol table name. Its format is a series of characters, ending with a newline character, in the following form: symbol table name: MyModule The symbol table contains each symbol needed by the module definitions that follow. Within the TBL file, each symbol is separated from its neighbors by a newline character. In the C and DAT file formats, the symbols are separated from one another by a null ('\0') character. The example Symbol Table figure shows a sample symbol table, corresponding to the ASN.1 source file shown in example ASN.1 source file figure. Example ASN.1 Source File -- This Example ASN.1 source file defines two ASN.1 modules. MyModule DEFINITIONS IMPLICIT TAGS ::= BEGIN -- start of MyModule EXPORTS MyType2; IMPORTS PrintStr FROM ExtModule; MyType1 ::= [4] SEQUENCE{ field1 MyType2, field2 OCTET STRING, field3 PrintStr } MyType2 ::= SET{ field1A SEQUENCE{ sub-field1 OCTET STRING, sub-field2 OCTET STRING } OPTIONAL, field1B [2] IMPLICIT OCTET STRING (SIZE(1..4)) OPTIONAL } END -- end of MyModule ExtModule DEFINITIONS IMPLICIT TAGS ::= BEGIN -- start of ExtModule EXPORTS PrintStr; IMPORTS MyType2 FROM MyModule; PrintStr ::= PrintableString XType ::= SEQUENCE OF MyType2 END -- end of ExtModule ExampleSymbolTable GLOBAL-MODULE MyModule MyType1 MyType2 ExtModule PrintStr XType field1 OCTET STRING field2 field3 SEQUENCE DEFAULT IMPLICIT sub-field1 sub-field2 field1A IMPLICIT field1B SET PrintableString SEQUENCE OF The module definitions appear after the symbol table and are discussed next. ═══ 12.1. Structure of Module Definitions ═══ Each module definition in the TBL file is of this format: 1. Module identifier 1 2. Number of elements in the module 3. Type, value and table definitions 4. End of type, value and table definitions 5. Number of types, values, and table definitions 6. List of symbol table references for the types, values and table definitions 7. Number of imported symbols 8. Imported symbol information 9. Number of exported symbols 10. Exported symbol information 11. Module identifier 2 12. Symbol table index for the module name 13. Default tagging The module identifier 1 is a string with this example format: module: MyModule The number of elements in the module is specified with this format: number of elements: 26 An element corresponds to one metatoken structure as specified in the tokstruc.h file. The type, value and table definitions occur next. Each type, value, and table definition starts with a line consisting of -2, an indicator of whether the definition is a type, value, or table definition, and the name of the type, value, or table being defined. Then the elements of the definition follow, one line per element. For example, the following fragment shows a type definition: -2 type: MyType1 2 23 0 107 0 4 -1 4 10 11 98 0 9 15 5 23 64 10 15 7 10 84 15 9 24 91 39 49 18 Each element is specified as a series of numbers. The number and the meaning of each number in the element depends on the ASN.1 source used to define the corresponding type, value, or table. Each element corresponds to one of the structures in the tokstruc.h file. The GDSTABLE program uses these to create the metatable parts of the C and DAT files. The first number is a token identifier as defined in the file metatoks.h. The end of the type, value, and table definitions is indicated by a single line consisting of -1, for example: -1 The number of type, value, and table definitions is of this format: types/values/tables: 2 The list of symbol table references for the type, value, and table definitions follow: 0 10 The number of imported symbols is of this example format: imports: 1 Note: The number of imported symbols may not be exactly equal to those listed in the ASN.1 source IMPORTS clause. The GDSASN1 Compiler includes external references in the imported symbol list. In fact, a symbol defined in another module may be referenced without appearing in the IMPORT clause if explicit references (modulename.symbolname) are used. However, explicit references should be avoided; ASN.1 allows them for compatibility with an earlier version of the standard (CCITT Rec. X.409-1988). The imported symbol information follows next. Each imported symbol has one line in the TBL file consisting of two numbers. The first number is symbol table reference for the module name of the imported symbol. The second number is the symbol table reference for the imported identifier. The following example shows one imported symbol: 39 49 The number of exported symbols is of this example format: exports: 1 The exported symbol information consists of zero or more lines, one line per exported symbol. Each line consists of two numbers. The first number is the symbol table reference for the name of the exported symbol. The second number is the element number of the corresponding definition in this module. This example shows one exported symbol: 31 10 The module identifier 2 looks like this: Module: MyModule The symbol table reference for the module identifier looks like this: 14 The default tagging for the module follows next on a single line and consists of the characters, implicit or explicit. For example: implicit ═══ 13. The Structure of a DAT File ═══ The DAT file is created as one of the output files of the GDSTABLE. program. The DAT file is a more compact and efficient form of the TBL file for the runtime application and the encode/decode routines. So, the DAT file contains the same information contained in the TBL file. The application program can read at run time the DAT file invoking a specific GenE/D runtime routine. The DAT file is machine-dependent. Its structure is similar to the TBL structure. It consists of the following components, in order: 1. Version identifier (char [], terminated by '\n') 2. Symbol table length (int) 3. Symbol table (char []) 4. Module definitions The version identifier is a string used to ensure the DAT file is compatible with the version of the runtime library used by the application. It is terminated by a newline character (not a null character). The symbol table length is an int and its value is the number of characters in the symbol table. The symbol table contains all the symbols needed by the module definitions. Each symbol is terminated by a null ('\0') character. The module definitions follow. Each module definition consists of the following information: 1. Number of bytes in the metatable (int) 2. Metatokens (mtok []) 3. Number of type, value, and table definitions (int) 4. List of type, value, and table definition references (tbldex) 5. Number of imported symbols (int) 6. List of imported symbol information (struct berimp []) 7. Number of exported symbols (int) 8. List of exported symbol information (struct berexp []) 9. Symbol table index for the module name (symdex) 10. Module tagging default (enum tagging) For more information on how the ASN.1 definitions are mapped into the metatable structures and how these metatable structures are mapped into the metatoken sections of the DAT files, see the General Data Stream Encoder/Decoder User's and Programmer's Guide manual. ═══ 14. List of Abbreviations ═══ Term Definition ASN.1 Abstract Syntax Notation Number One BER Basic Encoding Rules CCITT International Consultative Committee on Telegraph and Telephone GDS General Data Stream GDSD General Data Stream Definitions ISO International Organization of Standardization OSI Open Systems Interconnection PDU Protocol Data Unit SNA Systems Network Architecture TCP/IP Transmission Control Protocol Internet Protocol UAP User Application Program ═══ 15. Appendix A. Utilities ═══ Two utilities are supplied with the GenE/D system. ═══ 15.1. GDSTDATS Program ═══ The GDSTDATS program can be used to test if some .DAT file has some unresolved reference. To invoke this utility enter the following command on OS/2 or AIX/6000 command line: GDSTDATS and then enter the path and file name of each .DAT file you want to check. ═══ 15.2. GDSTTOOL Test Tool ═══ GDSTTOOL is a tool for testing GenE/D scenarios. A scenario consists of an ASN.1 source file and a contents data input file (also referred to as the .INP file). The .INP file is read by GDSTTOOL in order to get the data to be encoded. You must edit the .INP file, starting from a preformatted file generated by the GDSTABLE translator, if the -s option is specified. The .INP preformatted file contains a block like the following: ******************************************************************************* Item: MyModule_MyType1_SEQUENCE_item1_CharacterString TableIndex: 16 BaseType: CharacterString NumOfContents: ContLength: Content: UsrContent: ******************************************************************************* For each ASN.1 type that requires data or encoding decisions during encoding process (the types for which the contents-array is accessed by the GDSencode routine. Edit this file opportunely: o Follow NumOfContents tag with the number of occurrences of the SET OF or SEQUENCE OF component, if the block corresponds to a SET OF or a SEQUENCE OF type (see GDSallocateContentsArray). Moreover, in this case, after the block corresponding to a SET OF or a SEQUENCE OF, as many other blocks as the occurrences of the SEQUENCE OF or SET OF component are (note that they must be primitive types). The test tool extracts from each of these added blocks the information related to the specific occurrence corresponding to the block. o Follow ContLength tag with the length of the content data, if the block corresponds to a primitive type and the content data is specified. o Follow Content tag with one or more lines of character strings, if the block corresponds to a primitive type or the block corresponds to a constructed type that is an OPTIONAL or DEFAULT component of a parent constructed type (in this case the content data are not encoded; at least one character must be specified in order to inform the encode routine that the specific component must be encoded). Each character string cannot go past column 79. The continuation to the following line must be indicated specifying a not blank character in column 80. o Follow UsrContent tag with the name of a content user exit, if the Content tag is not followed by anything and the block corresponds to a primitive type. The name of the content userexit you can use is content_user_exit. The content user exit function is predefined. It reads data from the content file (specified as input parameter of test tool invocation) until EOF is reached, passing it to the encode routine. No conversion is performed on the content data. After you have edited the .INP file, you have to invoke the test tool passing to it: o The path and name of the .DAT file generated compiling the ASN.1 source file o The path and name of the .INP file o The path and name of the trace output file, where the GDSTTOOL prints trace information (the default is stdout) o The path and name of the encoded data stream file, where the GDSTTOOL writes the encoded data stream o The type of encoding: ber or gdsd o The name of the type that must be encoded/decoded o The name of the content file from which the content_user_exit function gets the content data GDSTTOOL performs the following operations: 1. Loads the .DAT file. 2. Parses the .IMP file. 3. Allocates a contents-array and loads this with the data extracted from the .IMP file. 4. Encodes the data stream, saving it in the passed file. 5. Decodes the encoded data stream. 6. Encodes the GDS structure tree generated by decoding, producing another data stream and saving it in a temporary file. 7. Compares the two generated data streams. ═══ 16. Appendix B. GDSASN1 Compiler Return Codes and Messages ═══ GDSASN1 compiler messages. ═══ 16.1. Error Messages ═══ ═══ 16.1.1. GDSC0401 ═══ "name" has a duplicate definition at line l, column c severity: 4 The symbol, name, has been used in another definition at the indicated line and column. ASN.1 allows names to be used more than once in a module (for example, named numbers, named bits, choice alternatives, sequence, and set components). Defined types and defined values and imported symbols cannot be used more than once in any one module. The same module reference cannot be used to name more than one module. ═══ 16.1.2. GDSC0402 ═══ Internal error: info severity: 4 The compiler found an irrecoverable error. The info is useful to the person who maintains the compiler for localizing and fixing the problem. ═══ 16.1.3. GDSC0403 ═══ SymbolKind "Symbol" referenced but not defined in module "M" severity: 4 A type, value, or table name has been referenced in module M, but it has not been defined or imported into the module. Symbols need not be defined before they can be referenced, but they must be defined or imported in the module in which they are referenced. ═══ 16.1.4. GDSC0404 ═══ Value range subtype not legal for parent type severity: 4 The value range can only be used for INTEGER and REAL data types. An attempt was made to use it with another data type. ═══ 16.1.5. GDSC0405 ═══ Size constraint subtype not legal for parent type severity: 4 The size constraint can only be used for BIT STRING, OCTET STRING, CharacterString, SET OF, and SEQUENCE OF data types. An attempt was made to use it with some other data type. ═══ 16.1.6. GDSC0406 ═══ ANY DEFINED BY reference "identifier" is undefined severity: 4 The identifier in the ANY DEFINED BY identifier must refer to a named type in the SEQUENCE or SET where the ANY DEFINED BY appears. The referenced named type can occur before or after the ANY DEFINED BY. Note that the identifier must begin with a lowercase letter and should not be confused with the identifier for the component's type. Here is a correctly defined example: A ::= SET{ a ANY DEFINED BY b, b INTEGER} See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ANY DEFINED BY. ═══ 16.1.7. GDSC0407 ═══ Component "comp" referenced by ANY DEFINED BY must not be OPTIONAL severity: 4 The referenced component, comp, in the SEQUENCE or SET is OPTIONAL. ASN.1 requires the component upon which the ANY DEFINED BY is referenced be mandatory or have a default value. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ANY DEFINED BY. ═══ 16.1.8. GDSC0408 ═══ Component "comp" referenced by ANY DEFINED BY must be a subtype of INTEGER or OBJECT IDENTIFIER severity: 4 The component upon which the ANY DEFINED BY depends, comp, is not a subtype of INTEGER or OBJECT IDENTIFIER. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ANY DEFINED BY. ═══ 16.1.9. GDSC0409 ═══ ANY DEFINED BY cannot be used in a SEQUENCE or SET severity: 4 The ANY DEFINED BY construct may not be used within a CHOICE, even though the CHOICE is a component of a SET or SEQUENCE. It cannot be used to define a type that is then referenced in a SET or SEQUENCE. It cannot be tagged. The following are invalid examples: A ::= SET{a INTEGER, b CHOICE{ [0] INTEGER, [1] ANY DEFINED BY a -- This is illegal -- } } B ::= SET{a INTEGER, b C} C ::= ANY DEFINED BY a -- This is illegal -- See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ANY DEFINED BY. ═══ 16.1.10. GDSC0410 ═══ Illegal ANY DEFINED BY syntax severity: 4 The incorrect syntax for the ANY DEFINED BY construct is usually caused by misspelling one of the keywords or by failing to use an identifier starting with a lowercase letter after ANY DEFINED BY. The line and column number in the error message identify the source of the error. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ANY DEFINED BY. ═══ 16.1.11. GDSC0411 ═══ Expected '-' or a digit severity: 4 The lexical analyzer found a dash and expected to find another dash, signifying a comment, or a digit, signifying a signed number. The character at the line and column number identifies the source of theb error. ═══ 16.1.12. GDSC0412 ═══ Identifier must not end in a dash - ignored severity: 4 An ASN.1 identifier can include dashes, but they must not occur: o at the beginning of the identifier o consecutively o as the last character in the identifier The compiler ignores the trailing dash. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ASN.1 identifiers. ═══ 16.1.13. GDSC0413 ═══ Expected 'char' for an assignment item, "::=" severity: 4 The compiler was expecting an assignment item, "::=" but found an invalid character at the indicated line and column number. ═══ 16.1.14. GDSC0414 ═══ Expected '0' or '1' in binary string item severity: 4 The lexical analyzer found an illegal character in a binary string item. The only allowed characters in a binary string are '0' and '1'. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ASN.1 binary strings. ═══ 16.1.15. GDSC0415 ═══ Expected hexadecimal digit in string item severity: 4 The lexical analyzer found an invalid character in a hexadecimal string item. The only allowed characters in a hexadecimal string are '0' through '9' and 'A' through 'F'. Note that lowercase hexadecimal digits 'a' through 'f' are not allowed. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ASN.1 hexadecimal strings. ═══ 16.1.16. GDSC0416 ═══ Expected 'B' or 'H' severity: 4 The lexical analyzer found the terminating single quote for a hexadecimal or binary string item, but did not find the required 'B' (for binary) or 'H' (hexadecimal) letter following the last single quote. Note there must not be any spaces between the single quote and the letter ('B' or 'H') and that the letter must follow, not precede the quoted string. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the syntax of ASN.1 hexadecimal and binary strings. ═══ 16.1.17. GDSC0417 ═══ Too many characters in item, aborting compilation severity: 4 The lexical analyzer filled up its internal buffer with characters before completing an ASN.1 item. This can be caused by a missing quotation mark. ═══ 16.1.18. GDSC0418 ═══ Skipping unrecognized character 'char' severity: 4 The lexical analyzer found a character that is not in the ASN.1 repertoire. This can be caused by mismatched quotation marks. ═══ 16.1.19. GDSC0419 ═══ "identifier" is a recursive type/value definition severity: 4 The "identifier" has been used to define itself, perhaps through a chain of indirections. These are illegal definitions: A ::= B -- illegal recursion B ::= C -- illegal recursion C ::= A -- illegal recursion Some forms of recursion are, however, allowed: Tree ::= CHOICE{ i InternalNode, l LeafNode} InternalNode ::= SEQUENCE{ leftSubtree Tree, rightSubtree Tree} LeafNode ::= INTEGER ═══ 16.1.20. GDSC0420 ═══ Script symbol "sym" is not recognized severity: 4 The lexical analyzer either does not support the script substitution symbol sym or it is misinterpreting the source as a containing a script substitution symbol. For this message to occur, the script option must be in effect, and the referenced symbol must occur within an ASN.1 section (for example, between .* asn.1 on and .* asn.1 off), and it must occur in a context where an ASN.1 item is expected (i.e. not in a comment or character string). See the GDSASN1 compiler input for the supported script symbols. ═══ 16.1.21. GDSC0421 ═══ Expected "STRING" following "Keyword" severity: 4 The compiler found the keyword "BIT" or "OCTET" and expected the next item to be the keyword "STRING". Note that "BIT STRING" is two separate words, as is "OCTET STRING". They can be on different lines, and even have comments separating them, but there must be no other keywords or punctuation between them. ═══ 16.1.22. GDSC0422 ═══ Illegal module definition severity: 4 The module definition is illegal. There are probably other error messages in the vicinity that indicate which clauses are incorrect. The compiler will attempt to recover at the next type or value assignment. An "END" item, if it exists, will probably generate an error message too, since the module definition lines are ignored. Common problems in module definitions are: o Failure to terminate an EXPORTS or IMPORTS clause with a semicolon. o Putting the EXPORTS clause before the IMPORTS clause o Misspelling keywords or using lowercase letters in DEFINITIONS, IMPLICIT, TAGS, BEGIN, EXPORTS, IMPORTS See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.23. GDSC0423 ═══ Illegal IMPORTS/EXPORTS symbol list, skipping to ';' severity: 4 The compiler found an error in an IMPORTS or EXPORTS clause of a module definition. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.24. GDSC0424 ═══ Expected an assignment severity: 4 This message occurs when the compiler expects a type assignment or a value assignment but encounters something different. This message is often accompanied by other messages that are more specific about the syntax in error. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.25. GDSC0425 ═══ "Identifier" is an illegal type/value assignment severity: 4 The parser found the beginning of a valid type or value assignment with the name Identifier, but encountered an error somewhere on the right-hand side of the "::=" item. Usually, other error messages will localize the problem. ═══ 16.1.26. GDSC0426 ═══ Illegal INTEGER/ENUMERATED named number list severity: 4 The compiler found the beginning of a named number list for an INTEGER or ENUMERATED type, but found an error within the list itself. There is usually another error message that more closely pinpoints the error. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of INTEGER and ENUMERATED. ═══ 16.1.27. GDSC0427 ═══ "identifier" is an illegal named number severity: 4 Within the named number list for an INTEGER or ENUMERATED, the compiler encountered a named number, identifier, which was illegal. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of a named number list. ═══ 16.1.28. GDSC0428 ═══ "identifier" must begin with a lowercase letter severity: 4 The identifier begins with an uppercase letter. Named bits (in a BIT STRING) and named numbers (in an INTEGER and ENUMERATED) must begin with lowercase letters. ═══ 16.1.29. GDSC0429 ═══ Illegal named bit list severity: 4 The compiler found the beginning of a named bit list for a BIT STRING type, but found an error within the list itself. There is usually another error message that more closely pinpoints the error. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of BIT STRING. ═══ 16.1.30. GDSC0430 ═══ Named bit value must be greater than or equal to zero severity: 4 The named bit was given a negative value. Bits are numbered starting from zero at the first bit. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of BIT STRING. ═══ 16.1.31. GDSC0431 ═══ "identifier" illegal named bit severity: 4 The compiler found incorrect syntax following the identifier and it expected a named bit. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of BIT STRING. ═══ 16.1.32. GDSC0432 ═══ Illegal element after comma severity: 4 The compiler found an error in the SET or SEQUENCE component following the indicated comma. Usually other error messages will locate the error more closely. A frequent error is the omission of a comma between components or including the comma as part of a comment instead of placing it outside the comment. ═══ 16.1.33. GDSC0433 ═══ Numeric REAL value base must be 2 or 10 severity: 4 ASN.1 requires that the REAL data type be of base 2 or base 10 only. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of REAL. ═══ 16.1.34. GDSC0434 ═══ Illegal subtype specification severity: 4 The compiler had found what looks like the beginning of a subtype specification, but encountered an error somewhere inside the specification. Usually, other error messages in the vicinity will localize the problem. ═══ 16.1.35. GDSC0435 ═══ Expected a '-' to terminate syntactic extension severity: 4 The lexical analyzer found what looks like a syntactic extension termination, "%--", but found a wrong character in the indicated position. ═══ 16.1.36. GDSC0436 ═══ Illegal ANY_TABLE_REF severity: 4 The compiler found the keyword, ANY_TABLE_REF, but did not find the correct syntax following it. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of ANY_TABLE_REF. ═══ 16.1.37. GDSC0437 ═══ ANY_TABLE_REF, "Identifier", does not refer to an ANY_TABLE severity: 4 The referenced Identifier was to a definition of other than an ANY_TABLE. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax of ANY_TABLE_REF. ═══ 16.1.38. GDSC0438 ═══ "Identifier" is an illegal ANY_TABLE assignment severity: 4 The compiler found what looks like an ANY_TABLE assignment, but encountered syntax errors in the rest of the definition. Usually, other error messages in the vicinity will more closely pinpoint the problem. ═══ 16.1.39. GDSC0439 ═══ Illegal tag severity: 4 A tag construction was begun with a '[', but was not followed by valid syntax. Common causes are misspelled keywords for UNIVERSAL, etc., and missing ']'. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.40. GDSC0440 ═══ OBJECT IDENTIFIER value component "identifier" is not defined severity: 4 The identifier must be defined or imported into the ASN.1 module somewhere. It must also be defined as an OBJECT IDENTIFIER value. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.41. GDSC0441 ═══ OBJECT IDENTIFIER value conversion error -- compiler limitation severity: 4 The OBJECT IDENTIFIER has too many components in it for the compiler to handle. Contact the person maintaining the compiler. ═══ 16.1.42. GDSC0442 ═══ OBJECT IDENTIFIER value reference "identifier is invalid severity: 4 The referenced identifier is not a correctly defined OBJECT IDENTIFIER, causing a compilation error at this point. Other error messages should occur where the OBJECT IDENTIFIER identifier is defined. ═══ 16.1.43. GDSC0443 ═══ Incompatible value for the associated type at line l, column c severity: 4 The notations for the referenced type and value do not agree. For example, assigning TRUE to a value whose type is INTEGER causes this error. Check the allowed value notation for the data type in question. ═══ 16.1.44. GDSC0444 ═══ Implicitly tagging a CHOICE or ANY is illegal severity: 4 ASN.1 prohibits implicitly tagging a CHOICE or ANY data type. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the restrictions and requirements for tagging. ═══ 16.1.45. GDSC0445 ═══ "Identifier" is defined as a type, but it has an incompatible reference severity: 4 The type Identifier is defined as a type but it is referenced as something else, probably as an ANY_TABLE. ═══ 16.1.46. GDSC0446 ═══ "identifier" is already used in line l column c severity: 4 The identifier was used more than once in a context where the identifiers must all be unique. Specifically, distinct identifiers must be used within a single instance of: o CHOICE alternatives o INTEGER named numbers o ENUMERATED named numbers o SEQUENCE named component types o SET named component types o BIT STRING named bits o OBJECT IDENTIFIER value component names The same identifier can be used in different instances of the above types. ═══ 16.1.47. GDSC0447 ═══ The type referenced in the SelectionType is not a CHOICE severity: 4 The selection type is used to select one of the CHOICE type alternatives. It cannot be used to select types from other data types. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.48. GDSC0448 ═══ CHOICE alternative "identifier" is not found severity: 4 The identifier in the selection type does not reference a CHOICE alternative. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.49. GDSC0449 ═══ This tag must be distinct from the tag at line l, column c severity: 4 ASN.1 requires that tags be distinct in certain cases. A tag is the combination of a class (UNIVERSAL, APPLICATION, PRIVATE, or context sensitive) and a number. The data types that have distinct tag requirements are: o CHOICE o SET o SEQUENCE For example, the following are all illegal: A ::= CHOICE{ a INTEGER, b INTEGER} B ::= SET{ a INTEGER, b INTEGER} C ::= SEQUENCE{ a BOOLEAN, b INTEGER OPTIONAL, c INTEGER} D ::= CHOICE{ a E, b F} E ::= CHOICE{ e1 INTEGER, e2 BOOLEAN} F ::= CHOICE{ e1 INTEGER, e2 NULL} Since decoding a value requires matching the tags, any case where the same tag could be interpreted to refer to more than one type will cause a decoding failure. ═══ 16.1.50. GDSC0450 ═══ ANY cannot be used where distinct tags are necessary severity: 4 ASN.1 requires that tags be distinct in certain cases. A tag is the combination of a class (UNIVERSAL, APPLICATION, PRIVATE, or context sensitive) and a number. The ANY (and ANY DEFINED BY) data type has an indeterminate tag and so must not be used where distinct tags are required. The data types that require distinct tags are: o CHOICE o SET o SEQUENCE For example, the following are all illegal: A ::= CHOICE{ a ANY, b INTEGER} B ::= SET{ a ANY, b INTEGER} C ::= SEQUENCE{ a BOOLEAN, b INTEGER OPTIONAL, c ANY} Since decoding a value requires matching the tags, any case where the same tag could be interpreted to refer to more than one type will cause a decoding failure. ═══ 16.1.51. GDSC0451 ═══ Recursive CHOICE reference is illegal severity: 4 A CHOICE definition includes alternatives that eventually refer back to the CHOICE (the recursion) without tagging. This type of recursion cannot be resolved and so is illegal. For example, this is illegal: A ::= CHOICE{x B, y INTEGER} B ::= CHOICE{s A, t NULL} Not all recursions are illegal. For example, the following is legal: A ::= CHOICE{x B, y INTEGER} -- legal B ::= CHOICE{s [0] A, t NULL} -- legal ═══ 16.1.52. GDSC0452 ═══ YaccMessage severity: 4 The compiler encountered a syntax error, ran out of memory, or experienced some other problem which is indicated by YaccMessage. In the case of a parse error, the line and column number indicate exactly where the compiler detected an error. More explicit error messages should explain the nature of the error. ═══ 16.1.53. GDSC0453 ═══ This alternative is not found in the CHOICE type at line l, column c severity: 4 A CHOICE value was specified that referenced an alternative in a CHOICE defined at line l, column c., which was not found. This is usually caused by misspelling the CHOICE alternative name. ═══ 16.1.54. GDSC0454 ═══ Missing or illegal tag before "IMPLICIT/EXPLICIT" severity: 4 The keywords IMPLICIT and EXPLICIT must be preceded by a valid tag construction; they cannot appear without the tag construction. A tag is constructed with square brackets with one or more characters between them. The following is an illegal example: A ::= IMPLICIT INTEGER -- illegal This is a legal example: B ::= [0] IMPLICIT INTEGER -- legal See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.55. GDSC0455 ═══ This defined value for the named number/bit must refer to a number severity: 4 A named number or bit is defined by referencing another value that is not a number. For example, the following causes this error message: A ::= INTEGER{a(x), b(3)} x BOOLEAN ::= TRUE ═══ 16.1.56. GDSC0456 ═══ Named number/bit "identifier1" has the same value as "identifier2" severity: 4 The named numbers or bits associated with identifier1 and identifier2 have the same value. ASN.1 requires them to be unique. For example, the following syntax will cause this error message: A ::= INTEGER{a(x), b(3)} x INTEGER ::= 3 ═══ 16.1.57. GDSC0457 ═══ Imported symbol "symbol" must be exported from module "module" severity: 4 The symbol is in an IMPORTS list, but it does not appear in the EXPORTS list of the referenced module. Note that the absence of an EXPORTS clause in a module means everything in that module is considered to be exported. If a module has an EXPORTS clause with no symbols, that module is considered to export nothing. ═══ 16.1.58. GDSC0458 ═══ Illegal assigned object identifier reference for module "modulename" severity: 4 The object identifier value assigned to the module is incorrect. Another error message will more finely pinpoint the errors. ═══ 16.1.59. GDSC0459 ═══ Illegal numeric real value - extra component(s) severity: 4 The REAL numeric value has too many components; exactly three numbers are required. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.60. GDSC0460 ═══ Illegal numeric real value - missing exponent severity: 4 The REAL numeric value has only two components; exactly three numbers are required. The third component is the exponent. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.61. GDSC0461 ═══ Illegal numeric real value - missing base severity: 4 The REAL numeric value has only one component; exactly three numbers are required. The second component is the base. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.62. GDSC0462 ═══ Illegal numeric real value - missing mantissa severity: 4 The REAL numeric value has zero components; exactly three numbers are required. The first component is the mantissa. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.63. GDSC0463 ═══ Illegal numeric real value - the mantissa must be a signed number severity: 4 All three components of the numeric real number must be numbers. A common mistake is to use a reference to a number rather than the number itself. a REAL ::= {x, 2, 10} -- illegal reference x INTEGER ::= 42 See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.64. GDSC0464 ═══ Illegal numeric real value - the exponent must be a signed number severity: 4 All three components of the numeric real number must be numbers. A common mistake is to use a reference to a number rather than the number itself. a REAL ::= {12, 2, x} -- illegal reference x INTEGER ::= 42 See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.65. GDSC0465 ═══ The EXPORT clause must precede the IMPORTS clause severity: 4 The order of the IMPORT and EXPORT clauses is fixed by the ASN.1 standard. The IMPORTS clause, if it exists, comes after the EXPORTS clause. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.66. GDSC0466 ═══ Only one IMPORTS/EXPORTS clause is allowed per module severity: 4 The referenced IMPORTS or EXPORTS clause is not the only one of its kind in the module definition. All of the IMPORTED symbols must be collected into one IMPORTS clause, and likewise for EXPORTED symbols. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.1.67. GDSC0467 ═══ typename Type not valid for IBM General Data Stream Definitions Encoding severity: 4 The specified type is not supported by IBM GDSD. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a list of the GDSD supported ASN.1 built-in types. ═══ 16.1.68. GDSC0468 ═══ class Illegal Tag Class for IBM General Data Stream Definitions Encoding severity: 4 The specified class is not supported by IBM GDSD. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the GDSD supported tag classes. ═══ 16.1.69. GDSC0469 ═══ valuename Illegal Value for IBM General Data Stream Definitions Encoding severity: 4 The specified value is not supported by IBM GDSD. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a list of the GDSD supported ASN.1 values. ═══ 16.1.70. GDSC0470 ═══ Illegal GDS variable IDENTIFIER length: min '1', max '4' severity: 4 The length of the IDENTIFIER field of a GDS variable (the HexadecimalString of the tag specification) must be in the interval 1-4. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the GDSD tagged types. ═══ 16.1.71. GDSC0471 ═══ Illegal GDSUNIQUE value length, maximum length is '4' severity: 4 The UNIQUE value item cannot be more than 4 bytes long. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the GDSD tagged types. ═══ 16.1.72. GDSC0472 ═══ Illegal segment length:min 'minval', max 'maxval' severity: 4 The specified segment length is not valid. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the allowed range of values, depending on the segmentation type. ═══ 16.1.73. GDSC0473 ═══ Illegal segment prefix length, correct length is 'prfxlen' severity: 4 The segment prefix length is not valid. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the allowed range of values, depending on the segmentation type. ═══ 16.1.74. GDSC0474 ═══ Illegal classnum Class Number\n"}, severity: 4 The specified class number is not valid. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the GDSD tagged types. ═══ 16.1.75. GDSC0475 ═══ Illegal GDSLENGTH Class Number, maximum value is '4' severity: 4 The GDSLENGTH class number must be in the range 1-4. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the GDSLENGTH tag. ═══ 16.1.76. GDSC0476 ═══ If IBM GDS Definitions are used primitive ASN.1 type 'typename' must be tagged with a GDSD Tag Class severity: 4 If an ASN.1 built-in type, supported by GDSD, is tagged, the tag class must be one of the GDSD tag classes. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the allowed GDSD tag classes. ═══ 16.1.77. GDSC0477 ═══ Illegal GDSD Tag Class for the ASN.1 type "typename" severity: 4 There are specific constraints on the possible GDSD tag classes for the GDSD supported built-in types. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the allowed GDSD tag classes for each ASN.1 built-in type. ═══ 16.1.78. GDSC0478 ═══ The "classname" Tag Class requires the GDS IDENTIFIER value (i.e. the HexadecimalString of the tag specification) if it tags a "typename" element severity: 4 Some GDSD tag classes do not require the specification of the IDENTIFIER value (i.e. the HexadecimalString of the tag specification). However, when they tag specific types, the IDENTIFIER value must be specified. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the constraints on GDSD tagging for each ASN.1 built-in type. ═══ 16.1.79. GDSC0479 ═══ GDSD Lookahead offset outside the range:min 'minval', max 'maxval' severity: 4 The range of the look-ahead offset is 0-255. ═══ 16.1.80. GDSC0480 ═══ Illegal Tag Class "classname" for the "typename" element severity: 4 There are specific constraints on the possible GDSD tag classes for the component types of structured ASN.1 types (SET, SEQUENCE, and so on). See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the constraints on GDSD tagging of component types. ═══ 16.1.81. GDSC0481 ═══ Illegal Tag Class "GDSUNKNLT" for types requiring explicit IDENTIFIER or LENGTH severity: 4 GDSUNKNLT tag class do not require the specification of the IDENTIFIER value (the HexadecimalString of the tag specification) and LENGTH length. However, when it tags specific types the IDENTIFIER value and the LENGTH length must be specified. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for a description of the constraints on GDSD tagging for each ASN.1 built-in type. ═══ 16.1.82. GDSC0482 ═══ Illegal Tag Class "classname" for the "CHOICE" alternative severity: 4 There are specific constraints on the GDSD tagging of the CHOICE alternative types. ═══ 16.1.83. GDSC0483 ═══ The "classname" Tag Class requires the Class Number if it tags a "CHOICE" alternative severity: 4 There are specific constraints on the GDSD tagging of the CHOICE alternative types. ═══ 16.1.84. GDSC0484 ═══ More than one level of segmentation, or segmentation inside defined length GDS variable severity: 4 Only one level of segmentation is possible at a time. Moreover it is not possible define segmentation inside a type with a defined-length. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for more details about these constraints. ═══ 16.1.85. GDSC0485 ═══ If IBM GDS Definitions are used all types cannot be EXPLICIT tagged severity: 4 If GDSD is used, all the ASN.1 supported tagged types must be IMPLICIT tagged. ═══ 16.1.86. GDSC0486 ═══ Illegal look-ahead test-value length, maximum length is 'maxlen' severity: 4 The look-ahead test value cannot be longer than 4 bytes. ═══ 16.1.87. GDSC0487 ═══ Illegal GDS variable IDENTIFIER value: min '00'H, max '7FFFFFFF'H severity: 4 The IDENTIFIER value of a GDS variable (the HexadecimalString of the tag specification) can be 1 to 4 bytes long, and its value can be from '00'H to '7FFFFFFF'H. ═══ 16.1.88. GDSC0488 ═══ Illegal look-ahead test value: min '00'H, max '7FFFFFFF'H severity: 4 The look-ahead test value (the HexadecimalString of the tag specification) can be 1 to 4 bytes long, and its value can be from '00'H to '7FFFFFFF'H. ═══ 16.2. Warning Messages ═══ ═══ 16.2.1. GDSC0301 ═══ This alternative reference is to a CHOICE type defined in another module severity: 3 It is not good practice to refer to a CHOICE alternative that is defined in another module not in this source file. Since the compiler cannot perform the necessary checks to ensure the reference is correct, you should do so. ═══ 16.2.2. GDSC0302 ═══ External reference "Identifier" should be in IMPORTS list severity: 3 It is good practice to identify the imported symbols in the IMPORTS list of the module definition. See the General Data Stream Encoder/Decoder User's and Programmer's Guide manual for the correct syntax. ═══ 16.2.3. GDSC0303 ═══ Not in a syntactic extension - "%--" is out of context severity: 3 A termination of a syntactic extension, "%--" was found outside of a syntactic extension, that is , there is no matching "--%". Check to see that pairs of "--%" and "%--" match correctly. ═══ 16.2.4. GDSC0304 ═══ This tag is made EXPLICIT because it tags CHOICE/ANY type severity: 3 ASN.1 forces this tag to be EXPLICIT even though the default tagging for the module was IMPLICIT. If you intended this to be the case, better practice is to use the EXPLICIT keyword to make this clear. Note that ASN.1 prohibits the IMPLICIT keyword to be applied to CHOICE and ANY types. For example, these are illegal definitions: A ::= [0] IMPLICIT CHOICE{ a INTEGER, b NULL } B ::= [1] IMPLICIT ANY ═══ 16.2.5. GDSC0305 ═══ A comment inside a syntactic extension is not portable severity: 3 This compiler allows comments within a syntactic extension. However, since syntactic extensions are not standard ASN.1 notation, other ASN.1 compilers will interpret the comments incorrectly and will cause error messages. Specifically, standard ASN.1 compilers will interpret the syntactic introducer, "--%", as the start of a comment, and when they encounter a "--", they will terminate the comment. Then, your commentary will be parsed as though it were not an ASN.1 comment. For example, the following is likely to cause other compilers to interpret Foo as a type reference, which it isn't: --% -- Foo is a very useless name -- %-- ═══ 16.2.6. GDSC0306 ═══ Special character only allowed in syntactic extension severity: 3 The character at the line and column number is not a standard ASN.1 character and should only be used within a syntactic extension, for example, between --% and %--. This is a portability warning since other ASN.1 compilers are likely to balk at this character. ═══ 16.2.7. GDSC0307 ═══ A syntactic guard start, "--%", inside a syntactic extension is not portable severity: 3 The syntactic guard start, "--%", was found when another, previous syntactic guard is still in effect. This usually indicates unmatched syntactic guard start/end pairs. In this case, the extraneous syntactic guard start is ignored. ═══ 16.2.8. GDSC0308 ═══ This NamedType should have an identifier severity: 3 The current version of ASN.1 does not require named types to have an identifier, but future versions will. It is good practice to always use identifiers for named types because the some value notations and type notations are made unambiguous if the identifier is used. A named type is a type specification preceded by an optional identifier (which must begin with a lowercase letter). In the following example, foo INTEGER is the named type, "foo" is the identifier, and "INTEGER" is the type being named: A ::= SET{ foo INTEGER, fum BOOLEAN} ═══ 16.2.9. GDSC0309 ═══ No ".* asn.1 on" introducer was found severity: 3 The SCRIPT option was specified and the compiler was not able to find a single ASN.1 section in the source file. Hence no ASN.1 source was parsed. If the file is indeed a mixture of BookMaster/Script and ASN.1 source, you must add the ".* asn.1 on" and ".* asn.1 off" lines in the appropriate places. If the file only contains ASN.1 statements, you should probably not use the SCRIPT option. See GDSASN1 Compiler input for more information on the SCRIPT option. ═══ 16.2.10. GDSC0310 ═══ External reference "symbolname" should be exported from module "modulename" severity: 3 The external reference, symbolname, does not appear in an EXPORTS clause of the referenced module, modulename. Although this is not an error, better practice is to explicitly declare which symbols are imported and exported between modules. ═══ 16.2.11. GDSC0201 ═══ feature not supported at run-time severity: 2 The syntax is valid ASN.1. However, the information related to the feature is not carried over into the metatable output. This may or may not affect the way your encoding/decoding application works. You should check to ensure your program does not require this feature in this instance. ═══ 16.2.12. GDSC0202 ═══ Total length of symbols is symtablength; the maximum is maxsymtablength. severity: 2 The symbol table length exceeds the maximum symbol table length defined by the MAXSYMTABLEN (65535). ═══ 17. Appendix C. GDSTABLE Translator Return Codes and Messages ═══ ═══ 17.1. GDST0401 ═══ Incorrect table file version. Expected version. Found version. severity: 4 The versions of the ASN.1 Compiler and the GDSTABLE programs are not the same. ═══ 17.2. GDST0402 ═══ Symbol table is symtablength characters long. The maximum allowed is maxsymtablength defined by MAXSYMTABLEN (65535). severity: 4 The symbol table length exceeds the maximum symbol table length defined by the MAXSYMTABLEN (65535). ═══ 17.3. GDST0403 ═══ Metatable size is metatabsize long; the maximum is maxmetatabsize severity: 4 The metatable size exceeds the maximum metatable size defined by the MAXTOKTABLEN (65535). ═══ 17.4. GDST0404 ═══ Argument argument is unknown. severity: 4 The specified argument is unknown. ═══ 17.5. GDST0405 ═══ Error opening error output file, error_file. severity: 4 The specified error output file cannot be opened. ═══ 17.6. GDST0406 ═══ Error opening C output data file, C_data_file. severity: 4 The specified C output data file cannot be opened. ═══ 17.7. GDST0407 ═══ Error opening C output header file, C_header_file. severity: 4 The specified C output header file cannot be opened. ═══ 17.8. GDST0408 ═══ Error opening table input file, TBL_file. severity: 4 The specified table input file cannot be opened. ═══ 17.9. GDST0409 ═══ Error opening data output file, DAT_file. severity: 4 The specified data output file cannot be opened. ═══ 17.10. GDST0410 ═══ Internal error. severity: 4 Something is wrong in the TBL file. A not defined token type has been found by GDSTABLE program. Try to recompile the ASN.1 source to generate again the TBL file. ═══ 17.11. GDST0411 ═══ Error opening TEST TOOL output file, TST_TOOL_file. severity: 4 The specified output file that must contain the pre-formatted data for test tool cannot be opened. ═══ 17.12. GDST0412 ═══ Error allocating storage severity: 4 Some internal or system error occurred during the storage allocation. ═══ 18. Appendix D. GDSEDLIB Runtime Library Return Codes ═══ ┌──────────────────────────────┬─────────────────────────────────────────────┬─────┬──────────────────────────────┐ │Function Name │Return Code Name │RC │Meaning │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSaddmodule │ADDMODULE_OK │0 │The module was successfully │ │ │ │ │added. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ADDMODULE_DUP_MODULE │-1 │Another module with the same │ │ │ │ │name already exists in the │ │ │ │ │list of active modules in the │ │ │ │ │run-time environment. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSAllocateContentsArray │ALLOCATECONT_OK │0 │The contents-array was │ │ │ │ │successfully allocated. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ALLOCATECONT_NO_ENOUGH_STORAGE │-1 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ALLOCATECONT_INVALID_MODULE │-2 │The module is invalid. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSAllocateContListArray │ALLOCATECONTLIST_OK │0 │The array was successfully │ │ │ │ │allocated. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ALLOCATECONTLIST_NO_ENOUGH_STORAGE │-1 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSAllocateGdsTreeArray │ALLOCATEGDSTREE_OK │0 │The array was successfully │ │ │ │ │allocated. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ALLOCATEGDSTREE_NO_ENOUGH_STORAGE │-1 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ALLOCATEGDSTREE_INVALID_MODULE │-2 │The module is invalid. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │basetype │BASETYPE_OK │0 │The base type was successfully│ │ │ │ │found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │BASETYPE_WRONG_TOKEN │1 │In searching for the base │ │ │ │ │type, a metatoken was │ │ │ │ │encountered that shouldn't │ │ │ │ │have been there, indicating a │ │ │ │ │structural problem with the │ │ │ │ │metatable. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │BASETYPE_UNRESOLVED_EXTERN_REF │2 │In searching for the base │ │ │ │ │type, an unresolved external │ │ │ │ │reference was encountered. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSdecber │DECBER_OK │0 │The decoding process was │ │ │ │ │successful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECBER_SYNTAX_ERROR │-1 │A syntax error was encountered│ │ │ │ │in the buffer. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECBER_NO_ENOUGH_STORAGE │-2 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECBER_BUFFER_EMPTY │-3 │The input buffer is empty. │ │ │ │ │Probably the data stream is │ │ │ │ │not complete. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECBER_BUFFER_TOO_SMALL │-4 │The input buffer is too small,│ │ │ │ │it must be at least 150 bytes │ │ │ │ │long. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSdecgdsd │DECGDSD_NO_MATCH │1 │The decoded type does not │ │ │ │ │match the decoded data. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_MATCH │0 │The decode type matches the │ │ │ │ │decoded data. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_SYNTAX_ERROR │-1 │A syntax error was encountered│ │ │ │ │in the data. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INTERNAL_ERROR │-2 │An internal programming error │ │ │ │ │occurred. Probably something │ │ │ │ │is wrong in the Metatable. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_UNRESOLVED_REFERENCE │-3 │An unresolved external │ │ │ │ │reference was encountered. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_BUFFER_EMPTY │-4 │Other data must be decoded but│ │ │ │ │the reading user-exit does not│ │ │ │ │load other data in the buffer │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INVALID_ID │-5 │The decoded IDENTIFIER value │ │ │ │ │does not match the correct │ │ │ │ │value. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INVALID_UNIQUE_ITEM │-6 │The decoded unique item value │ │ │ │ │does not match the correct │ │ │ │ │value. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INVALID_LENGTH │-7 │The length of decoded data │ │ │ │ │does not match the correct │ │ │ │ │value. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_NO_ENOUGH_STORAGE │-8 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INVALID_SEG_ID_PREFIX │-9 │The decoded LL segment prefix │ │ │ │ │does not match the correct │ │ │ │ │value. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INVALID_SEG_SEQ_NUM │-10 │The decoded segment sequence │ │ │ │ │number is not correct. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_INVALID_SEG_IDF_PREFIX │-11 │The decoded LLIDFISS segment │ │ │ │ │prefix does not match the │ │ │ │ │correct value. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_LAST_SEG_BEFORE_EOD │-12 │Content data are segmentated │ │ │ │ │and the last segment indicator│ │ │ │ │indicates that this is the │ │ │ │ │last segment, but not all the │ │ │ │ │content data has been decoded.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │.DECGDSD_MISSING_MANDATORY_ELEMENT │-13 │A mandatory element of SET or │ │ │ │ │SEQUENCE type is missing. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_BUFFER_TOO_SMALL │-14 │The input buffer is too small,│ │ │ │ │it must be at least 300 bytes │ │ │ │ │long. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_USR_DEC_FUN_FAILED │-15 │The decoding user-exit failed.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECGDSD_SUBTYPE_CONSTRNTS_NO_MATCH │-16 │Decoded content data do not │ │ │ │ │match a sub-type constraint. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSdecode │DECODE_MATCH │0 │The GDS structure tree matches│ │ │ │ │the ASN.1 type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECODE_NO_MATCH │1 │The GDS structure tree does │ │ │ │ │not match the ASN.1 type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECODE_SYNTAX_ERROR │-1 │The GDS tree does not match │ │ │ │ │the ASN.1 type and │ │ │ │ │furthermore, some syntax error│ │ │ │ │has been detected, e.g. a │ │ │ │ │constructed INTEGER value. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECODE_INTERNAL_ERROR │-2 │An internal programming error │ │ │ │ │occurred. Probably something │ │ │ │ │is wrong in the Metatable. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECODE_UNRESOLVED_REFERENCE │-3 │An unresolved external │ │ │ │ │reference was encountered. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECODE_USR_DEC_FUN_FAILED │-4 │The decoding user-exit failed.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │DECODE_SUBTYPE_CONSTRNTS_NO_MATCH │-5 │Decoded content data do not │ │ │ │ │match a sub-type constraint. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSencber │ENCBER_OK │0 │The encoding process was │ │ │ │ │successful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_NO_ENOUGH_STORAGE │-1 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_GDSUSRWRT_FAILED │-2 │The writing user-exit failed. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_USER_EXIT_FAILED │-3 │The content user-exit failed. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_PRIM_TYPE_CONTENT_MISSING │-4 │No content data or incomplete │ │ │ │ │content data have been passed │ │ │ │ │for the primitive type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_INTERNAL_ERROR │-5 │An internal programming error │ │ │ │ │occurred. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_UNDEFLEN_NOT_PERMITTED │-6 │Indefinite length used for │ │ │ │ │primitive type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCBER_BUFFER_TOO_SMALL │-7 │The output buffer is too │ │ │ │ │small, it must be at least 150│ │ │ │ │bytes long. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSencgdsd │ENCGDSD_OK │0 │The encoding process was │ │ │ │ │successful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_INTERNAL_ERROR │-1 │An internal programming error │ │ │ │ │occurred. Probably something │ │ │ │ │is wrong in the GDS structure │ │ │ │ │tree. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_BUFFER_TOO_SMALL │-2 │The output buffer is too │ │ │ │ │small, it must be at least 9 │ │ │ │ │bytes long. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_GDSUSRWRT_FAILED │-3 │The writing user-exit failed. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_INVALID_CLASS │-4 │An invalid GDSD tag class was │ │ │ │ │found in a GDS structure. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_INVALID_FIXED_ITEM_LENGTH │-5 │An invalid length value was │ │ │ │ │found in the GDS structure │ │ │ │ │corresponding to a GDSFLEN │ │ │ │ │tagged type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_NO_ENOUGH_STORAGE │-6 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_INVALID_LENGTH │-7 │An invalid length value was │ │ │ │ │found in the GDS structure │ │ │ │ │corresponding to a GDSLENGTH │ │ │ │ │tagged type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_INVALID_LL_LENGTH │-8 │An invalid length value of the│ │ │ │ │LENGTH field was found in the │ │ │ │ │GDS structure corresponding to│ │ │ │ │a GDSLENGTH type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_UNDEFLEN_NOT_PERMITTED │-9 │A GDS structure with undefined│ │ │ │ │length was found, but │ │ │ │ │segmentation is not used. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_SEGMENT_TOO_SHORT │-10 │LLIDFISS segmentation is used │ │ │ │ │with a too short segment. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_PRIM_TYPE_CONTENT_MISSING │-11 │No content data or incomplete │ │ │ │ │content data have been passed │ │ │ │ │for the primitive type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_USER_EXIT_FAILED │-12 │The content user-exit failed. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCGDSD_NESTED_SEGMENT │-13 │Nesting of segmented types has│ │ │ │ │been found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSencode │ENCODE_MATCH │0 │The encode operation concluded│ │ │ │ │successfully. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_NO_MATCH │1 │The encoding operation │ │ │ │ │terminated unsuccessfully due │ │ │ │ │to a mismatch in the syntax of│ │ │ │ │the value to be encoded and │ │ │ │ │its related type. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_SYNTAX_ERROR │-1 │The encoding operation │ │ │ │ │terminated unsuccessfully due │ │ │ │ │to a syntax error. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INTERNAL_ERROR │-2 │An internal programming error │ │ │ │ │occurred. Probably something │ │ │ │ │is wrong in the Metatabel or │ │ │ │ │the encoding user-exit │ │ │ │ │supplies an empty sub-tree. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_UNRESOLVED_REFERENCE │-3 │An unresolved external │ │ │ │ │reference was encountered. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_GDSD_FIXED_LENGTH │-4 │A GDS structure corresponding │ │ │ │ │to a GDSFLEN tagged type has │ │ │ │ │an invalid length value │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_ENCODING_TYPE │-5 │The encoding type specified is│ │ │ │ │not valid (it can be: ber, or │ │ │ │ │gdsd or none). │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_UNDEFLENGTH_NOT_PERMITTED │-6 │Undefined length has been │ │ │ │ │passed for types tagged with │ │ │ │ │tag class requiring defined │ │ │ │ │length. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_LL_LENGTH │-7 │A GDSLENGTH tagged type has an│ │ │ │ │invalid length of the LENGTH │ │ │ │ │field. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_LENGTH │-8 │A GDS structure has a length │ │ │ │ │value that cannot be encoded │ │ │ │ │in the allowed LENGTH field. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_UNIQUE_ITEM_LENGTH │-9 │A GDS structure corresponding │ │ │ │ │to a GDSUNIQUE tagged type has│ │ │ │ │an invalid length. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_SEGMENT_LENGTH │-10 │A GDS structure corresponding │ │ │ │ │to a segmented type has an │ │ │ │ │invalid segment length. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_INVALID_NUMBER_OF_SSOF_ITEMS │-11 │The number of occurrences of │ │ │ │ │the SET OF or SEQUENCE OF │ │ │ │ │element, specified in the │ │ │ │ │corresponding entry of the │ │ │ │ │contents-array len field, is │ │ │ │ │not valid. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_DEFAULT_FUNCTION │-12 │The default encoding user-exit│ │ │ │ │has been invoked. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_MISSING_MANDATORY_ELEMENT │-13 │A mandatory element of SET or │ │ │ │ │SEQUENCE type has been not │ │ │ │ │encoded. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_NO_ENOUGH_STORAGE │-14 │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ENCODE_USER_EXIT_FAILED │-15 │Some problem occurred in the │ │ │ │ │encoding user-exit or it │ │ │ │ │didn't return the correct │ │ │ │ │parameters. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSfindtbl │FIND_TABLE_OK │0 │If the definition is found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │FIND_TABLE_FAIL │-1 │if no definition is found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSfindtype │FIND_TYPE_OK │0 │If the definition is found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │FIND_TYPE_FAIL │-1 │if no definition is found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSfindval │FIND_VALUE_OK │0 │If the definition is found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │FIND_VALUE_FAIL │-1 │If no definition is found. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSfirstmodule │FIRST_MOD_OK │0 │The active module list is not │ │ │ │ │empty and the modptr and the │ │ │ │ │modname pointers are not NULL.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │FIRST_MOD_FAIL │-5 │The active module list is │ │ │ │ │empty and the modptr and the │ │ │ │ │modname pointers are set to │ │ │ │ │NULL. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSinitEnvironment │INIT_ENV_OK │0 │Allocation and initialization │ │ │ │ │of run-time environment has │ │ │ │ │been performed. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │INIT_ENV_FAILED │-1 │Allocation and initialization │ │ │ │ │of run-time environment │ │ │ │ │failed, probably for some │ │ │ │ │storage allocation problem. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSINTEGERtolong │INTG2LNG_OK │0 │The conversion was successful.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │INTG2LNG_ERROR │-1 │The conversion was │ │ │ │ │unsuccessful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSlngs2OID │LNGS2OID_OK │0 │The conversion was successful.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │LNGS2OID_ERROR │-1 │The conversion was │ │ │ │ │unsuccessful. Reasons for │ │ │ │ │failure include an inadequate │ │ │ │ │output buffer or an invalid │ │ │ │ │component. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSlongtoINTEGER │LONG2INTEGER_OK │0 │The conversion was successful.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSnewgds │NEWGDS_OK │ │The new GDS structure has been│ │ │ │ │correctly allocated │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │NEWGDS_NO_ENOUGH_STORAGE │ │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSOIDtolngs │OID2LNGS_OK │0 │The conversion was successful.│ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │OID2LNGS_ERROR │-1 │The conversion was │ │ │ │ │unsuccessful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSprintgds │PRINT_GDS_OK │0 │The print operation was │ │ │ │ │successful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │PRINT_GDS_ERROR │-1 │The print operation was │ │ │ │ │unsuccessful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │PRINT_GDS_NO_ENOUGH_STORAGE │ │Some problem occurred during │ │ │ │ │storage allocation. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSPrintUnresolvedImports │PRTUNRES_OK │0 │The print operation was │ │ │ │ │successful. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │PRTUNRES_BAD_FILE │-1 │The print operation was │ │ │ │ │unsuccessful because of a │ │ │ │ │unusable file descriptor │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSreaddatfile │READ_DAT_OK │0 │The DAT file was successfully │ │ │ │ │read into the run-time │ │ │ │ │environment. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │READ_DAT_OPEN │-3 │An error occurred in opening │ │ │ │ │the file. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │READ_DAT_VERSION │-4 │The DAT file has version │ │ │ │ │number incompatible with the │ │ │ │ │run-time library. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │ADDMODULE_DUP_MODULE │-1 │A duplicate module was found │ │ │ │ │already loaded into the │ │ │ │ │run-time environment. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSresolveallimports │RESOLVE_IMPORTS_OK │0 │All imported symbols were │ │ │ │ │resolved │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │UNRESOLVED_REFERENCE │-2 │One of the imported symbols │ │ │ │ │could not be resolved amongst │ │ │ │ │the active modules. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSresolveimports │RESOLVE_IMPORTS_OK │0 │All imported symbols were │ │ │ │ │resolved. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │UNRESOLVED_REFERENCE │-2 │One of the imported symbols │ │ │ │ │could not be resolved amongst │ │ │ │ │the active modules. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │GDSunloadmodule │UNLOAD_MOD_OK │0 │The module was successfully │ │ │ │ │unloaded. │ ├──────────────────────────────┼─────────────────────────────────────────────┼─────┼──────────────────────────────┤ │ │UNLOAD_MOD_NOT_FOUND │-6 │The module was not found among│ │ │ │ │the list of active modules. │ └──────────────────────────────┴─────────────────────────────────────────────┴─────┴──────────────────────────────┘ ═══ 19. Appendix E. Type Declarations ═══ This section lists all the GenE/D type declarations that must be known by the User Agent Program. /********************************************************************* * The following identifies the ASN.1 base types ********************************************************************* */ enum basetypes { bas_unknown, /* 0 unknown */ bas_integer, /* 1 integer */ bas_choice, /* 2 choice */ bas_boolean, /* 3 boolean */ bas_null, /* 4 null */ bas_bitstr, /* 5 bit string */ bas_octstr, /* 6 octet string */ bas_seqenum, /* 7 sequence{...} */ bas_seqof, /* 8 sequence of ... */ bas_setenum, /* 9 set{...} */ bas_setof, /* 10 set of ... */ bas_any, /* 11 any */ bas_objid, /* 12 object identifier */ bas_real, /* 13 real */ bas_enum, /* 14 enumerated */ bas_charstr, /* 15 character string type */ bas_anytbl, /* 16 any defined by table */ bas_expltag /* 17 explicit encoded type */ }; /* basetypes */ /************************************************************************ * Tag classes. The ones beginning with "GDS" are not ASN.1 standard, * they can be used if IBM GDS Definition encoding is used. ************************************************************************ */ enum tagclass { cont, /* CONTEXT SPECIFIC - only BER */ univ, /* UNIVERSAL - BER and GDSD */ appl, /* APPLICATION - only BER */ priv, /* PRIVATE - only BER */ gdstl, /* GDSTL - only GDSD */ gdslt, /* GDSLT - only GDSD */ gdssegiss, /* GDSSEGISS - only GDSD */ gdssegll, /* GDSSEGLL - only GDSD */ gdslen, /* GDSLENGTH - only GDSD */ gdsuniq, /* GDSUNIQUE - only GDSD */ gdsflen, /* GDSFLEN - only GDSD */ gdsuntil, /* GDSOccursUntilLKAHD - only GDSD */ gdswhen, /* GDSOccursWhenLKAHD - only GDSD */ gdswhile, /* GDSOccursWhileLKAHD - only GDSD */ gdsunkn, /* GDSUNKNLT - only GDSD */ noclass /* class not specified, error situations */ }; /* tagclass */ /************************************************************************ * Type of encoding. Used by GDSencode routine, in order to do correctly * some encoding decision, and by GDSprintgds routine in order to * print correctly the GDS structure tree. ************************************************************************ */ enum TypOfEnc { ber, /* Basic Encoding Rules */ gdsd, /* IBM General Data Stream Definitions */ none /* the lengths are not calculated by encode, * useful if other encoding rules are used */ }; /************************************************************************ * Storage class: dynamic or static ************************************************************************ */ enum stg { stat, /* static - not subject to reclaimation */ allocd /* allocated - subject to reclaimation */ }; /************************************************************************ * Status of GDS, used during BER decoding of SET type ************************************************************************ */ enum setstat { /* set element status */ matched, /* GDS is matched in the set element */ unmatched /* GDS is unmatched */ }; /************************************************************************ * Form of type: primitive or constructor ************************************************************************ */ enum frm { prim, /* primitive form */ constr /* constructor form */ }; /************************************************************************ * Last piece of data indicator, used if the content data is passed * using an user exit. ************************************************************************ */ enum lastflag { NO, /* this is not last piece of data */ YES /* this is last piece of data */ }; /************************************************************************ * User exit for passing the content data ************************************************************************ */ #define usr_cont_exit\ int (*usrcontent) (char **buff, unsigned long *buflen, enum lastflag *lastf) /************************************************************************ * Segment structure, used in case of IBM GDSD segmentation ************************************************************************ */ struct segment { unsigned long seg_len; /* length of the segment */ char *seg_content; /* segment content data */ struct segment *next_seg; /* pointer to the next segment. * NULL if it is the last */ }; /************************************************************************ * GDS structure ************************************************************************ */ struct gds { enum tagclass cls; /* class */ unsigned long id; /* identifier number */ enum frm form; /* primitive or constructed */ long loc; /* length of CONTENTS field */ long log; /* length of GDS */ int basetype; /* base type of GDS */ char *modname; /* module name pointer */ char *name; /* type/value name pointer */ char *sop; /* address of start of GDS */ char *contents; /* address of contents */ struct gds *next; /* sibling ptr */ struct gds *contains; /* contained GDSs */ struct gds *parent; /* parent (containing) GDS */ enum stg gdsstg; /* storage class for GDS structure */ enum stg contstg; /* storage class for GDS contents field */ enum setstat sstat; /* set element matching status */ unsigned long id_seg_len; /* the maximum length of the segment * or the IDENTIFIER length */ usr_cont_exit; /* the pointer to the user exit called by */ /* GDSencgdsd and GDSencber routines to get */ /* the data that must be encoded. It could */ /* be used in case of GDSD segmentation */ struct segment *seg_list; /* pointer to a list of segments. It is set * by GDSdecgdsd function if decoding user-exit * is not used and content data are segmented */ }; /************************************************************************ * The following are structures to pass during the GDS tree walking * process for encoding. ************************************************************************ */ struct encinh { /* inherited attributes */ struct ietag *it; /* points to the structure containing * the information of implicit tagging if * the type is implicit tagged */ char *symname; /* name of the current item to encode */ char *modname; /* current module name */ void *module_ptr; /* module for type to encode */ void *usrparms; /* user parms */ char opt; /* TRUE if item is optional or defaulted, FALSE if mandatory */ }; struct encinhsyn { /* inherited and synthesized attributes */ struct gds *p; /* the GDS structure allocated fo the type */ unsigned short ndx; /* Metatable index of the type encoded */ enum basetypes base; /* base type of GDS */ long ssof_items_num; /* num of items inside a SET OF or SEQ OF */ }; /************************************************************************ * Indicates if LLIDFISS segmentation is used. The UAP can decide, * calling GDSencgdsd function, if it wants to use LLIDFISS segmention * or not. ************************************************************************ */ typedef enum { nouse, /* segmentation is not used */ use /* the LLIDFISS segmentation is used */ } useLLIDFISS; /************************************************************************ * Used by GDSdecgdsd function to return to the UAP information * about decoding errors. ************************************************************************ */ struct errdata { void *err_item; /* item in error */ int err_item_len; /* length of item in error */ }; /************************************************************************ * contents structures, used by UAP to pass content data to GDSencode * function instead of encoding user-exit mechanism ************************************************************************ */ struct contents_str { char *content; /* content data */ usr_cont_exit; /* content user exit */ struct content_str *contlist; /* list of contents, used for SET OF and * SEQUENCE OF */ enum stg contstg; /* storage class */ long len; /* content length (number of bytes), or * number of contents in contlist */ }; struct content_str { char *content; /* content data */ usr_cont_exit; /* content user exit */ enum stg contstg; /* storage class */ long len; /* content length (number of bytes) */ }; ┌────────────────────────────────────────────┐ │ │ │ │ │ End of Document │ │ │ │ │ └────────────────────────────────────────────┘ ═══ ═══ This edition applies to the Release 1 of General Data Stream Encoder/Decoder, program number 5648-075 and to all subsequent releases and modifications until otherwise indicated in new editions or technical newsletters. ═══ ═══ Copyright International Business Machines Corporation 1993. All rigths reserved. ═══ ═══ The ? option causes syntax help information to be displayed. ═══ ═══ The source-file specifies the path and filename for the ASN.1 input file. The default is the standard input file, which is normally the console. If input is from the console, remember that you indicate the end of file condition by typing control D ═══ ═══ The -e option specifies the output file for error messages. The error-file option, if specified, identifies the path and file name for the output file. The default error output is directed to the standard output file, which is normally the console. The standard output file is also indicated by the absence of error-file. ═══ ═══ The -t option specifies the output file for the metatable data in the TBL format. The tbl-file parameter indicates the path and filename for the output file. The default for this option is to produce no TBL definitions. ═══ ═══ The -script option specifies that the input file contains Script or BookMaster* formatting controls. ═══ ═══ The -noscript option specifies that the input file does not contain Script or BookMaster formatting controls. Click here for more information about processing the input file. ═══ ═══ The -gdsd option specifies that the input ASN.1 file can contain GDSD extensions to the standard ASN.1 language and that the GDSD limitations must be checked. These extensions are useful if IBM GDS Definitions encoding is used. Click here for more information about GDSD extensions of ASN.1. ═══ ═══ The -nogdsd option specifies that the input ASN.1 file cannot contain GDSD extensions to the standard ASN.1 language, (this is the default). If the extensions are used syntax errors are issued. Click here for more information about GDSD extensions of ASN.1. ═══ ═══ The -w option sets the minimum message warning level. Values range from 1 to 4, and the default is 3. Level 4 messages are considered errors and cannot be suppressed. ═══ ═══ The -d option turns on debugging information for the compiler. The output is sent to the debug-file, if it is specified. If debug-file is not specified, the output is directed to standard output (stdout). ═══ ═══ The ? option causes syntax help information to be displayed. ═══ ═══ The source-file specifies the path and filename for the ASN.1 input file. The default is the standard input file, which is normally the console. If input is from the console, remember that you indicate the end of file condition by typing control Z ═══ ═══ The /e option specifies the output file for error messages. The error-file option, if specified, identifies the path and file name for the output file. The default error output is directed to the standard output file, which is normally the console. The standard output file is also indicated by the absence of error-file. ═══ ═══ The /t option specifies the output file for the metatable data in the TBL format. The tbl-file parameter indicates the path and filename for the output file. The default for this option is to produce no TBL definitions. ═══ ═══ The /script option specifies that the input file contains Script or BookMaster formatting controls. ═══ ═══ The /noscript option specifies that the input file does not contain Script or BookMaster formatting controls. Click here for more information about processing the input file. ═══ ═══ The /gdsd option specifies that the input ASN.1 file can contain GDSD extensions to the standard ASN.1 language and that the GDSD limitations must be checked. These extensions are useful if IBM GDS Definitions encoding is used. Click here for more information about GDSD extensions of ASN.1. ═══ ═══ The /nogdsd option specifies that the input ASN.1 file cannot contain GDSD extensions to the standard ASN.1 language (this is the default). If the extensions are used syntax errors are issued. Click here for more information about GDSD extensions of ASN.1. ═══ ═══ The /w option sets the minimum message warning level. Values range from 1 to 4, and the default is 3. Level 4 messages are considered errors and cannot be suppressed. ═══ ═══ The /d option turns on debugging information for the compiler. The output is sent to the debug-file, if it is specified. If debug-file is not specified, the output is directed to standard output (stdout). ═══ ═══ The tblfile file is in the TBL. format and serves as input to GDSTABLE. The tblfile is one of the output files of the GDSASN1 Compiler. ═══ ═══ The datfile file is the output of GDSTABLE. and it serves as input to the applications which perform the encoding/decoding functions. ═══ ═══ The /c option specifies the output file for the C language Metatable definitions. The c-file parameter indicates the path and filename for the output file. The default for this option is to produce no C language definitions. ═══ ═══ The /h option specifies the output file for the C language header definitions. The h-file parameter indicates the path and filename for the output file. The default for this option is to produce no C language header definitions. ═══ ═══ The /e option specifies the output file for the error messages. The default is the standard output. ═══ ═══ The /s option specifies the output file for the pre-formatted input file for the Test Tool. ═══ ═══ The tblfile file is in the TBL. format and serves as input to GDSTABLE.. The tblfile is one of the output files of the GDSASN1 Compiler. ═══ ═══ The datfile file is the output of GDSTABLE. and it serves as input to the applications which perform the encoding/decoding functions. ═══ ═══ The /c option specifies the output file for the C language Metatable definitions. The c-file parameter indicates the path and filename for the output file. The default for this option is to produce no C language definitions. ═══ ═══ The /h option specifies the output file for the C language header definitions. The h-file parameter indicates the path and filename for the output file. The default for this option is to produce no C language header definitions. ═══ ═══ The /e otpion specifies the output file for the error messages. The default is the standard output. ═══ ═══ The /s option specifies the output file for the pre-formatted input file for the Test Tool.