|
|
1.1 ! root 1: .NS 2 ! 2: The structure and meaning of the tables generated from the ASN.1 grammar ! 3: .XS ! 4: The structure and meaning of the tables generated from the ASN.1 grammar ! 5: .XE ! 6: .PP ! 7: Each collection of \fBASN.1\fR grammar is called a module. ! 8: (See ! 9: .[ ! 10: ASN.1 ! 11: .] ! 12: ) ! 13: Each \fBASN.1\fR module is completely specified in the program by a ! 14: single \fBC\fR structure of type \fBmodtyp\fR and the data which it references. ! 15: See the \fIpepdefs.h\fR file in the \fIpepsy\fR directory. ! 16: For each \fBASN.1\fR module ! 17: there are three tables that are generated from\fBASN.1\fR grammar. ! 18: These initialised arrays which we call tables are ! 19: called the encoding, decoding and printing tables. ! 20: Each of these tables is referenced through a different pointer ! 21: of the \fBmodtyp\fR structure. ! 22: .PP ! 23: Each of these pointers references an array of pointers, ! 24: one pointer for each \fBASN.1\fR type defined in the module. ! 25: The position of one of these pointers is the unique type number we give to ! 26: its corresponding type. ! 27: The pointer references an array of type \fBtpe\fR or \fBptpe\fR, depending ! 28: whether it is an entry in the decoding/encoding tables or printing tables ! 29: respectively. ! 30: See \fIpep.h\fR in the \fIpepsy\fR directory. ! 31: This array actually contains the necessary information to encode/decode/print ! 32: that \fBASN.1\fR type. ! 33: So given the \fBmodtyp\fR structure of an \fBASN.1\fR module and its ! 34: type number you can call a routine to encode, decode or print that type. ! 35: .PP ! 36: The rest of this document assumes a good knowledge of \fBASN.1\fR notation ! 37: so go read a copy if you haven't already. ! 38: From here on I shall mention only \fBtpe\fR and this means \fBtpe\fR in the ! 39: case of encoding or decoding and \fBptpe\fR in the case of printing, unless ! 40: otherwise stated. ! 41: Each type is represented by an array of \fBtpe\fR (or \fBptpe\fR for printing). ! 42: The basic element consists of four integer fields, ! 43: the printing table is the same with an addition \fBchar\fR pointer field which ! 44: contains the name corresponding to that entry in the \fBASN.1\fR grammar. ! 45: The first specifies the type of the entry and determines how the ! 46: rest are interpreted. ! 47: The possible types are listed in \fIpepsy/pep.h\fR. ! 48: Each type is an array which starts with an entry of type \fBPE_START\fR ! 49: and ends with one of type \fBPE_END\fR. ! 50: Each primitive type requires one entry to specify it, ! 51: apart from possible \fBPE_START\fR and \fBPE_END\fR used to specify the start ! 52: and end of the type. ! 53: Constructed types are represented by a list of entries terminated by an ! 54: entry of type \fBPE_END\fR. ! 55: As \fBASN.1\fR types can be nested inside so will the ! 56: representation in \fBtpe\fR entries be nested. ! 57: For example the \fBASN.1\fR type definition: ! 58: .nf ! 59: Example1 ::= ! 60: SEQUENCE { ! 61: seq1 SEQUENCE { ! 62: an-i INTEGER, ! 63: an-ostring OCTET STRING ! 64: }, ! 65: a-bool IMPLICIT [0] BOOLEAN ! 66: } ! 67: .fi ! 68: .ce 1 ! 69: Will generate an encoding array: ! 70: .nf ! 71: static tpe et_Example1Test[] = { ! 72: { PE_START, 0, 0, 0 }, ! 73: { SEQ_START, 0, 16, FL_UNIVERSAL }, ! 74: { SEQ_START, OFFSET(struct type_Test_Example1, seq1), 16, FL_UNIVERSAL }, ! 75: { INTEGER, OFFSET(struct element_Test_0, an__i), 2, FL_UNIVERSAL }, ! 76: { OCTETSTRING, OFFSET(struct element_Test_0, an__ostring), 4, FL_UNIVERSAL }, ! 77: { PE_END, 0, 0, 0 }, ! 78: { BOOLEAN, OFFSET(struct type_Test_Example1, a__bool), 0, FL_CONTEXT }, ! 79: { PE_END, 0, 0, 0 }, ! 80: { PE_END, 0, 0, 0 } ! 81: }; ! 82: ! 83: .fi ! 84: .PP ! 85: Here the second last \fBPE_END\fR matches and closes off the ! 86: first \fBSEQ_START\fR. ! 87: The entries which correspond to the other primative types are pretty ! 88: obvious, with the INTEGER entry corresponding to the primative INTEGER. ! 89: For fields that generate data the general interpretation of the other three ! 90: fields is offset, tag and flags/class fields respectively. ! 91: .IP offset ! 92: The second field gives the offset in a \fBC\fR data structure ! 93: needed to reference the data that corresponds to this table entry. ! 94: Each \fBASN.1\fR type has \fBC\fR structure types generated as described in ! 95: the ! 96: .[ ! 97: ISODE ! 98: .] ! 99: manuals, volume 4 "The applications Cookbook" Section 5.2, ! 100: "POSY Environment". ! 101: As this offset may have to be determined in a compiler dependent manner ! 102: a \fBC\fR preprocessor macro is used hide the actual details. ! 103: .IP tag ! 104: This is the tag associated with the \fBASN.1\fR type for that entry. ! 105: Notice that in the example the [0] IMPLICIT which changes the tag ! 106: associated with the BOOLEAN entry actually has the correct tag of 0 in the ! 107: table. ! 108: Likewise SEQUENCE has the correct tag of 16 in its \fBSEQ_START\fR entry ! 109: and so on for the others. ! 110: .IP flags/class ! 111: This contains the \fBASN.1\fR class associated with the entry's type. ! 112: That is UNIVERSAL for all except the BOOLEAN type which is CONTEXT class. ! 113: This fourth can also contain flags that specify if the type is OPTIONAL ! 114: or DEFAULT. ! 115: There is plenty of room here as there is only four possibly classes. ! 116: .PP ! 117: Now that you have some idea of how these arrays are arranged for a type ! 118: definition I will proceed to go through the possible type of ! 119: entries and describe what they do and how they work. ! 120: These values are defined in \fIpepsy/pep.h\fR. ! 121: Those entries with a value below \fBTYPE_DATA\fR are entries that ! 122: don't correspond to data to be encoded/decoded and are for other book keeping ! 123: type purposes. ! 124: .IP "PE_START and PE_END" ! 125: As explained above \fBPE_START\fR starts the beginning of a \fBASN.1\fR type's ! 126: array. ! 127: It probably isn't necessary but the size of the tables is so small it isn't ! 128: much of an over head to keep around for cosmetic reasons. ! 129: The entry type \fBPE_END\fR is necessary to mark the end of some ! 130: compound type as well as the end of \fBASN.1\fR data type. ! 131: .IP "XOBJECT and UCODE" ! 132: These are obsolete types and probably should be removed. ! 133: They were to allow \fBC\fR code written directly by the user to be incorporated ! 134: into the encoding/decoding but it was found unnecessary. ! 135: Prehaps some brave soul would like to use them in an attempt to implement ! 136: a similar system based on \fIpepy\fR which is what we first attempted to ! 137: do until we found this to be much easier. ! 138: .IP MALLOC ! 139: This field only occurs in the decoding tables. ! 140: It specifies how much space to malloc out for the current \fBC\fR structure ! 141: it is just inside of. ! 142: For instance in the example above the decoding table has the following entry: ! 143: .DS C ! 144: { MALLOC, 0, sizeof (struct type_Test_Example1), 0 }, ! 145: .DE ! 146: just after the first \fBSEQ_START\fR entry. ! 147: It tells it to \fBmalloc\fR out a \fBstruct type_Test_Example1\fR structure ! 148: to hold the data from the sequence when it is decoded. ! 149: .IP SCTRL ! 150: This entry is used in handling the \fBASN.1\fR CHOICE type. ! 151: The \fBC\fR type generated for \fBASN.1\fR CHOICE type is a structure with ! 152: an offset field in it and a ! 153: union of all the \fBC\fR types present in the CHOICE. ! 154: Each \fBASN.1\fR type in the CHOICE of types has a \fBC\fR type definition ! 155: generated for it. ! 156: The union is of all these types, which is quite a logical way to implement ! 157: a CHOICE type. ! 158: The offset field specifies which possibility of interpreting the union ! 159: should be used (which \fImember\fR should selected). ! 160: As such it needs to be read by the encoding routines ! 161: when encoding the data from the \fBC\fR data structures ! 162: and to be set by the decoding routines when it is decoding the data into ! 163: the \fBC\fR data structures. ! 164: There is one such entry for each \fBCHOICE\fR type to specify where the ! 165: offset field is. ! 166: .IP CH_ACT ! 167: Another redundant entry type. ! 168: I think this was also used in code to handle \fBC\fR statements or ! 169: actions specified by the user. ! 170: It probably should be removed. ! 171: .IP OPTL ! 172: This is used to handle the optionals field that is generated by ! 173: \fBposy\fR when optional types that are \fInot\fR implemented by pointers ! 174: are present in the \fBASN.1\fR type. ! 175: For example if an \fBASN.1\fR type has an optional integer field how ! 176: does the encoding routine determine if the integer is to be ! 177: present or not? ! 178: If it was implemented as a pointer it could use a \fBNULL\fR (zero) pointer ! 179: to mean that the type was not present because ! 180: NULL is guaranteed to never occur as a legal pointer to a real object. ! 181: But all the possible values for integer could be legally passed so ! 182: instead for these types which are not pointers and are optional ! 183: a bit map is allocated in the structure. ! 184: Each non pointer optional type a bit from the bit map is ! 185: allocated. ! 186: .PP ! 187: If that bit is set the corresponding type is present and it is not ! 188: present if the bit is not set. ! 189: Each bit has a \fB#define\fR generated for it. ! 190: The bit map is merely an integer field called "\fBoptionals\fR" limiting ! 191: maximum number of such optionals to 32 on Sun machines, 16 on some others. ! 192: (An array of \fBchar\fR as BSD fd_sets would have avoid all such limits, ! 193: not that this limit is expected to be exceeded very often !) ! 194: Like the \fBSCTRL\fR entry this entry merely serves to specify where ! 195: this field is so it can be test and set by the encoding and decoding routines ! 196: respectively. ! 197: .IP "ANY and CONS_ANY" ! 198: The \fBC\fR type corresponding to the entry is a \fBPE\fR pointer. ! 199: To conform with \fIpepy\fR the tag and class of this entry are ignored, ! 200: which may or may not be the most sensible thing. ! 201: The \fBCONS_ANY\fR is a redundant symbol which means the same thing but ! 202: is not used. ! 203: This should be clean up and removed. ! 204: .IP "INTEGER, BOOLEAN, BITSTRING, OCTETSTRING and OBJID" ! 205: These are just as described in the first article. ! 206: See the ISODE manual to find out what they are allocated as a \fBC\fR data ! 207: type to implement them. ! 208: The offset fields says where to find this data type with in the current ! 209: structure. ! 210: .IP "SET_START, SETOF_START, SEQ_START and SEQOF_START" ! 211: These compound entries differ from the above in that they group all ! 212: the following entries together up to the matching \fBPE_END\fR. ! 213: The entries with \fBOF\fR in them correspond to the \fBASN.1\fR types ! 214: which have \fBOF\fR in them ! 215: e.g. \fBSET OF\fR. ! 216: Allowing the \fBOF\fR items to have an arbitrary number of entries is ! 217: excessive flexibility, they can only have one type by the \fBASN.1\fR grammar ! 218: rules. ! 219: The \fBC\fR data type corresponding to them is either a structure if ! 220: it is the first such type in the array or a pointer to a structure ! 221: is isn't. ! 222: This complicates the processing of these structures a little but not greatly. ! 223: The \fBOF\fR types differ one other important way, ! 224: they may occur zero, one or more times, with no upper bound. ! 225: To cope with this the \fBC\fR data type is a linked list structure. ! 226: The pointer to the data structure determines whether or not there is another ! 227: occurrence of the type, if it is NULL there isn't. ! 228: Thus each data structure has this pointer to the next occurrence, the offset of ! 229: this pointer is placed in the \fBPE_END\fR field where it can conveniently ! 230: be used to determine whether or not to make another pass through the ! 231: table entry. ! 232: .IP OBJECT ! 233: When one type references another it generates an \fBOBJECT\fR entry. ! 234: This specifies the type number of the type ! 235: which is present in the 3rd field of the \fBtpe\fR structure, ! 236: \fBpe_tag\fR. ! 237: The 2nd field still gives the offset in the \fBC\fR data structure ! 238: which specifies where the user's data for that type is to be found. ! 239: Usually this a pointer to the \fBC\fR data structure for that type. ! 240: .IP T_NULL ! 241: This entry means the \fBASN.1\fR primative type \fBNULL\fR. ! 242: It doesn't have any body and consequently has no offset as it cannot ! 243: carry data directly. ! 244: Only its absence or presence can mean anything so if it is optional it sets or ! 245: clears a bit in the bit map as described earlier for \fBOPTL\fR entry. ! 246: .IP T_OID ! 247: This use to be used for Object Identifiers and now is unused, ! 248: it should be got rid. ! 249: .IP OBJID ! 250: This corresponds to the Object Identifier \fBASN.1\fR type primitive. ! 251: It is implemented the same as other primative types like \fBINTEGER\fR ! 252: and \fBOCTET STRING\fR. ! 253: .IP ETAG ! 254: This entry gives the explicit tag of the following entry. ! 255: The usual fields which define class and tag are the only ones which have ! 256: meaning in this entry. ! 257: By concatenating successive \fBETAG\fR entries it is possibly to build up ! 258: an limited number explicit tags, although this hasn't been tested yet. ! 259: .IP IMP_OBJ ! 260: If a type has an implicit tag usually all we have to do is set its tag ! 261: and class appropriately in its entry. ! 262: This works for all but one important case, the reference of another type. ! 263: This is messy because we can't alter the definition of the type with out ! 264: wrecking it for the other uses. ! 265: So what we do for encoding is build the type normally ! 266: and then afterward it is built ! 267: change its tag and class to be the values we want. ! 268: Similarly for decoding we match the tag and class up and then decode the body ! 269: of the type. ! 270: We can't use a \fBOBJECT\fR entry for this because among other ! 271: reasons there 3rd field is already to store the type number. ! 272: (The forth needs to be free to contain flags such as \fBDEFAULT\fR ! 273: and \fBOPTIONAL\fR) ! 274: So a new entry type is used, \fBIMP_OBJ\fR, to hold the tag and class. ! 275: It must be followed by an \fBOBJECT\fR entry which is used to handle the type ! 276: as normal, the \fBIMP_OBJ\fR entry gives the tag and class to be used. ! 277: Like the \fBETAG\fR entry the \fBIMP_OBJ\fR affects the entry that follows it. ! 278: .IP "EXTOBJ and EXTMOD" ! 279: These handle external type references. ! 280: This is just like a normal (internal?) type reference except we must now ! 281: specify which module as well as the type. ! 282: Similarly because there are no more free fields in the \fBOBJECT\fR type ! 283: we need two entries to hold all the information we need. ! 284: The \fBEXTMOD\fR occurs first and holds the type number and the offset ! 285: into the \fBC\fR data structure and the flags, exactly as for an \fBOBJECT\fR ! 286: entry. ! 287: The next entry, which must be an \fBEXTMOD\fR, contains a pointer to ! 288: the \fBmodtyp\fR structure for its module. ! 289: Like a normal \fBOBJECT\fR entry to handle the case of an implicit tag ! 290: an \fBIMP_OBJ\fR entry would occur before these two entries which gives ! 291: the class and tag. ! 292: Likewise it could have an explicit tag in which the two entries ! 293: would be proceeded by an \fBETAG\fR entry. ! 294: .IP "DFLT_F and DFLT_B" ! 295: When a type has a default value, to handle decoding and encoding properly you ! 296: need to know its value. ! 297: As there is no space to store the value in most entries we allocate a whole ! 298: entry to specify the value. ! 299: When encoding it is convenient to have the default occur before the entry it ! 300: refers to. ! 301: This allows a single check to handle all the default encoding. ! 302: All it has to do is check whether it is the same as the default value and if so ! 303: not bother encoding the next type. ! 304: On the other hand when decoding it is more convenient to have ! 305: the entry after the ! 306: one it refers to. ! 307: In this case we need to determine that it is missing before we use the default ! 308: value to determine the value to pass to the user. ! 309: To handle this we have entries of both types. ! 310: .B DFLT_F ! 311: contains the default value for the following entry (F = Front) ! 312: and \fBDFLT_B\fR contains that for the entry before it (B = Back). ! 313: Consequently \fBDFLT_F\fR are only used in the decoding tables ! 314: and \fBDFLT_B\fR entries are only used in the decoding (and printing tables). ! 315: .IP S-Types ! 316: These types are entries for the same \fBASN.1\fR type as the entry type ! 317: formed by removing the starting `S'. ! 318: The above forms would do to handle \fBASN.1\fR but we also have to be ! 319: compatible with the \fBC\fR data structures generated by \fIposy\fR. ! 320: The implementors decided to optimise the \fBC\fR data structures generated ! 321: a little means we have to have all these \fBS\fR type entries. ! 322: If a type was a single field in most cases they produced a \fB#define\fR ! 323: which eliminates the need to have a whole structure just for that type. ! 324: In all the places where this type is used the field of the \fBC\fR structure ! 325: is changed from a pointer to field which holds the value directly in the ! 326: structure. ! 327: See the \fBISODE\fR reference given above for more details. ! 328: .PP ! 329: We handle this by generating the same tables that would be generated ! 330: with out the optimisation, except the optimised types the S-type of entries ! 331: instead of the normal ones. ! 332: For example an optimised \fBOCTET STRING\fR would have ! 333: the type field of its entry as \fBSOCTETSTRING\fR instead of \fBOCTETSTRING\fR. ! 334: The only difference in how \fBS\fR type and its corresponding normal are handle ! 335: is how they find the \fBC\fR data structure for that entry. ! 336: That difference is that there is no indirection through pointers. ! 337: .IP "Flags field" ! 338: Besides the encoding the class the \fBpe_flags\fR field ! 339: also contains a few possible flags. ! 340: Mainly \fBFL_OPTIONAL\fR which means the \fBASN.1\fR type ! 341: corresponding to this flag is OPTIONAL. ! 342: Consequently when encoding it has to determine if the type is present in the ! 343: user data possibly using the bit map as described under the \fBOPTL\fR entry. ! 344: Likewise when decoding it may have to set a bit in the bit map appropriately. ! 345: The other flag at the moment is \fBFL_DEFAULT\fR which means the entry ! 346: corresponds to an \fBASN.1\fR DEFAULT type. ! 347: This bit is still needed as not all types have \fBDFLT_*\fR entries implmented ! 348: for them at the moment. ! 349: In particular compound value things like SEQUENCE and SET can't have thier ! 350: default value specified. ! 351: This is consistent with \fBISODE\fR, if fact implementing that may even ! 352: break existing \fBISODE\fR code. ! 353: This last flag \fBFL_IMPLICIT\fR is obsolete and not not used any where.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.