AmbSignalMapper: Improve handling of bitbake environment
authorPetr Nechaev <petr.nechaev@cogentembedded.com>
Fri, 6 Mar 2015 00:00:46 +0000 (03:00 +0300)
committerPetr Nechaev <petr.nechaev@cogentembedded.com>
Mon, 30 Mar 2015 11:26:07 +0000 (14:26 +0300)
* Removed "-w" from perl commandline in shebang for better compatibility with bitbake environment. Warnings can be enforced
manually when needed.
* Fixed path computation in plugin generation code

tools/AmbSignalMapper/bin/dbc2amb
tools/AmbSignalMapper/bin/dbc2json
tools/AmbSignalMapper/bin/json2amb
tools/AmbSignalMapper/lib/Intel/IviPoc/AmbPluginGenerator.pm

index acc5aad..d2c4099 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
 #      Copyright (C) 2014  Intel Corporation
 #   Copyright (c) 2015  Cogent Embedded Inc.
index e96f867..453bdf2 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
 #      Copyright (C) 2014  Intel Corporation
 #
index f2b4718..b785f2e 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
 #      Copyright (C) 2014  Intel Corporation
 #
index 7524509..a7b977e 100644 (file)
@@ -49,13 +49,13 @@ plugin project.
 
 The following little code snippet shows the module usage.
 
-       use Intel::IviPoc::AmbPluginGenerator qw(processPlugin);
+    use Intel::IviPoc::AmbPluginGenerator qw(processPlugin);
 
-       my $hashingAllowed = "E";
-       my $inputfile = "myfile.json";
-       my $targetDir = '/home/user/project/automotive-message-broker/plugins';
-       processPlugin ( $hashingAllowed, $inputfile, $targetDir );
-       ...
+    my $hashingAllowed = "E";
+    my $inputfile = "myfile.json";
+    my $targetDir = '/home/user/project/automotive-message-broker/plugins';
+    processPlugin ( $hashingAllowed, $inputfile, $targetDir );
+    ...
 
 =head1 EXPORT
 
@@ -83,65 +83,65 @@ based on information comming from input JSON file.
 my $hashingAllowed = 'E';       # Enabled by default
 
 sub processPlugin {
-       $hashingAllowed = $_[0];
-       my $dbcjson = $_[1];
-       my $targetDir = $_[2];
-       
-       if ($hashingAllowed eq 'E' ) {
-               &encryptAmbPropertyNames( $dbcjson );
-       }
-
-       my $pluginName = $dbcjson->{'pluginName'};
-
-       my $templatesDir = 'templates/';
-       my $pluginDir = File::Spec->catdir( ($targetDir, lc($pluginName). '_plugin/') );
-
-       # make new folder
-       &createDirectory( $pluginDir );
-
-       my @templatesFiles = ( "CMakeLists.txt"
-                                                , "ambtmpl_cansignal.h"
-                                                , "ambtmpl_cansignal.cpp"
-                                                , "ambtmpl_plugin.h"
-                                                , "ambtmpl_plugin.cpp"
-                                                , "ambtmpl_cansignals.h"
-                                                , "ambtmpl_plugin.idl"
-                                                , "ambtmpl.in.json"
-                                                );
-
-       my @pluginFiles = ( "CMakeLists.txt"
-                                         , lc ($pluginName) . "_cansignal.h"
-                                         , lc ($pluginName) . "_cansignal.cpp"
-                                         , lc ($pluginName) . "_plugin.h"
-                                         , lc ($pluginName) . "_plugin.cpp"
-                                         , lc ($pluginName) . "_cansignals.h"
-                                         , lc ($pluginName) . "_plugin.idl"
-                                         , lc ($pluginName) . ".in.json"
-                                         );
-
-       my @generationSubs = ( undef
-                                                , undef
-                                                , undef
-                                                , \&generateUuid
-                                                , \&generateCppImplTypes
-                                                , \&generateSignalsTypes
-                                                , \&generateIdlTypes
-                                                , undef
-                                                );
-
-       my $templateFile = '';
-       my $pluginFile = '';
-       my ($volume, $directory) = File::Spec->splitpath( $INC{'Intel/IviPoc/AmbPluginGenerator.pm'} );
-       for my $i (0..scalar(@pluginFiles)-1) {
-               # First join templates folder and filename
-               $templateFile = File::Spec->catfile( ($templatesDir), $templatesFiles[$i] );
-               # Now prepend the module full path
-               $templateFile = File::Spec->catpath( $volume, $directory, $templateFile );
-               # Join target directory with target filename
-               $pluginFile = File::Spec->catfile( ($pluginDir), $pluginFiles[$i] );
-               # Generate each plugin files
-               &generatePluginFile( $templateFile, $pluginFile, $dbcjson, $generationSubs[$i]);
-       }
+    $hashingAllowed = $_[0];
+    my $dbcjson = $_[1];
+    my $targetDir = $_[2];
+    
+    if ($hashingAllowed eq 'E' ) {
+        &encryptAmbPropertyNames( $dbcjson );
+    }
+
+    my $pluginName = $dbcjson->{'pluginName'};
+
+    my $templatesDir = 'templates/';
+    my $pluginDir = File::Spec->catdir( ($targetDir, lc($pluginName). '_plugin/') );
+
+    # make new folder
+    &createDirectory( $pluginDir );
+
+    my @templatesFiles = ( "CMakeLists.txt"
+                         , "ambtmpl_cansignal.h"
+                         , "ambtmpl_cansignal.cpp"
+                         , "ambtmpl_plugin.h"
+                         , "ambtmpl_plugin.cpp"
+                         , "ambtmpl_cansignals.h"
+                         , "ambtmpl_plugin.idl"
+                         , "ambtmpl.in.json"
+                         );
+
+    my @pluginFiles = ( "CMakeLists.txt"
+                      , lc ($pluginName) . "_cansignal.h"
+                      , lc ($pluginName) . "_cansignal.cpp"
+                      , lc ($pluginName) . "_plugin.h"
+                      , lc ($pluginName) . "_plugin.cpp"
+                      , lc ($pluginName) . "_cansignals.h"
+                      , lc ($pluginName) . "_plugin.idl"
+                      , lc ($pluginName) . ".in.json"
+                      );
+
+    my @generationSubs = ( undef
+                         , undef
+                         , undef
+                         , \&generateUuid
+                         , \&generateCppImplTypes
+                         , \&generateSignalsTypes
+                         , \&generateIdlTypes
+                         , undef
+                         );
+
+    my $templateFile = '';
+    my $pluginFile = '';
+    my ($volume, $directory) = File::Spec->splitpath(__FILE__);
+    for my $i (0..scalar(@pluginFiles)-1) {
+        # First join templates folder and filename
+        $templateFile = File::Spec->catfile( ($templatesDir), $templatesFiles[$i] );
+        # Now prepend the module full path
+        $templateFile = File::Spec->catpath( $volume, $directory, $templateFile );
+        # Join target directory with target filename
+        $pluginFile = File::Spec->catfile( ($pluginDir), $pluginFiles[$i] );
+        # Generate each plugin files
+        &generatePluginFile( $templateFile, $pluginFile, $dbcjson, $generationSubs[$i]);
+    }
 }
 
 =head2 generatePluginFile
@@ -153,31 +153,31 @@ based on information comming from input JSON file.
 =cut
 
 sub generatePluginFile {
-       my $srcFileName = $_[0];
-       my $dstFileName = $_[1];
-       my $dbcjson = $_[2];
-       my $generationSub = $_[3];
+    my $srcFileName = $_[0];
+    my $dstFileName = $_[1];
+    my $dbcjson = $_[2];
+    my $generationSub = $_[3];
 
-       my $pluginName = $dbcjson->{'pluginName'};
+    my $pluginName = $dbcjson->{'pluginName'};
 
-       # Open template file
-       my $content = &readFileContent( $srcFileName );
-       $content = &replaceTemplateStrings( $content, $pluginName );
+    # Open template file
+    my $content = &readFileContent( $srcFileName );
+    $content = &replaceTemplateStrings( $content, $pluginName );
 
-       if (defined $generationSub) {
-               my $generatedCode = $generationSub->( $dbcjson );
-               my $place = '\/\*GENERATED_CODE\*\/';
-               $content =~ s/$place/$generatedCode/g;
-       }
+    if (defined $generationSub) {
+        my $generatedCode = $generationSub->( $dbcjson );
+        my $place = '\/\*GENERATED_CODE\*\/';
+        $content =~ s/$place/$generatedCode/g;
+    }
 
-       # Create new file
-       my $pluginFileHandle = &createFile( $dstFileName );
+    # Create new file
+    my $pluginFileHandle = &createFile( $dstFileName );
 
-       # Copy data from one file to another.
-       print $pluginFileHandle $content;
+    # Copy data from one file to another.
+    print $pluginFileHandle $content;
 
-       # close the file
-       close ($pluginFileHandle);
+    # close the file
+    close ($pluginFileHandle);
 }
 
 =head2 createDirectory
@@ -187,11 +187,11 @@ Creates directory for plugin.
 =cut
 
 sub createDirectory {
-       my $dirName = $_[0];
+    my $dirName = $_[0];
 
-       unless(-e $dirName or mkdir $dirName) {
-               die "Unable to create directory '$dirName' $!";
-       }
+    unless(-e $dirName or mkdir $dirName) {
+        die "Unable to create directory '$dirName' $!";
+    }
 }
 
 =head2 createFile
@@ -201,13 +201,13 @@ Creates file and returns a file handle to it.
 =cut
 
 sub createFile {
-       my $fileName = $_[0];
+    my $fileName = $_[0];
 
-       # Open file or die
-       open(my $fileHandle, '>', $fileName)
-               or die "Could not open file '$fileName' $!";
+    # Open file or die
+    open(my $fileHandle, '>', $fileName)
+        or die "Could not open file '$fileName' $!";
 
-       return $fileHandle;
+    return $fileHandle;
 }
 
 =head2 replaceTemplateStrings
@@ -217,15 +217,15 @@ Replaces all occurencies of template specific symbols with plugin name.
 =cut
 
 sub replaceTemplateStrings {
-       my $text = $_[0];
-       my $pluginName = $_[1];
-
-       $text =~ s/AmbTmpl/$pluginName/g;
-       $pluginName = lc ($pluginName);
-       $text =~ s/ambtmpl/$pluginName/g;
-       $pluginName = uc ($pluginName);
-       $text =~ s/AMBTMPL/$pluginName/g;
-       return $text;
+    my $text = $_[0];
+    my $pluginName = $_[1];
+
+    $text =~ s/AmbTmpl/$pluginName/g;
+    $pluginName = lc ($pluginName);
+    $text =~ s/ambtmpl/$pluginName/g;
+    $pluginName = uc ($pluginName);
+    $text =~ s/AMBTMPL/$pluginName/g;
+    return $text;
 }
 
 =head2 generateUuid
@@ -236,12 +236,12 @@ Returns C++ code to be placed into the target plugin.
 =cut
 
 sub generateUuid {
-       my $dbcjson = $_[0];
+    my $dbcjson = $_[0];
 
-       my $ug = new Data::UUID;
-       my $uuidText = $ug->create_str();
+    my $ug = new Data::UUID;
+    my $uuidText = $ug->create_str();
 
-       return $uuidText;
+    return $uuidText;
 }
 
 =head2 generateCppImplTypes
@@ -252,31 +252,31 @@ Returns C++ code to be placed into the target plugin.
 =cut
 
 sub generateCppImplTypes {
-       my $dbcjson = $_[0];
-
-       my $registerMessageText = '';
-       my $hexValue = ();
-
-       my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
-       for my $ecui (0..scalar(@engineControlUnits)-1) {
-               if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
-                       my @messages = @{$engineControlUnits[$ecui]{'messages'}};
-                       for my $msgi (0..scalar(@messages)-1) {
-                               $hexValue = '0x' . uc ( sprintf( "%x", $messages[$msgi]{'canId'} ) );
-                               $registerMessageText .= "    registerMessage($hexValue, $messages[$msgi]{'canDlc'}";
-
-                               my @signals = @{$messages[$msgi]{'signals'}};
-                               foreach my $signal ( @signals ) {
-                                       my $type = $signal->{'AMBPropertyType'};
-                                       $registerMessageText .= &generateCppProperty( $signal, $type);
-                               }
-
-                               $registerMessageText .= "\n                   );\n";
-                       }
-               }
-       }
-
-       return $registerMessageText;
+    my $dbcjson = $_[0];
+
+    my $registerMessageText = '';
+    my $hexValue = ();
+
+    my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
+    for my $ecui (0..scalar(@engineControlUnits)-1) {
+        if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
+            my @messages = @{$engineControlUnits[$ecui]{'messages'}};
+            for my $msgi (0..scalar(@messages)-1) {
+                $hexValue = '0x' . uc ( sprintf( "%x", $messages[$msgi]{'canId'} ) );
+                $registerMessageText .= "    registerMessage($hexValue, $messages[$msgi]{'canDlc'}";
+
+                my @signals = @{$messages[$msgi]{'signals'}};
+                foreach my $signal ( @signals ) {
+                    my $type = $signal->{'AMBPropertyType'};
+                    $registerMessageText .= &generateCppProperty( $signal, $type);
+                }
+
+                $registerMessageText .= "\n                   );\n";
+            }
+        }
+    }
+
+    return $registerMessageText;
 }
 
 =head2 generateCppProperty
@@ -287,23 +287,23 @@ definitions.
 =cut
 
 sub generateCppProperty {
-       my $signal = $_[0];
-       my $type = $_[1];
-
-       my $generatedText = '';
-       my $zonesInUse = 0; # TODO this needs to be in config file
-
-       if ( exists( $signal->{'AMBPropertyName'} ) ) {
-               my $ambPropertyName = $signal->{'AMBPropertyName'};
-
-               # TODO CANSignal needs to take zone as argument
-               #my $zone = 'Zone::None';
-               #if ($zonesInUse) {
-               #    $zone = &calculateZone( $ambPropertyName );
-               #}
-               $generatedText .= "\n                   , new ${ambPropertyName}Type()";
-       }
-       return $generatedText;
+    my $signal = $_[0];
+    my $type = $_[1];
+
+    my $generatedText = '';
+    my $zonesInUse = 0; # TODO this needs to be in config file
+
+    if ( exists( $signal->{'AMBPropertyName'} ) ) {
+        my $ambPropertyName = $signal->{'AMBPropertyName'};
+
+        # TODO CANSignal needs to take zone as argument
+        #my $zone = 'Zone::None';
+        #if ($zonesInUse) {
+        #    $zone = &calculateZone( $ambPropertyName );
+        #}
+        $generatedText .= "\n                   , new ${ambPropertyName}Type()";
+    }
+    return $generatedText;
 }
 
 =head2 generateSignalsTypes
@@ -314,27 +314,27 @@ Returns C++ code to be placed into the target plugin.
 =cut
 
 sub generateSignalsTypes {
-       my $dbcjson = $_[0];
-
-       my $enumsText = '';
-       my $propertiesText = '';
-
-       # First generate the c++ enums from signals with values
-       my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
-       for my $ecui (0..scalar(@engineControlUnits)-1) {
-               if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
-                       my @messages = @{$engineControlUnits[$ecui]{'messages'}};
-                       for my $msgi (0..scalar(@messages)-1) {
-                               my @signals = @{$messages[$msgi]{'signals'}};
-                               foreach my $signal ( @signals ) {
-                                       my $type = $signal->{'AMBPropertyType'};
-                                       $enumsText .= &generateEnumOrValues( $signal, $type);
-                                       $propertiesText .= &generatePropertyClasses( $signal, $type );
-                               }
-                       }
-               }
-       }
-       return $enumsText . $propertiesText;
+    my $dbcjson = $_[0];
+
+    my $enumsText = '';
+    my $propertiesText = '';
+
+    # First generate the c++ enums from signals with values
+    my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
+    for my $ecui (0..scalar(@engineControlUnits)-1) {
+        if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
+            my @messages = @{$engineControlUnits[$ecui]{'messages'}};
+            for my $msgi (0..scalar(@messages)-1) {
+                my @signals = @{$messages[$msgi]{'signals'}};
+                foreach my $signal ( @signals ) {
+                    my $type = $signal->{'AMBPropertyType'};
+                    $enumsText .= &generateEnumOrValues( $signal, $type);
+                    $propertiesText .= &generatePropertyClasses( $signal, $type );
+                }
+            }
+        }
+    }
+    return $enumsText . $propertiesText;
 }
 
 =head2 generateEnumOrValues
@@ -345,60 +345,60 @@ definitions.
 =cut
 
 sub generateEnumOrValues {
-       my $signal = $_[0];
-       my $type = $_[1];
-
-       my $generatedText = "";
-
-       my $ambPropertyName = $signal->{'canId'};
-       if ( exists( $signal->{'AMBPropertyName'} ) ) {
-               $ambPropertyName = $signal->{'AMBPropertyName'};
-       }
-
-       if ( exists( $signal->{'values'} ) ) {
-               my @dupvalues = @{$signal->{'values'}};
-               my @values = sort { $$a{'value'} <=> $$b{'value'} } (&removeDuplicates (\@dupvalues));
-               my $hexValue = ();
-
-               if ( $type eq 'enum' or $type =~ m/int/) {
-                       # Start with comments
-                       $generatedText .= "/**< $ambPropertyName\n";
-                       for my $vali (0..scalar(@values) -1 ) {
-                               $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
-                               $generatedText .= " * $hexValue = $values[$vali]->{'description'}\n";
-                       }
-                       $generatedText .= " */\n";
-               }
-
-               if ( $type eq 'enum' ) {
-                       # Enum definition
-                       $generatedText .= "namespace ${ambPropertyName}s {\n";
-                       $generatedText .= "enum ${ambPropertyName}Type {\n";
-
-                       # Generate enum values
-                       for my $vali (0..scalar(@values) -1 ) {
-                               $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
-                               $generatedText .= "    $values[$vali]->{'name'} = $hexValue";
-                               if ($vali != scalar(@values)-1 ) {
-                                       $generatedText .= ",";
-                               }
-                               $generatedText .= "\n";
-                       }
-                       $generatedText .= "};\n";
-                       $generatedText .= "}\n\n";
-               } elsif ( $type =~ m/int/ ) {
-                       $generatedText .= "namespace ${ambPropertyName}s {\n";
-                       # Generate values
-                       for my $vali (0..scalar(@values) -1 ) {
-                               $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
-                               $generatedText .= "static const $type $values[$vali]->{'name'} = $hexValue;";
-                               $generatedText .= "\n";
-                       }
-               $generatedText .= "}\n\n";
-               }
-       }
-
-       return $generatedText;
+    my $signal = $_[0];
+    my $type = $_[1];
+
+    my $generatedText = "";
+
+    my $ambPropertyName = $signal->{'canId'};
+    if ( exists( $signal->{'AMBPropertyName'} ) ) {
+        $ambPropertyName = $signal->{'AMBPropertyName'};
+    }
+
+    if ( exists( $signal->{'values'} ) ) {
+        my @dupvalues = @{$signal->{'values'}};
+        my @values = sort { $$a{'value'} <=> $$b{'value'} } (&removeDuplicates (\@dupvalues));
+        my $hexValue = ();
+
+        if ( $type eq 'enum' or $type =~ m/int/) {
+            # Start with comments
+            $generatedText .= "/**< $ambPropertyName\n";
+            for my $vali (0..scalar(@values) -1 ) {
+                $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
+                $generatedText .= " * $hexValue = $values[$vali]->{'description'}\n";
+            }
+            $generatedText .= " */\n";
+        }
+
+        if ( $type eq 'enum' ) {
+            # Enum definition
+            $generatedText .= "namespace ${ambPropertyName}s {\n";
+            $generatedText .= "enum ${ambPropertyName}Type {\n";
+
+            # Generate enum values
+            for my $vali (0..scalar(@values) -1 ) {
+                $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
+                $generatedText .= "    $values[$vali]->{'name'} = $hexValue";
+                if ($vali != scalar(@values)-1 ) {
+                    $generatedText .= ",";
+                }
+                $generatedText .= "\n";
+            }
+            $generatedText .= "};\n";
+            $generatedText .= "}\n\n";
+        } elsif ( $type =~ m/int/ ) {
+            $generatedText .= "namespace ${ambPropertyName}s {\n";
+            # Generate values
+            for my $vali (0..scalar(@values) -1 ) {
+                $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
+                $generatedText .= "static const $type $values[$vali]->{'name'} = $hexValue;";
+                $generatedText .= "\n";
+            }
+        $generatedText .= "}\n\n";
+        }
+    }
+
+    return $generatedText;
 }
 
 =head2 generatePropertyClasses
@@ -413,83 +413,83 @@ Returns C++ definitions of one signal property.
 =cut
 
 sub generatePropertyClasses {
-       my $signal = $_[0];
-       my $type = $_[1];
+    my $signal = $_[0];
+    my $type = $_[1];
 
-       my $generatedText = '';
+    my $generatedText = '';
 
-       my $ambPropertyName = $signal->{'canId'};
-       if ( exists( $signal->{'AMBPropertyName'} ) ) {
+    my $ambPropertyName = $signal->{'canId'};
+    if ( exists( $signal->{'AMBPropertyName'} ) ) {
        $ambPropertyName = $signal->{'AMBPropertyName'};
-       }
+    }
 
-       my $byteOrdering = "Endian::Intel";                 # LittleEndian by default
-       if ( exists( $signal->{'byteOrdering'} ) and $signal->{'byteOrdering'} eq '0') {
+    my $byteOrdering = "Endian::Intel";                 # LittleEndian by default
+    if ( exists( $signal->{'byteOrdering'} ) and $signal->{'byteOrdering'} eq '0') {
        $byteOrdering = "Endian::Motorola";                 # BigEndian
-       }
+    }
 
-       my $signedness;
-       if ($signal->{'signedness'} eq '+') {
+    my $signedness;
+    if ($signal->{'signedness'} eq '+') {
        $signedness = "Signedness::Unsigned";               # Unsigned
-       } else {
+    } else {
        $signedness = "Signedness::Signed";                 # Signed
-       }
-
-       my $convertFromFunction = "nullptr";
-       if ( exists( $signal->{'AMBConversionFrom'} ) ) {
-               $convertFromFunction = $signal->{'AMBConversionFrom'};
-       }
-
-       my $convertToFunction = "nullptr";
-       if ( exists( $signal->{'AMBConversionTo'} ) ) {
-               $convertToFunction = $signal->{'AMBConversionTo'};
-       }
-
-       $generatedText .= "\n";
-       $generatedText .= "/**< $ambPropertyName.\n";
-
-       my $typeBasedText = '';
-       my $cppType;
-
-       if ( $type =~ m/enum/ ) {
-               if ( exists( $signal->{'values'} ) ) {
-                       $generatedText .= " *\@see ${ambPropertyName}s::${ambPropertyName}Type\n";
-                       $cppType = "${ambPropertyName}s::${ambPropertyName}Type";
-               }
-       } elsif ( $type =~ m/bool/ ) {
-               if ( exists( $signal->{'values'} ) ) {
-                       my @dupvalues = @{$signal->{'values'}};
-                       my @values = sort { $$a{'value'} <=> $$b{'value'} } (&removeDuplicates (\@dupvalues));
-                       my $hexValue = ();
-                       for my $vali (0..scalar(@values) -1 ) {
-                               $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
-                               $generatedText .= " * $hexValue = $values[$vali]->{'description'}\n";
-                       }
-               }
-               $cppType = "$type";
-       } elsif ( $type =~ m/int8/ ) {
-               $cppType = "char";
-       } elsif ( $type =~ m/int32/ ) {
-               if ( $type eq 'uint32_t' ) {
-                       $cppType = "$type";
-               } else {
-                       $cppType = "int";
-               }
-       } else {    # (u)int16, (u)int64
-               $cppType = "$type";
-       }
-
-       $typeBasedText .= "CANSIGNAL($ambPropertyName, $cppType, $signal->{'startBit'}, $signal->{'length'}, $byteOrdering, $signedness, $signal->{'factor'}, $signal->{'offset'}, static_cast<$cppType>($signal->{'minValue'}), static_cast<$cppType>($signal->{'maxValue'}), $convertFromFunction, $convertToFunction)\n";
-
-       $generatedText .= " */\n";
-       my $shownPropertyName = $ambPropertyName;
-       if ($hashingAllowed eq 'E' ) {
-               $shownPropertyName = $signal->{'AMBPropertyNameEnc'};
-       }
-       $generatedText .= "const VehicleProperty::Property $ambPropertyName = \"$shownPropertyName\";\n";
-       $generatedText .= $typeBasedText;
-
-       return $generatedText;
+    }
+
+    my $convertFromFunction = "nullptr";
+    if ( exists( $signal->{'AMBConversionFrom'} ) ) {
+        $convertFromFunction = $signal->{'AMBConversionFrom'};
+    }
+
+    my $convertToFunction = "nullptr";
+    if ( exists( $signal->{'AMBConversionTo'} ) ) {
+        $convertToFunction = $signal->{'AMBConversionTo'};
+    }
+
+    $generatedText .= "\n";
+    $generatedText .= "/**< $ambPropertyName.\n";
+
+    my $typeBasedText = '';
+    my $cppType;
+
+    if ( $type =~ m/enum/ ) {
+        if ( exists( $signal->{'values'} ) ) {
+            $generatedText .= " *\@see ${ambPropertyName}s::${ambPropertyName}Type\n";
+            $cppType = "${ambPropertyName}s::${ambPropertyName}Type";
+        }
+    } elsif ( $type =~ m/bool/ ) {
+        if ( exists( $signal->{'values'} ) ) {
+            my @dupvalues = @{$signal->{'values'}};
+            my @values = sort { $$a{'value'} <=> $$b{'value'} } (&removeDuplicates (\@dupvalues));
+            my $hexValue = ();
+            for my $vali (0..scalar(@values) -1 ) {
+                $hexValue = '0x' . uc ( sprintf( "%x", $values[$vali]->{'value'} ) );
+                $generatedText .= " * $hexValue = $values[$vali]->{'description'}\n";
+            }
+        }
+        $cppType = "$type";
+    } elsif ( $type =~ m/int8/ ) {
+        $cppType = "char";
+    } elsif ( $type =~ m/int32/ ) {
+        if ( $type eq 'uint32_t' ) {
+            $cppType = "$type";
+        } else {
+            $cppType = "int";
+        }
+    } else {    # (u)int16, (u)int64
+        $cppType = "$type";
+    }
+
+     $typeBasedText .= "CANSIGNAL($ambPropertyName, $cppType, $signal->{'startBit'}, $signal->{'length'}, $byteOrdering, $signedness, $signal->{'factor'}, $signal->{'offset'}, static_cast<$cppType>($signal->{'minValue'}), static_cast<$cppType>($signal->{'maxValue'}), $convertFromFunction, $convertToFunction)\n";
+
+    $generatedText .= " */\n";
+    my $shownPropertyName = $ambPropertyName;
+    if ($hashingAllowed eq 'E' ) {
+        $shownPropertyName = $signal->{'AMBPropertyNameEnc'};
+    }
+    $generatedText .= "const VehicleProperty::Property $ambPropertyName = \"$shownPropertyName\";\n";
+    $generatedText .= $typeBasedText;
+
+    return $generatedText;
 }
 
 =head2 generateIdlTypes
@@ -500,24 +500,24 @@ Returns IDL code to be placed into the target plugin.
 =cut
 
 sub generateIdlTypes {
-       my $dbcjson = $_[0];
-
-       my $generatedText = '';
-
-       my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
-       for my $ecui (0..scalar(@engineControlUnits)-1) {
-               if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
-                       my @messages = @{$engineControlUnits[$ecui]{'messages'}};
-                       for my $msgi (0..scalar(@messages)-1) {
-                               my @signals = @{$messages[$msgi]{'signals'}};
-                               foreach my $signal ( @signals ) {
-                                       my $type = $signal->{'AMBPropertyType'};
-                                       $generatedText .= &generateIdlProperty( $signal, $type);
-                               }
-                       }
-               }
-       }
-       return $generatedText;
+    my $dbcjson = $_[0];
+
+    my $generatedText = '';
+
+    my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
+    for my $ecui (0..scalar(@engineControlUnits)-1) {
+        if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
+            my @messages = @{$engineControlUnits[$ecui]{'messages'}};
+            for my $msgi (0..scalar(@messages)-1) {
+                my @signals = @{$messages[$msgi]{'signals'}};
+                foreach my $signal ( @signals ) {
+                    my $type = $signal->{'AMBPropertyType'};
+                    $generatedText .= &generateIdlProperty( $signal, $type);
+                }
+            }
+        }
+    }
+    return $generatedText;
 }
 
 =head2 generateIdlProperty
@@ -528,58 +528,58 @@ definitions of one signal property.
 =cut
 
 sub generateIdlProperty {
-       my $signal = $_[0];
-       my $type = $_[1];
-       my $generatedText = '';
-
-       my $ambPropertyName = $signal->{'canId'};
-       if ( exists( $signal->{'AMBPropertyName'} ) ) {
-               $ambPropertyName = $signal->{'AMBPropertyName'};
-       }
-
-       $generatedText .= "[NoInterfaceObject]\n";
-       $generatedText .= "interface org.automotive.${ambPropertyName} : VehiclePropertyType {\n";
-       if ( $type eq 'enum' ) {
-               if ( exists( $signal->{'values'} ) ) {
-                       my @dupvalues = @{$signal->{'values'}};
-                       my @values = sort { $$a{'value'} <=> $$b{'value'} } (&removeDuplicates (\@dupvalues));
-
-                       my $hexValue = ();
-                       for my $vali (0..scalar(@values) -1 ) {
-                               # TODO const unsigned short migth be not enough, guess type based on values
-                               $hexValue = '0x' . uc (sprintf( "%x", $values[$vali]->{'value'} ) );
-                               $generatedText .= "    const unsigned short " . uc($values[$vali]->{'name'}) . " = $hexValue;\n";
-                       }
-               }
-       }
-
-       $generatedText .= "\n";
-       $generatedText .= "    /**  ${ambPropertyName}\n";
-       $generatedText .= "     *   \\brief  Returns ${ambPropertyName}\n";
-       $generatedText .= "     **/\n";
-
-       my $unsigned = '';
-       if ( $type =~ m/uint/ ) {
-               $unsigned = 'unsigned ';
-       }
-
-       if ( $type =~ m/enum/ ) {
-               # TODO const unsigned short migth be not enough, guess type based on values
-               $generatedText .= "    readonly attribute octet ${ambPropertyName};\n";
-       } elsif ( $type =~ m/bool/ ) {
-               $generatedText .= "    readonly attribute boolean ${ambPropertyName};\n";
-       } elsif ( $type =~ m/int8/ ) {
-               $generatedText .= "    readonly attribute ${unsigned}octet ${ambPropertyName};\n";
-       } elsif ( $type =~ m/int16/ ) {
-               $generatedText .= "    readonly attribute ${unsigned}short ${ambPropertyName};\n";
-       } elsif ( $type =~ m/int32/ ) {
-               $generatedText .= "    readonly attribute ${unsigned}long ${ambPropertyName};\n";
-       } else {
-               $generatedText .= "    readonly attribute double ${ambPropertyName};\n";
-       }
-       $generatedText .= "};\n\n";
-
-       return $generatedText;
+    my $signal = $_[0];
+    my $type = $_[1];
+    my $generatedText = '';
+
+    my $ambPropertyName = $signal->{'canId'};
+    if ( exists( $signal->{'AMBPropertyName'} ) ) {
+        $ambPropertyName = $signal->{'AMBPropertyName'};
+    }
+
+    $generatedText .= "[NoInterfaceObject]\n";
+    $generatedText .= "interface org.automotive.${ambPropertyName} : VehiclePropertyType {\n";
+    if ( $type eq 'enum' ) {
+        if ( exists( $signal->{'values'} ) ) {
+            my @dupvalues = @{$signal->{'values'}};
+            my @values = sort { $$a{'value'} <=> $$b{'value'} } (&removeDuplicates (\@dupvalues));
+
+            my $hexValue = ();
+            for my $vali (0..scalar(@values) -1 ) {
+                # TODO const unsigned short migth be not enough, guess type based on values
+                $hexValue = '0x' . uc (sprintf( "%x", $values[$vali]->{'value'} ) );
+                $generatedText .= "    const unsigned short " . uc($values[$vali]->{'name'}) . " = $hexValue;\n";
+            }
+        }
+    }
+
+    $generatedText .= "\n";
+    $generatedText .= "    /**  ${ambPropertyName}\n";
+    $generatedText .= "     *   \\brief  Returns ${ambPropertyName}\n";
+    $generatedText .= "     **/\n";
+
+    my $unsigned = '';
+    if ( $type =~ m/uint/ ) {
+        $unsigned = 'unsigned ';
+    }
+
+    if ( $type =~ m/enum/ ) {
+        # TODO const unsigned short migth be not enough, guess type based on values
+        $generatedText .= "    readonly attribute octet ${ambPropertyName};\n";
+    } elsif ( $type =~ m/bool/ ) {
+        $generatedText .= "    readonly attribute boolean ${ambPropertyName};\n";
+    } elsif ( $type =~ m/int8/ ) {
+        $generatedText .= "    readonly attribute ${unsigned}octet ${ambPropertyName};\n";
+    } elsif ( $type =~ m/int16/ ) {
+        $generatedText .= "    readonly attribute ${unsigned}short ${ambPropertyName};\n";
+    } elsif ( $type =~ m/int32/ ) {
+        $generatedText .= "    readonly attribute ${unsigned}long ${ambPropertyName};\n";
+    } else {
+        $generatedText .= "    readonly attribute double ${ambPropertyName};\n";
+    }
+    $generatedText .= "};\n\n";
+
+    return $generatedText;
 }
 
 =head2 encryptAmbPropertyNames
@@ -589,21 +589,21 @@ Encrypt AmbPropertyNames.
 =cut
 
 sub encryptAmbPropertyNames {
-       my $dbcjson = $_[0];
-
-       my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
-       for my $ecui (0..scalar(@engineControlUnits)-1) {
-               if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
-                       my @messages = @{$engineControlUnits[$ecui]{'messages'}};
-                       for my $msgi (0..scalar(@messages)-1) {
-                               my @signals = @{$messages[$msgi]{'signals'}};
-                               foreach my $signal ( @signals ) {
-                                       my $shownPropertyName = sha1_hex( $signal->{'AMBPropertyName'} );
-                                       $signal->{'AMBPropertyNameEnc'} = 'S' . sha1_hex( $shownPropertyName );
-                               }
-                       }
-               }
-       }
+    my $dbcjson = $_[0];
+
+    my @engineControlUnits = @{$dbcjson->{'electronicControlUnits'}};
+    for my $ecui (0..scalar(@engineControlUnits)-1) {
+        if ( exists( $engineControlUnits[$ecui]{'messages'} ) ) {
+            my @messages = @{$engineControlUnits[$ecui]{'messages'}};
+            for my $msgi (0..scalar(@messages)-1) {
+                my @signals = @{$messages[$msgi]{'signals'}};
+                foreach my $signal ( @signals ) {
+                    my $shownPropertyName = sha1_hex( $signal->{'AMBPropertyName'} );
+                    $signal->{'AMBPropertyNameEnc'} = 'S' . sha1_hex( $shownPropertyName );
+                }
+            }
+        }
+    }
 }
 
 =head2 removeDuplicates
@@ -613,38 +613,38 @@ Returns array of values witout duplicates.
 =cut
 
 sub removeDuplicates {
-       my @arr = sort { $a->{'name'} cmp $b->{'name'} }  @{$_[0]};
-
-       my @duplicates;
-       my $prev = pop @arr;
-
-       while (defined(my $x = pop @arr)) {
-               if ($prev->{'name'} eq $x->{'name'}) {
-                       push @duplicates, $x;
-                       while (defined(my $y = pop @arr)) {
-                               if ($y->{'name'} ne $x->{'name'}) {
-                                       $prev = $y;
-                                       last;
-                               }
-                       }
-               }
-               else {
-                       $prev = $x;
-               }
-       }
-       # Typically very small arrays
-       @arr = sort @{$_[0]};
-       if (scalar @duplicates > 0) {
-               foreach my $x (@arr) {
-                       foreach my $y (@duplicates) {
-                               if ($x->{'name'} eq $y->{'name'}) {
-                                       $x->{'name'} .= '_' . $x->{'value'};
-                               }
-                       }
-               }
-       }
-
-       return @arr;
+    my @arr = sort { $a->{'name'} cmp $b->{'name'} }  @{$_[0]};
+
+    my @duplicates;
+    my $prev = pop @arr;
+
+    while (defined(my $x = pop @arr)) {
+        if ($prev->{'name'} eq $x->{'name'}) {
+            push @duplicates, $x;
+            while (defined(my $y = pop @arr)) {
+                if ($y->{'name'} ne $x->{'name'}) {
+                    $prev = $y;
+                    last;
+                }
+            }
+        }
+        else {
+            $prev = $x;
+        }
+    }
+    # Typically very small arrays
+    @arr = sort @{$_[0]};
+    if (scalar @duplicates > 0) {
+        foreach my $x (@arr) {
+            foreach my $y (@duplicates) {
+                if ($x->{'name'} eq $y->{'name'}) {
+                    $x->{'name'} .= '_' . $x->{'value'};
+                }
+            }
+        }
+    }
+
+    return @arr;
 }
 
 =head2 calculateZone
@@ -654,19 +654,19 @@ Returns calculated Zone for given signal.
 =cut
 
 sub calculateZone {
-       my $ambPropertyName = $_[0];
-       my $zone = 'Zone::None';
-
-       if ( $ambPropertyName =~ m/FrL/) {
-               $zone = 'Zone::FrontLeft';
-       } elsif ( $ambPropertyName =~ m/FrR/) {
-               $zone = 'Zone::FrontRight';
-       } elsif ( $ambPropertyName =~ m/ReL/) {
-               $zone = 'Zone::RearLeft';
-       } elsif ( $ambPropertyName =~ m/ReR/) {
-               $zone = 'Zone::RearRight';
-       }
-       return $zone;
+    my $ambPropertyName = $_[0];
+    my $zone = 'Zone::None';
+
+    if ( $ambPropertyName =~ m/FrL/) {
+        $zone = 'Zone::FrontLeft';
+    } elsif ( $ambPropertyName =~ m/FrR/) {
+        $zone = 'Zone::FrontRight';
+    } elsif ( $ambPropertyName =~ m/ReL/) {
+        $zone = 'Zone::RearLeft';
+    } elsif ( $ambPropertyName =~ m/ReR/) {
+        $zone = 'Zone::RearRight';
+    }
+    return $zone;
 }
 
 ##############################################################################
@@ -679,7 +679,7 @@ IntelIVIPoc, C<< <ivipoc at intel.com> >>
 
 You can find documentation for this module with the perldoc command.
 
-       perldoc Intel::IVIPoc::AMBPluginGenerator
+    perldoc Intel::IVIPoc::AMBPluginGenerator
 
 
 =head1 ACKNOWLEDGEMENTS