![]() |
![]() |
![]() |
![]() |
![]() |
Creating the Transfer Syntax
The SDL Suite offers several ways to create the transfer syntax. The available coding access interfaces are:
In this tutorial, only the C code interface will be covered. For a complete description of ASN.1 encoding and decoding, please see ASN.1 Encoding and De-coding in the SDL Suite.
Using the C code interface, the transfer syntax can be created either using the Organizer's make dialog or using the Targeting Expert. Both methods are presented in this tutorial. When using the Targeting Expert, you can select to use the Cadvanced SDL to C Compiler or the Cmicro SDL to C Compiler when creating the transfer syntax. Both methods will be covered as well.
This section starts with a short introduction and the actual instructions are presented in:
Introduction
To be able to transfer the abstract syntax between two nodes in network, you must first create the transfer syntax. The transfer syntax representation is then transmitted in a protocol buffer.
When creating the transfer syntax you must perform the following tasks:
The template files must be generated in order for you to include the ASN.1 data types in the compilation and code generation processes. The template files extract information from your SDL system and create a skeleton. Often these template files do not contain sufficient information to meet the demands of the application and therefore you must edit the templates. The template files that are generated cover the following areas:
However, the SDL Suite needs additional information in order to create the environment file. Before the generation you must determine which encoding/decoding schemes to use and you must create type nodes files.
The type nodes are auto-created by ASN.1 Utilities and must not be edited.
The template makefile is only created if you are using the Make dialog. The default makefile of the Targeting Expert handles all necessary make functionality.
Environment Functions
The environment is defined as all devices or functions that are needed by the application but not specified within the SDL system. By sending signals to the environment, the SDL system wants certain tasks to be performed. This could be for instance:
- reading or writing information to a file
- sending or receiving messages across the network
- reading or writing information on hardware ports or sockets
However, the SDL system only controls events that occur within the system. It does not specify how signals leaving the system are handled by the environment. This is why you must provide an interface between the SDL system and the environment. This interface is made up by the environment functions.
The SDL Suite is rather helpful and can generate a template environment file that includes a skeleton of the environment functions. The environment file is written in C code and by editing this file you can specify the behavior of signals from the SDL system and of signals going in to the SDL system.
An environment header file or system interface header file can also be created. This file contains all type definitions and other external definitions that are necessary in order to implement the environment functions.
There are several ways to create the environment file. You can:
Encoding/Decoding
When creating the transfer syntax, the messages that will be transferred must be encoded and the incoming messages must be decoded. The type of encoding rules to apply is specified in the environment file. This means that the encoding/decoding function calls must be included in the environment file.
The SDL Suite supports the standard BER and PER encoding/decoding schemes, but it also allows you to use a user specified encoding scheme. ASCII encoding is available in the SDL Suite as well, but it does not support encoding of ASN.1 types.
Type Nodes
To include the ASN.1 data types in your application, they must be translated into a form that the SDL Suite understands. Within the SDL Suite, this translation is handled by the ASN.1 Utilities.
The ASN.1 Utilities tool is invoked automatically when the SDL system is analyzed and it allows you to:
- perform syntactic and semantic analysis of your ASN.1 modules
- generate SDL code from the ASN.1 modules
- generate type information for encoding and decoding using BER or PER
This means that when you are using the ASN.1 utilities, you create type nodes. A type node is a static variable that describes the properties and characteristics of an ASN.1 data type, including tag information needed by BER/PER encoders and decoders. The variable is named yASN1_<type_name>.
All nodes are generated in files named <asn1module_name>_asn1coder.c and declarations to access them in files named <asn1module_name>_asn1coder.h.
The type nodes are auto-created by ASN.1 Utilities and must not be edited.
Make Process
This section is only valid if you build and analyze your project using the Organizer's make dialog.
The default makefile in the SDL Suite, determines the relationship between source files, header files, object files and libraries in your project.
However, the default makefile does not include the generated files in the make process. To include the environment files and the type node files in the make process, you must generate a template makefile that will be appended to the default makefile, see Figure 190. The template makefile can be generated by the SDL Suite.
Generating Template Files - the Organizer
Follow the instructions below to generate environment files, type node files and the template makefile using the Organizer's Make dialog:
- Click the SDL system symbol in the Organizer.
- From the Generate menu, select the Make... command. The SDL Make window opens.
- Specify your options in the make dialog according to the following list:
Make sure that you de-select the Compile & link option as you only want to generate the template files.
- Specify your target directory where the generated files will be stored.
- Figure 191 shows the Make dialog with the selected options.
Encode and decode calls are only generated if the Generate ASN.1 coder option is enabled in the make dialog.
In your target directory, you will now find the generated files including:
- <system_name>_env.c
This is the environment skeleton file.- <system_name>.ifc
This is the environment header file.- <system_name>_env.tpm
This is the template makefile.- <asn1module_name>_asn1coder.c
<asn1module_name>_asn1coder.h
These files are the type nodes created by the ASN.1 utilities.Editing the Generated Files - the Organizer
As the generated files only consist of skeleton functions, you must edit the files to suit the functionality of your application.
- Edit the environment file <system_name>_env.c file using any text editor. In the skeleton file, macros are included but they are not defined. To define the required functionality, either create a <system_name>_env.h file and define all macros there, or replace the macros with the required code directly in the <system_name>_env.c file. Example 4 shows the updated SNMP environment file.
- Save the environment file.
- Edit the template makefile <system_name>_env.tpm if necessary.
- Save the template makefile.
- Make copies of the edited files and save the copies in a different folder.
Example 4 : Environment Functions
- The SNMP get_request message should be encoded by BER DEFINITE and then sent to the network entity by UDP protocol to port 161 which is the default port for the SNMP requests. BER encode and decode function calls are automatically generated to the environment functions. This code should then be updated with the socket function calls and with choosing correct BER dialect.
- The following code is part of the environment file for the Windows platform (#include <WinSock.h>) and displays the function that handles the out signals.
char* data;int datalen, i;tBuffer Buf = 0;struct sockaddr_in manager_addr, agent_addr;XENV_OUT_START/* Signals going to the env via the channel Signal_env *//* Signal snmp_request */IF_OUT_SIGNAL(snmp_request,"snmp_request")/* Encoding message to the buffer */BufInitBuf( Buf, bms_SmallBuffer );ERSetRule( Buf, er_BER | er_Definite );BufInitWriteMode( Buf );BEREncode(Buf, (tASN1TypeInfo *)&yASN1_Message,(void *)&((yPDef_snmp_request *)(*SignalOut))->Param1);BufCloseWriteMode( Buf );/* Sending message to the network */BufInitReadMode( Buf );datalen = BufGetDataLen( Buf );data = BufGetSeg( Buf, datalen );agent_addr.sin_family = AF_INET;agent_addr.sin_port = htons(161);agent_addr.sin_addr.s_addr = inet_addr("192.168.0.20"); /* ip address of any network entity, a good entity for test is network printer */i = sendto( manager_sock, data, datalen, 0, (struct sockaddr *) &agent_addr, sizeof (agent_addr) );BufCloseReadMode( Buf );BufCloseBuf(Buf);RELEASE_SIGNALEND_IF_OUT_SIGNAL(snmp_request,"snmp_request")/* Signal Init */IF_OUT_SIGNAL(Init,"Init")WSADATA wsdata;WORD wVersionRequested;wVersionRequested = MAKEWORD(2,2);/* Registering in the socket library */if( WSAStartup( wVersionRequested, &wsdata ) != 0 )exiterr("Init", "WSAStartup");/* Creating manager socket */if ( (manager_sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP )) == -1 )exiterr("Init", "socket");manager_addr.sin_family = AF_INET;manager_addr.sin_port = htons(162);manager_addr.sin_addr.s_addr = INADDR_ANY;/* Binding manager socket to <local IP>:162 */if ( bind(manager_sock, (struct sockaddr *) &manager_addr, sizeof (manager_addr)) == SOCKET_ERROR )exiterr("Init", "bind");RELEASE_SIGNALEND_IF_OUT_SIGNAL(Init,"Init")/* Signal Close */IF_OUT_SIGNAL(Close,"Close")OUT_SIGNAL1(Close,"Close")XENV_BUF(BufInitWriteMode(Buf));OUT_SIGNAL2(Close,"Close")XENV_BUF(BufCloseWriteMode(Buf));RELEASE_SIGNALEND_IF_OUT_SIGNAL(Close,"Close")}Encoder and Decoder function calls
As stated earlier, it is not necessary to auto-create the environment file. By copying another environment file or by writing it from scratch, you can customize the environment file for your needs. If you do so you must use the correct syntax of the encoding and decoding functions.
The syntax of the BER function calls is:
BER_ENCODE (Buffer, &Typenode, &Signalparameter)BER_DECODE (Buffer, &Typenode, &Signalparameter)The syntax of the PER function calls is:
PER_ENCODE ( Buffer, &Typenode, &Signalparameter)PER_DECODE ( Buffer, &Typenode, &Signalparameter)Example 5 : Encoding and Decoding function calls
- The following function calls are being used in the SNMP example:
BER_ENCODE(Buf, (tASN1TypeInfo *)&yASN1_Message,(void *)&((yPDef_snmp_request *)(*SignalOut))->Param1));BER_DECODE(Buf, (tASN1TypeInfo *)&yASN1_Message,(void *)&((yPDef_snmp_reply *)SignalIn)->Param1))After the snmp message has been sent to an active network entity to port 161, the SDL system should change the state and start waiting for a reply with the values requested, see Figure 192.
Decoding incoming signals
Before the SDL system can receive and use the information that is encapsulated in the incoming environment signals, a number of tasks must be performed in the environment file. Most of them are automatically generated to the environment file by the SDL Suite, but some must be handled manually.
The following list defines the steps involved in the decoding process. You must perform step 1 manually, while steps 2 through 4 are generated by the SDL Suite:
- Extract the encoded information from the protocol-specific packet and transfer it to a data buffer. This should be implemented in C code in the environment file. In our case this is receive bytes from the socket and save them into the buffer.
- Allocate memory for the signal structure. Special functions for that are automatically generated into the environment file by SDL Suite.
- Call BER_DECODE function. The function is defined in the decoding library and handles the actual decoding process.
- The decoded signal is sent to the SDL system. This is performed by the SDL_Output function.
The following code is part of the environment file for the Windows platform (#include <WinSock.h>) and displays the function that handles incoming signals.
/* Signal snmp_reply */if ( manager_sock != -1 ){datalen = recv( manager_sock, reply, sizeof(reply), 0 );if ( datalen == SOCKET_ERROR )exiterr("snmp_reply", "recv");else{BufInitBuf( Buf, bms_SmallBuffer );BufInitWriteMode( Buf );BufPutSeg( Buf, reply, datalen );BufCloseWriteMode( Buf );ERSetRule( Buf, er_BER | er_Definite );BufInitReadMode(Buf);IN_SIGNAL1(snmp_reply,"snmp_reply")BERDecode(Buf, (tASN1TypeInfo *)&yASN1_Message,(void *)&((yPDef_snmp_reply *)SignalIn)->Param1);IN_SIGNAL2(snmp_reply,"snmp_reply")BufCloseReadMode(Buf);BufCloseBuf(Buf);}}Generating Template Files - Targeting Expert
Follow the instructions below to generate environment files, type node files and the template makefile using the Targeting Expert.
- From the Generate menu, select the Targeting Expert command. The SDL Targeting Expert window opens.
- From the drop-down menu located above the Partitioning Diagram Model frame, select Light Integrations and the desired SDL to C Compiler. It is possible to used either Cadvanced or Cmicro. The pre-defined alternative specifies the type of compiler needed for the generation.
- Select the SDL to C Compiler tab.
- In the General box, select Analyze/generate code.
- In the Environment box, select:
- Select the Communication tab. In the Coders box, select the Generate ASN.1 coder functions check box.
- Press the Full Make button. This generates the environment file.
Encode and decode calls are only generated if the Coder functions... option is enabled.
In your target directory, you will now find the generated files including:
- <system_name>_env.c (Cadvanced)
env.c (Cmicro)
This is the environment skeleton file.- <system_name>.ifc
This is the environment header file.- <asn1module_name>_asn1coder.c
<asn1module_name>_asn1coder.h
These files are the type nodes created by the ASN.1 utilities.Editing the Generated Files - Targeting Expert
As the generated files only consist of skeleton functions, you must edit the files to suit the functionality of your application.
Make a habit of making a copy of the environment file after it has been edited. Otherwise the edits will be overwritten, if the file is re-generated by mistake.
- Rename the environment file.
- Edit the environment file <system_name>_env.c file according to your needs. In the skeleton file, macros are included but they are not defined. To define the required functionality, either create a <system_name>_env.h file and define all macros there, or replace the macros with the required code directly in the <system_name>_env.c file.
- Save the environment file.
Example 6 : Environment functions - Cmicro
- The following code is part of the environment file skeleton and displays the function that handles the out signals.
switch (xmk_TmpSignalID){case snmp_request :{/* BEGIN User Code *//* Use (yPDP_snmp_request)xmk_TmpDataPtr to access the signal's parameters *//* ATTENTION: the data needs to be copied. Otherwise it *//* will be lost when leaving xOutEnv *//* This section can be used to encode outgoing data with the selected coder functions.** Please remove the comments and send the data with your communications interface!** (<SendViaCommunicationsInterface( data, datalen )> must be replaced)char* data;int datalen;BufInitWriteMode( Buf );XENV_ENC( PER_ENCODE( Buf, (tASN1TypeInfo *) &yASN1_z_RFC1157_SNMP_0_Message,(void *) &((yPDef_snmp_request *)xmk_TmpDataPtr)- >Param1));BufCloseWriteMode( Buf );BufInitReadMode( Buf );datalen = BufGetDataLen(Buf);data = BufGetSeg( Buf, datalen );<SendViaCommunicationsInterface( data, datalen )>;BufCloseReadMode( Buf );*//* Do your environment actions here. */xmk_result = XMK_TRUE; /* to tell the caller that *//* signal is consumed *//* END User Code */}break ;case Init :{/* BEGIN User Code *//* Do your environment actions here. */xmk_result = XMK_TRUE; /* to tell the caller that *//* signal is consumed *//* END User Code */}break ;case Close :{/* BEGIN User Code *//* Do your environment actions here. */xmk_result = XMK_TRUE; /* to tell the caller that *//* signal is consumed *//* END User Code */}break ;default :xmk_result = XMK_FALSE;/* to tell the caller that *//* signal is NOT consumed *//* and to be handled by *//* the Cmicro Kernel ... */break ;}
http://www.ibm.com/rational |
![]() |
![]() |
![]() |
![]() |