Skip to content

III ASN.1 Tool with included #include statements to support newer compilers

License

Notifications You must be signed in to change notification settings

Kampbell/III-ASN.1

 
 

Repository files navigation

###Introduction###

The III ASN.1 Tool includes two parts : an ASN.1 compiler "asnparser" which compiles the Abstract Syntax to c++ files, and a runtime library which is used to link with the c++ files generated by asnparser. Based on the works of Open H.323 projects, it is developed for the needs of H.450 series protocol. Hence, it supports the information object class defined in X.681. Below are the summary of its features.

Supports PER ,BER and AVN (Abstract Value Notation) encoding/decoding
Partially Supports X.681, X.682, X.683 (Only the parts used by H.450 series) 
Supports immediate decoding of table constrained open type. 
Follows the C++ interface defined by TeleManagement Forum and X/Open consortium.
Capable of suppressing generating code for unused ASN.1 types.  
Far smaller and faster than its predecessor. 
It's open source and free of charge for any personal or commercial use; however, its distribution is subject to the Mozilla Public License Version 1.0. 
A bundled H.323 packet analyzer for Microsoft Network Monitor severed as an example to use the tool.

###History###

The Institute for Information Industry (III) have been implementing H.323 protocol stack since 1997. The Encoding/Decoding of ASN.1 types in the H.245 and H.225.0 protocols are the fundamental elements of any H.323 implementation. In 1999, we decided to adopt the ASN.1 compiler from Open H.323 project because it provided the source code that gave us more control. However, when we started to develop H.450 series protocols. The lack of information object support in the OpenH.323 compiler made us to choose between the commercial products or develop our own based on the OpenH.323 ASN.1 compiler. After some discussions, we decided to develop our own. After months of development, we are glad to release our works back to the open source community.

Although we began our development from the works of Open H.323 ASN.1 compiler. We did not want the generated code and library to depend on their Pwlib. Therefore we replaced the containers in the ASN.1 library by their counterparts from STL. In the mean time, we also found the existence of ASN.1/C++ standard interface from the TeleManagement Forum and The Open Group Ltd. After finishing the development of parsing of Information Objects, we started to rewrite the library based on the specification. As the result, the C++ interface is quite different from that in Pwlib. This also save us from the work of documenting the interface and usage of the ASN.1 library. Download III ASN.1 Tool can be download from the CVS repository.

###Building III ASN.1 Tool###

Below are the dependent libraries/tools and their download sites. Dependent Libraries/Tools Download Sites asnparser flex & bison http://www.openh323.org/bin/flexbison.zip BOOST library http://www.boost.org C++ Standard Library Compiler build-in or http://www.stlport.org Runtime library BOOST library http://www.boost.org C++ Standard Library Compiler build-in or http://www.stlport.org MS Netmonitor H.323 parser Microsoft Platform SDK http://www.microsoft.com/msdownload/platformsdk/sdkupdate sed http://www.cornerstonemag.com/sed

Note :

MSVC 6.0 users should download the patch of build-in C++ standard library from
http://www.dinkumware.com/vc_fixes.html.
The version of the BOOST Library we have tested are 1.28.0.

####Build ASN.1 Tools in MSVC.####

If you are using MSVC 6.0, download and install the patch of build-in C++ standard library from
http://www.dinkumware.com/vc_fixes.html; in addition, you should replace the definition of auto_ptr in C:\Program Files\Microsoft Visual Studio\VC98\include\memory with the contents  in the file.
 open iiiasn1.dsw with MSVC
If you want to build III H.323 Packet analyzer for Microsoft Network Monitor, install Microsoft Platform SDK.
Start MSVC, Go into the Tools menu, Options item, Directories tab and add  to the Include files path with the BOOST. In addition, add the path of iiiasn1-2_12/Lib to the executable files path. If you want to build III H.323 Packet analyzer for Microsoft Network Monitor, add the path of sed to the executable files path.
Select Build All.
Copy the IIIH323Parser.dll to the subdirectory parsers of your netmon directory when needed. (network monitor is a bundled program of Windows 2000 Server Edition, it also available from Microsoft Server Management Server)

####Build Runtime Library in Unix Environment####

Unpack iiiasn1.tar.gz.
Specify the path of BOOST Library in the environment variable CPLUS_INCLUDE_PATH as follows:

 $ export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:$HOME/boost_1_28_0
configure iiiasn1 and build it.

$ cd iiiasn1-2_12
$ mkdir build && cd build
$ ../configure
$ make

If you want to build test programs, use "make check" instead of "make".

###Configuration###

The following are the options you may specify by setting the corresponding flags on C++ compiler command-line. Controlling Macro Description ASN1_HAS_IOSTREAM This switch is used to enable IOSTREAM and AVN support. However, it requires the ANSI compliant IOSTREAM library. ASN1_ALLOCATOR Enables custom memory manager. ASN1_STATIC Define it when linking against the static ASN.1 library in MSVC. BOOST_NO_MT This switch is used for BOOST pool library to disable multithread support, required only if ASN1_ALLOCATOR is set.

When building the ASN.1 run time library in UNIX environment, you should run the configure script with the following options. conifigure options Description --enable-avn, --diable-avn Enables or disables IOSTREAM and AVN support --enable-allocator, --disable-allocator Enables or disables custom memory manager --enable-thread, --disable-thread Enables or disable multi-threading Using III ASN.1 Compiler

The following describes how to compile the ASN.1 files. ansparser [options] asnfile... -v --verbose Verbose output (multiple times for more verbose) -e --echo Echo input file -d --debug Debug output (copious!) -c --c++ Generate C++ files -s[n] --split[n] Split output if it has more than n (default 50) classes -o --output dir Output directory

For example, if you have 4 files "h2250v4.asn h235v2.asn h245v7.asn h248.asn" to be compiled, you enter the following command : (you can find the mentioned files in asnh323 directory)

asnparser -c h245v7.asn h235v2.asn h2250v4.asn

Notice that you have to be careful about the order of the input files if they have dependencies. In the above case, "h2250v4.asn" imports modules from "h235v2.asn" and "h245v7.asn", so they should proceed "h2250v4.asn".

Below are the list of generated files: h323_messages.h h323_message.inl h323_messages.cxx h235_security_messages.h h235_security_messages.inl h235_security_messages.cxx h235_security_messages_t.cxx multimedia_system_constrol.h multimedia_system_constrol.inl multimedia_system_constrol.cxx msc_faxprofile.h msc_faxprofile.inl msc_faxprofile.cxx

The output files are named after their module names rather than their input file names. The *.h files are the header files which contain the declarations of c++ class; the *.inl files contain the definitions of inline member functions; the *.cxx files contain the definitions of non-inline member functions; and the _t.cxx contain the template definition of template classes. However, there're only 3 modules in these files, where do the msc_faxprofile. come from? That's because the H323-MESSAGES imported FaxProfile from MULTIMEDIA-SYSTEM-CONTROL. In order to minimize the dependency between different translation unit and reduce compile time, the declarations and definitions of FaxProfile are extracted to a separate file.

The extracting types from imported module feature is very useful. For instance, if you need only the definition of MULTIMEDIA-SYSTEM-CONTROL.OpenLogicalChannel in some source files of your application. You can manually define a module as follows :

LGC DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
IMPORTS OpenLogicalChannel FROM MULTIMEDIA-SYSTEM-CONTROL;
Olc ::= OpenLogicalChannel
END

Save the file, and compile it using asnparser with other modules. You will get separate files which contains the definitions of "OpenLogicalChannel".

If you need to remove some types from a module, use the compiler directive "Remove". The file "lgc.asn" contains an example. However, you should be aware that if you remove a type that appears in a type's extension root (that is, the component which appears before the extension mark "..." of "SEQUENCE", "SET" or "CHOICE", the PER decoder cannot ignore a message which contains such component, even though it is marked as OPTIONAL (You cannot remove non-OPTIONAL component of a "SEQUENCE" or "SET" type anyway).

###How to use the C++ Interfaces###

The C++ Interfaces is similar to those specified by TeleManagement Forum, you can download the document TMF040-1 here.

However, not all interfaces in this document are implemented or strictly followed. Below are some of the differences between our implementation and TMF040-1.

The III ASN.1 runtime library doesn't use C++ exception as its error handling mechanism. Errors can be checked by the return code of (member) function call instead of exception catching.
The only compiler directive supported is "Remove". Furthermore, only typereferences can be removed. 
std::vector is used by SEQUENCE_OF instead std::deque. 
SET_OF is implemented the same way as SEQUENCE_OF.
INTEGER is not a template class, which means no 64 bit or big integer support. 
BIT_STRING interface does not follow the interface of std::vector<bool>.
OCTET_STRING inherits std::vector<char> rather than std::string.
No AbstractType.
isValid() and isStrictlyValid() only checks some basic PER visible constraint. Table constraint is not checked.
The Abstract Value Notation of OpenTypeFieldVal is  not correct. The correct semantic should be "Type ':' Value". However, only "Value" is outputted by asValueNotation() and  use setAsValueNotation() for open type does not work.
CoderEnv does not follow std::set<Module*>  interface, it only provides basic insert/erase functions; on the other hand, find(const char*moduleName) is added.
Information Object and Information Object Set do not have abstract base classes; in addition, no code is generated for ValueSetField in Information Object Class.
For the components in CHOICE, there are no enumerations of the component names because not all the C++ compilers we have tested support this syntax. Use the component_name::id_ instead. Furthermore, the TMF040-1 specification uses component_name::id instead of component_name::id_. However, without the underscore, it may cause name conflicts. As a result, we added an underscore for all the generated CHOICE component id.

You can find some practical examples about the usage of the ASN.1 C++ interface in the testsuite project file. Here is an example of H.4502 CTInitiate.invoke usage excerpted from h450Test.cpp file.

namespace H4501 = H4501_Supplementary_ServiceAPDU_Structure ; namespace HGEL = H4501_General_Error_List; namespace H4502 = Call_Transfer_Operations; namespace ROA = Remote_Operations_Apdus; namespace H225 = H323_MESSAGES;

H4501::Module h4501Module;
HGEL::Module hgelModule;
H4502::Module h4502Module(&hgelModule); // The objects in H4501-General-Error-List
                                            // is referenced by Module Call-Transfer-Operations

const H4501::OPERATION& callTransferOperations = h4502Module.get_H323CallTransferOperations();

// Insert all objects in H323CallTranferOperation to OperationSet
h4501Module.get_OperationSet().insert(callTransferOperations.begin(),
                                      callTransferOperations.end());

ASN1::CoderEnv env;
// set encoding rule
env.set_per_Basic_Aligned();
// only OperationSet in H4501_Supplementary_ServiceAPDU_Structure is needed by decoder
env.insert(&h4501Module);

// CTInitiate.invoke
H4501::H4501SupplementaryService pdu1, pdu2;
pdu1.set_serviceApdu().select_rosApdus().resize(1);

ROA::ROS<H4501::InvokeIdSet, H4501::OperationSet, H4501::OperationSet>& ros = pdu1.ref_serviceApdu().ref_rosApdus()[0];
ROA::Invoke<H4501::InvokeIdSet, H4501::OperationSet>& invoke = ros.select_invoke();
invoke.set_invokeId(1);
invoke.set_opcode(h4502Module.get_callTransferInitiate().operationCode);
std::auto_ptr< H4502::CTInitiateArg> arg(new H4502::CTInitiateArg); // use std::auto_ptr to preserve exception safty
arg->set_callIdentity("1111");
arg->set_reroutingNumber().set_destinationAddress().resize(1);
arg->ref_reroutingNumber().ref_destinationAddress()[0].select_h323_ID(L"Huang-Ming Huang");
invoke.set_argument().grab(arg.release());

std::vector<char> buf;
ASN1::encode(pdu1, &env, std::back_inserter(buf));

if (ASN1::decode(buf.begin(), buf.end(), &env, pdu2) &&
     pdu1 == pdu2 )
       std::cout << "decode success!\n";
else
    std::cout << "decode error!\n";

###Common Problems###

Here are some of the common problems you might encounter in MSVC.

The boost pool library which is used for custom memory manager does not support MSVC 6.0. If you want to use custom memory manager in MSVC 6.0, open  boost/pool/detail/singleton.hpp and  modify the only "private" keyword in the file to "public."

###Latest News### Aug 31, 2002 - version 2.12

Adds Support for GCC 3.1 and MSVC.Net.
Fixes some PER decoding problems.
Adds DLL support for MSVC.

Oct 6, 2001 - version 2.11

Provides custom memory manager for better performance.
Optional components in SEQUENCE are now created on demands.
Fixed the bug when parsing CallingPartyNumber and add ConnectedPartyNumberInformationElement in IIIH323Parser. (Thanks to Danail Kirov for providing this patch)
Update the h2250v7.asn to the latest (02 Jun 2001) version. (Thanks to Paul E. Jones for the information)
Provides invalid_tracer() which can be used to print the invalid component of a constructed ASN.1 value.
Some bug fixes in asn1.h ,BEREncoder.cxx BERDecoder.cxx.

July 9, 2001 -Version 2.1

Configure script added for Unix environment.
The library has been optimized for memory footprint and C++ compile time.
Some bugs fixes and GCC 2.95.x compiler bug workaround. 

May 4, 2001

  Fixed the problem with InvokeIdSet in Invoke APDU  of H.4501 which I mistook it as a variable constraint.

May 2, 2001

Bug fixes reflects Pwlib asner.cxx revision 1.42.  

April 26, 2001 - Version 2.0

First Publicly Release   

Huang-Ming Huang Network Communication Lab Institute for Information Industry Taiwan, Republic of China

About

III ASN.1 Tool with included #include statements to support newer compilers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 66.4%
  • C 17.8%
  • Yacc 6.4%
  • M4 2.4%
  • Shell 2.3%
  • Lex 1.8%
  • Other 2.9%