Code mapper

Figure 2.3: From system/data models to runtime "glue"
Image aadl2glueC
Having semantically equivalent data type definitions, the teams doing the functional modeling of the AP-Level containers can proceed with their work. They rest assured that their input and output interfaces safely carry all the information required for communication with other AP Level containers.

When however, they reach the point that their modeling tool performs code generation, a different kind of problem appears: the generated code representing the exchanged messages' data structures is completely different, even though the structures themselves carry the same semantic content (asn2dataModel guarantees that).

Someone must translate the data between these different codes, and this is the job performed by aadl2glueC: it creates the necessary C3.2 ``glue'' code for mapping the data between the data structures generated by asn1c and the data structures generated by the modeling tool. Notice that the work performed by this code is done at runtime, so it must be performed with accuracy and precision - and as fast as possible. In the case of SCADE for example, the code generated by aadl2glueC is using advanced MACROs provided by ESTEREL to read/write the fields from within the messages to the appropriate SCADE destinations (variables, object instances, etc):

AVALON:~/ASSERT$ ls -l
total 16
-rw-r--r-- 1 root root 235 2007-02-21 13:27 Data.aadl
-rw-r--r-- 1 root root 446 2007-02-21 13:32 Lustre5.PosData.asn1.lus
-rw-r--r-- 1 root root 716 2007-02-21 13:29 PosData.asn1
-rw-r--r-- 1 root root 213 2007-02-21 13:29 System.aadl

AVALON:~/ASSERT$ aadl2glueC Data.aadl System.aadl 

AVALON:~/ASSERT$ ls -l
total 36
-rw-r--r-- 1 root root   235 2007-02-21 13:27 Data.aadl
-rw-r--r-- 1 root root   446 2007-02-21 13:32 Lustre5.PosData.asn1.lus
-rw-r--r-- 1 root root   716 2007-02-21 13:29 PosData.asn1
-rw-r--r-- 1 root root 12693 2007-02-21 13:41 PosData.asn1.TC_Parser.from.
asn1c.to.Lustre5.c 
-rw-r--r-- 1 root root   291 2007-02-21 13:41 PosData.asn1.TC_Parser.from.
asn1c.to.Lustre5.h
-rw-r--r-- 1 root root   213 2007-02-21 13:29 System.aadl

AVALON:~/ASSERT$ cat PosData.asn1.TC_Parser.from.asn1c.to.Lustre5.h
#ifndef __LUSTREPOSDATAASN1_H__
#define __LUSTREPOSDATAASN1_H__

#include <stdlib.h> /* for size_t */

int Convert_From_ASN1C_To_TCLink_In__TC_Parser__Id(
    void *pBuffer, size_t iBufferSize);

int Convert_From_TCLink_To_ASN1C_In__TC_Parser__Param(
    void *pBuffer, size_t iMaxBufferSize);

...
As seen above, this code generator creates ``glue'' functions that are responsible for mapping the data between the interfaces.

The first, Convert_From_ASN1C_To_TCLink_In_TC_Parser__Id decodes an input ASN.1 stream (as provided by the pBuffer and iBufferSize parameters) of ASN.1 type TC_Link and stores its values inside the SCADE variables that have been generated for parameter Id of subprogram TC_Parser. The second one, Convert_From_TCLink_To_ASN1C_In__TC_Parser__Param, does the reverse: it reads the data used by SCADE to represent parameter Param of subprogram TC_Parser and encodes them in an ASN.1 stream of type TC_Link. The stream is stored inside the provided buffer arguments.

The implementation details on how the mapping between data stuctures takes place are stored inside PosData.asn1.TC_Parser.from.asn1c.to.Lustre5.c.

The generated functions don't stop at providing message translators; in the end, the outside world only needs access to two functions: an Initialize_PIname function that calls whatever initialization code is necessary (and must be called exactly once at the beginning of the system runtime) and an Execute_PIname which calls the appropriate message translation primitives for the input parameters, executes the functional code for the Provided Interface, and translates the outputs back into ASN.1 streams.

To put it simply, the code mapper creates a complete interface for usage of the APLC's code from ASSERT's VM, utilizing ASN.1 to encode and decode the messages it sends and receives.