added tools
authorKevron Rees <kevron.m.rees@intel.com>
Thu, 24 Apr 2014 22:40:15 +0000 (15:40 -0700)
committerKevron Rees <kevron.m.rees@intel.com>
Fri, 11 Jul 2014 19:56:31 +0000 (12:56 -0700)
26 files changed:
tools/AmbSignalMapper/.gitignore [new file with mode: 0644]
tools/AmbSignalMapper/Changes [new file with mode: 0644]
tools/AmbSignalMapper/MANIFEST [new file with mode: 0644]
tools/AmbSignalMapper/Makefile.PL [new file with mode: 0644]
tools/AmbSignalMapper/README [new file with mode: 0644]
tools/AmbSignalMapper/bin/dbc2json [new file with mode: 0755]
tools/AmbSignalMapper/bin/json2amb [new file with mode: 0755]
tools/AmbSignalMapper/dbc2json.html [new file with mode: 0644]
tools/AmbSignalMapper/json2amb.html [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/AmbCommon.pm [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/AmbPluginGenerator.pm [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/DbcGrammar [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/DbcGrammar.pod [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/CMakeLists.txt [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignal.cpp [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignal.h [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignals.h [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.cpp [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.h [new file with mode: 0644]
tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.idl [new file with mode: 0644]
tools/AmbSignalMapper/t/00-load.t [new file with mode: 0644]
tools/AmbSignalMapper/t/ambsignalmapper.t [new file with mode: 0644]
tools/AmbSignalMapper/t/boilerplate.t [new file with mode: 0644]
tools/AmbSignalMapper/t/manifest.t [new file with mode: 0644]
tools/AmbSignalMapper/t/pod-coverage.t [new file with mode: 0644]
tools/AmbSignalMapper/t/pod.t [new file with mode: 0644]

diff --git a/tools/AmbSignalMapper/.gitignore b/tools/AmbSignalMapper/.gitignore
new file mode 100644 (file)
index 0000000..2133cf4
--- /dev/null
@@ -0,0 +1,18 @@
+Makefile
+Makefile.old
+Build
+Build.bat
+META.*
+MYMETA.*
+.build/
+_build/
+cover_db/
+blib/
+inc/
+.lwpcookies
+.last_cover_stats
+nytprof.out
+pod2htm*.tmp
+pm_to_blib
+AmbSignalMapper-*
+AmbSignalMapper-*.tar.gz
diff --git a/tools/AmbSignalMapper/Changes b/tools/AmbSignalMapper/Changes
new file mode 100644 (file)
index 0000000..e514979
--- /dev/null
@@ -0,0 +1,5 @@
+Revision history for AmbSignalMapper
+
+0.01    Date/time
+        First version, released on an unsuspecting world.
+
diff --git a/tools/AmbSignalMapper/MANIFEST b/tools/AmbSignalMapper/MANIFEST
new file mode 100644 (file)
index 0000000..02a5ad5
--- /dev/null
@@ -0,0 +1,23 @@
+Changes
+Makefile.PL
+MANIFEST                       This list of files
+README
+bin/dbc2json
+bin/json2amb
+lib/Intel/IviPoc/DbcGrammar
+lib/Intel/IviPoc/DbcGrammar.pod
+lib/Intel/IviPoc/AmbPluginGenerator.pm
+lib/Intel/IviPoc/AmbCommon.pm
+lib/Intel/IviPoc/templates/ambtmpl_plugin.h
+lib/Intel/IviPoc/templates/ambtmpl_plugin.cpp
+lib/Intel/IviPoc/templates/ambtmpl_plugin.idl
+lib/Intel/IviPoc/templates/ambtmpl_cansignal.h
+lib/Intel/IviPoc/templates/ambtmpl_cansignal.cpp
+lib/Intel/IviPoc/templates/ambtmpl_cansignals.h
+lib/Intel/IviPoc/templates/CMakeLists.txt
+t/00-load.t
+t/ambsignalmapper.t
+t/manifest.t
+t/pod-coverage.t
+t/pod.t
+t/boilerplate.t
diff --git a/tools/AmbSignalMapper/Makefile.PL b/tools/AmbSignalMapper/Makefile.PL
new file mode 100644 (file)
index 0000000..bae450e
--- /dev/null
@@ -0,0 +1,72 @@
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use ExtUtils::MakeMaker;
+
+our @EXCLUSIONS=();
+our $MORE_MAKERULES='';
+
+compile_DbcGrammar();
+
+WriteMakefile(
+       NAME             => 'Intel::IviPoc::AmbPluginGenerator',
+       AUTHOR           => q{Intel IVI PoC <ivipoc@intel.com>},
+       VERSION_FROM     => 'lib/Intel/IviPoc/AmbPluginGenerator.pm',
+       ABSTRACT_FROM    => 'lib/Intel/IviPoc/AmbPluginGenerator.pm',
+       LICENSE          => 'LGPL2.1',
+       PL_FILES         => {},
+       MIN_PERL_VERSION => 5.006,
+       CONFIGURE_REQUIRES => {
+               'ExtUtils::MakeMaker' => 0,
+       },
+       BUILD_REQUIRES => {
+               'Test::More' => 0,
+               'Parse::RecDescent' => 0,
+       },
+       PREREQ_PM => {
+               'Exporter'=>0,
+               'JSON'=>0,
+               'Data::UUID'=>0,
+               'File::Basename'=>0,
+               'File::Spec'=>0,
+               'Cwd'=>0,
+               'Digest::SHA1'=>0,
+               #'Config::General'=>0,
+       },
+       EXE_FILES => [ 'bin/dbc2json','bin/json2amb'],
+       dist  => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+       clean => { FILES => 'AmbSignalMapper-*' },
+);
+
+# Overriding ExtUtils::MM methods
+# --------------------------------------------------------------------
+# Exclude the sources used to generate others from the build (See below).
+sub MY::libscan {
+my($self,$path)=@_;
+       if(($path =~ /~$/) || grep($path eq $_, @EXCLUSIONS)){
+               return ""; }
+       $self->MY::SUPER::libscan($path); }
+
+# Append any additional Makefile rules added by the following.
+sub MY::postamble {
+       shift->MY::SUPER::postamble(@_) . $MORE_MAKERULES; }
+
+# Compile the RecDescent grammar during make; 
+sub compile_DbcGrammar {
+       push(@EXCLUSIONS,'blib/lib/Intel/IviPoc/DbcGrammar');
+       $MORE_MAKERULES .= <<'MakeGrammar';
+
+# Precompile the (Recursive Descent) DbcGrammar
+pure_all :: $(INST_LIBDIR)/Intel/IviPoc/DbcGrammar.pm
+
+$(INST_LIBDIR)/Intel/IviPoc/DbcGrammar.pm: lib/Intel/IviPoc/DbcGrammar
+       $(PERLRUN) -MParse::RecDescent - lib/Intel/IviPoc/DbcGrammar Intel::IviPoc::DbcGrammar
+       $(NOECHO) $(MKPATH) $(INST_LIBDIR)/Intel/IviPoc
+       $(MV) -f DbcGrammar.pm blib/lib/Intel/IviPoc/DbcGrammar.pm
+       $(CHMOD) $(PERM_RWX) bin/dbc2json
+       $(CHMOD) $(PERM_RWX) bin/json2amb
+
+MakeGrammar
+}
+
+
diff --git a/tools/AmbSignalMapper/README b/tools/AmbSignalMapper/README
new file mode 100644 (file)
index 0000000..42907f5
--- /dev/null
@@ -0,0 +1,77 @@
+AmbSignalMapper
+
+ABSTRACT:
+
+The AmbSignalMapper tool serves basic utilities for AMB signal mapping process.
+It should take place in three steps:
+
+1. Vector CANdb++ conversion into intermediate file (First phase)
+2. Manual annotation of intermediate file (Second phase)
+3. Processing of intermediate file and AMB plugin and WebIDL creation (Third phase)
+
+The First phase is achieved by software utolity called dbc2json.
+The second phase needs to be done by humans manually.
+The third phase is again covered by software utolity called json2amb. 
+
+PREREQUISITES:
+
+Perl version 5.006 or higher.
+
+The following modules are needed to succesfuly build and run the AmbSignalMapper tool:
+    'ExtUtils::MakeMaker'
+    'Test::More',
+    'Parse::RecDescent',
+    'Exporter',
+    'JSON',
+    'Data::UUID',
+    'File::Basename',
+    'File::Spec',
+    'Cwd',
+    'Digest::SHA1'.
+
+These modules are optional for executing moodule tests:
+    'Test::Pod',
+    'Test::Pod::Coverage',
+
+The following command is an example of Data::UUID module instalation.
+Note that sudo credentials might be needed on users linux box. 
+    
+    cpan install Data::UUID
+
+INSTALLATION
+
+To install this module, run the following commands:
+
+    perl Makefile.PL
+    make
+    make test
+    make install
+
+SUPPORT AND DOCUMENTATION
+
+After installing, you can find documentation for this module with the
+perldoc command.
+
+    perldoc dbc2json
+    
+    perldoc json2amb   
+
+LICENSE AND COPYRIGHT
+
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
diff --git a/tools/AmbSignalMapper/bin/dbc2json b/tools/AmbSignalMapper/bin/dbc2json
new file mode 100755 (executable)
index 0000000..e96f867
--- /dev/null
@@ -0,0 +1,204 @@
+#!/usr/bin/perl -w
+
+#      Copyright (C) 2014  Intel Corporation
+#
+#      This library is free software; you can redistribute it and/or
+#      modify it under the terms of the GNU Lesser General Public
+#      License as published by the Free Software Foundation; either
+#      version 2.1 of the License, or (at your option) any later version.
+#
+#      This library is distributed in the hope that it will be useful,
+#      but WITHOUT ANY WARRANTY; without even the implied warranty of
+#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#      Lesser General Public License for more details.
+#
+#      You should have received a copy of the GNU Lesser General Public
+#      License along with this library; if not, write to the Free Software
+#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+use strict;
+use warnings;
+
+use Intel::IviPoc::DbcGrammar;
+use Intel::IviPoc::AmbCommon;
+use File::Basename;
+use File::Spec;
+use Cwd;
+use JSON;
+
+
+=head1 NAME
+
+dbc2json - Vector CANdb++ to JSON file format converter.
+
+=head1 SYNOPSIS
+
+B<dbc2json> I<infile> [ I<outfile> ]
+
+=head1 DESCRIPTION
+
+Part of Automotive Message Broker Signal Mapper tool.
+
+B<dbc2json> converts file in Vector CANdb++ format to intermediate JSON file.
+
+Intermediate file is used to format and annotate raw data from CANDb++ file into format suitable for AMB plugin creation.
+
+=head1 OPTIONS
+
+=over 4
+
+=item I<infile>
+
+Input I<infile> file in Vector CANdb++ (*.dbc) format.
+
+=item [ I<outfile> ]
+
+Target output I<outfile> file converted to JSON, otherwise created in current directory.
+
+=back
+
+=head1 FILES
+
+=over 4
+
+=back
+
+=head1 REQUIRES
+
+Perl 5.006, Intel::IviPoc::DbcGrammar, File::Basename, File::Spec, Cwd, JSON
+
+=head1 SEE ALSO
+
+perl(1), json2amb(1)
+
+=cut
+
+local $/;
+
+# get total arg passed to this script
+my $total = $#ARGV + 1;
+
+if ( $total < 1 or $total > 2) {
+    # get script name and print usage
+    my $scriptname = $0;
+    &printUsage($scriptname);
+    exit;
+    }
+
+# First parameter is input file
+my $inputfilename = $ARGV[0];
+my $text = &readFileContent($inputfilename);
+
+# Second optional parameter is output file
+my $outputfilename = '';
+if ( $total == 1 ) {
+    my ($infilename, $indirectories, $insuffix) = fileparse($inputfilename, qr/\.[^.]*/);
+    my $targetDir = getcwd;
+    $outputfilename = File::Spec->catfile( ($targetDir), $infilename . '.json' );
+} else {
+    $outputfilename = $ARGV[1];
+}
+
+# We add one space if there is something like  ""ReceiverId to get "" ReceiverId
+$text =~ s/"(.*)"(\w*)/"$1" $2/g;
+
+#Create parser
+my $parser = new Intel::IviPoc::DbcGrammar;
+
+# Print wait info for user
+&printWait($inputfilename, $outputfilename);
+
+# Parse input file and generate json
+my $result;
+$result = $parser->DbcOutput($text);
+my %jsonroot = %{$result};
+
+# Get the filename without path and extension and set it as pluginName
+my ($outfilename, $outdirectories, $outsuffix) = fileparse($outputfilename, qr/\.[^.]*/);
+$jsonroot{'pluginName'} = $outfilename;
+
+# Now just spit the JSON out
+my $json = JSON->new;
+$json = $json->utf8;
+my $json_text = $json->pretty->encode( \%jsonroot  );
+
+open (my $fho, '>', $outputfilename)
+  or die "Can't create filehandle: $!";
+
+binmode($fho, ":utf8");
+
+print { $fho } $json_text;
+
+if ( $total == 1 or $total == 2 ) {
+    # close current output file
+    close($fho);
+}
+
+# Finnish
+exit;
+
+=head2 printWait
+
+Prints out wait information
+
+=cut
+
+sub printWait {
+    print STDERR ("\n");
+    print STDERR ("Processing input file:\n");
+    print STDERR ("    $_[0]\n");
+    print STDERR ("Generating output file:\n");
+    print STDERR ("    $_[1]\n");
+    print STDERR ("\n");
+    print STDERR ("This operation may take some while. Please wait...\n");
+    print STDERR ("\n");
+    print STDERR ("\n");
+}
+
+=head2 printUsage
+
+Prints out basic usage help
+
+=cut
+
+sub printUsage {
+    my $scriptname=$_[0];
+    print STDERR ("$scriptname\n");
+    print STDERR ("Usage: dbc2json infile [outfile]\n");
+    print STDERR ("  infile              Input dbc file\n");
+    print STDERR ("  outfile             File (optional) converted to json,\n");
+    print STDERR ("                      otherwise created in current directory.\n");
+    print STDERR ("\n");
+}
+
+=head1 AUTHOR
+
+IntelIVIPoc, C<< <ivipoc at intel.com> >>
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc dbc2json
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 LICENSE AND COPYRIGHT
+
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+=cut
diff --git a/tools/AmbSignalMapper/bin/json2amb b/tools/AmbSignalMapper/bin/json2amb
new file mode 100755 (executable)
index 0000000..7e39e98
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/perl -w
+
+#      Copyright (C) 2014  Intel Corporation
+#
+#      This library is free software; you can redistribute it and/or
+#      modify it under the terms of the GNU Lesser General Public
+#      License as published by the Free Software Foundation; either
+#      version 2.1 of the License, or (at your option) any later version.
+#
+#      This library is distributed in the hope that it will be useful,
+#      but WITHOUT ANY WARRANTY; without even the implied warranty of
+#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#      Lesser General Public License for more details.
+#
+#      You should have received a copy of the GNU Lesser General Public
+#      License along with this library; if not, write to the Free Software
+#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+
+use Intel::IviPoc::AmbPluginGenerator qw(processPlugin);
+use Cwd;
+
+=head1 NAME
+
+json2amb - JSON to Automotive Message Broker plugin generator.
+
+=head1 SYNOPSIS
+
+B<json2amb> B<-e|-E> | B<-d|-D> I<infile> [ I<outdir> ]
+
+=head1 DESCRIPTION
+
+Part of Automotive Message Broker Signal Mapper tool.
+
+B<json2amb> converts intermediate JSON file to Automotive Message Broker plugin.
+
+B<json2amb> - The command line interface for Intel::IviPoc::AmbPluginGenerator.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-e|-E>
+
+Signal encryption enabled.
+
+=item B<-d|-D>
+
+Signal encryption disabled
+
+=item I<filename>
+
+Input json file.
+
+=item [ I<outdir> ]
+
+    This parameter is optional. Target directory where the plugin is generated to.
+    Otherwise current directory.
+
+=back
+
+=head1 FILES
+
+=over 4
+
+=back
+
+=head1 REQUIRES
+
+Perl 5.006, Cwd, Intel::IviPoc::AmbPluginGenerator, Intel::IviPoc::AmbCommon
+
+=head1 SEE ALSO
+
+perl(1), dbc2json(1)
+
+=cut
+
+local $/;
+
+# get total arg passed to this script
+my $total = $#ARGV + 1;
+my $scriptname = $0;
+if ( $total < 1) {
+    # get script name and print usage
+    &printUsage($scriptname);
+    exit;
+    }
+
+my $hashingAllowed = 'E';
+if ( $ARGV[0] eq '-e' or $ARGV[0] eq '-E' ) {
+    $hashingAllowed = 'E';
+} elsif ( $ARGV[0] eq '-d' or $ARGV[0] eq '-D' ) {
+    $hashingAllowed = 'D';
+} else {
+    print STDERR ("\nERROR: Invalid input option $ARGV[0]\n\n");
+    &printUsage($scriptname);
+    exit;
+}
+
+my $targetDir = ();
+if ($total == 2) {
+    $targetDir = getcwd;
+} else {
+    $targetDir = Cwd::abs_path($ARGV[2]);
+}
+
+# Generate the plaugin
+processPlugin ( $hashingAllowed, $ARGV[1], $targetDir );
+
+# Finnish
+exit;
+
+=head2 printUsage
+
+Prints out basic usage help
+
+=cut
+
+sub printUsage {
+    my $scriptname=$_[0];
+    print STDERR ("$scriptname\n");
+    print STDERR ("Usage: json2amb enc infile [outdir]\n");
+    print STDERR ("  enc:            mandatory signal encryption option\n");
+    print STDERR ("    -e                    Signal encryption enabled\n");
+    print STDERR ("    -d                    Signal encryption disabled\n");
+    print STDERR ("  infile              Input json file\n");
+    print STDERR ("  outdir              Target plugin directory (optional) generated to,\n");
+    print STDERR ("                      otherwise current directory.\n");
+}
+
+=head1 AUTHOR
+
+IntelIVIPoc, C<< <ivipoc at intel.com> >>
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc json2amb
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 LICENSE AND COPYRIGHT
+
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+=cut
diff --git a/tools/AmbSignalMapper/dbc2json.html b/tools/AmbSignalMapper/dbc2json.html
new file mode 100644 (file)
index 0000000..e16cdf0
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><title>dbc2json</title>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >
+</head>
+<body class='pod'>
+<!--
+  generated by Pod::Simple::HTML v3.22,
+  using Pod::Simple::PullParser v3.22,
+  under Perl v5.014002 at Tue Jan  7 15:04:44 2014 GMT.
+
+ If you want to change this HTML document, you probably shouldn't do that
+   by changing it directly.  Instead, see about changing the calling options
+   to Pod::Simple::HTML, and/or subclassing Pod::Simple::HTML,
+   then reconverting this document from the Pod source.
+   When in doubt, email the author of Pod::Simple::HTML for advice.
+   See 'perldoc Pod::Simple::HTML' for more info.
+
+-->
+
+<!-- start doc -->
+<a name='___top' class='dummyTopAnchor' ></a>
+
+<h1><a class='u'
+name="NAME"
+>NAME</a></h1>
+
+<p>dbc2json - Vector CANdb++ to JSON file format converter.</p>
+
+<h1><a class='u'
+name="SYNOPSIS"
+>SYNOPSIS</a></h1>
+
+<p><b>dbc2json</b> <i>infile</i> [ <i>outfile</i> ]</p>
+
+<h1><a class='u'
+name="DESCRIPTION"
+>DESCRIPTION</a></h1>
+
+<p>Part of Automotive Message Broker Signal Mapper tool.</p>
+
+<p><b>dbc2json</b> converts file in Vector CANdb++ format to intermediate JSON file.</p>
+
+<p>Intermediate file is used to format and annotate raw data from CANDb++ file into format suitable for AMB plugin creation.</p>
+
+<h1><a class='u'
+name="OPTIONS"
+>OPTIONS</a></h1>
+
+<dl>
+<dt><a name="infile"
+><i>infile</i></a></dt>
+
+<dd>
+<p>Input <i>infile</i> file in Vector CANdb++ (*.dbc) format.</p>
+
+<dt><a name="[_outfile_]"
+>[ <i>outfile</i> ]</a></dt>
+
+<dd>
+<p>Target output <i>outfile</i> file converted to JSON,
+otherwise created in current directory.</p>
+</dd>
+</dl>
+
+<h1><a class='u'
+name="FILES"
+>FILES</a></h1>
+
+<h1><a class='u'
+name="REQUIRES"
+>REQUIRES</a></h1>
+
+<p>Perl 5.006,
+Intel::IviPoc::DbcGrammar,
+File::Basename,
+File::Spec,
+Cwd,
+JSON</p>
+
+<h1><a class='u'
+name="SEE_ALSO"
+>SEE ALSO</a></h1>
+
+<p>perl(1),
+json2amb(1)</p>
+
+<h2><a class='u'
+name="readFileContent"
+>readFileContent</a></h2>
+
+<p>Reads and returns the whole content of given file.</p>
+
+<h2><a class='u'
+name="printWait"
+>printWait</a></h2>
+
+<p>Prints out wait information</p>
+
+<h2><a class='u'
+name="printUsage"
+>printUsage</a></h2>
+
+<p>Prints out basic usage help</p>
+
+<h1><a class='u'
+name="AUTHOR"
+>AUTHOR</a></h1>
+
+<p>IntelIVIPoc,
+<code>&#60;ivipoc at intel.com&#62;</code></p>
+
+<h1><a class='u'
+name="SUPPORT"
+>SUPPORT</a></h1>
+
+<p>You can find documentation for this module with the perldoc command.</p>
+
+<pre>    perldoc dbc2json</pre>
+
+<h1><a class='u'
+name="ACKNOWLEDGEMENTS"
+>ACKNOWLEDGEMENTS</a></h1>
+
+<h1><a class='u'
+name="LICENSE_AND_COPYRIGHT"
+>LICENSE AND COPYRIGHT</a></h1>
+
+<p>Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA</p>
+<!-- end doc -->
+
+</body></html>
diff --git a/tools/AmbSignalMapper/json2amb.html b/tools/AmbSignalMapper/json2amb.html
new file mode 100644 (file)
index 0000000..a0f26ee
--- /dev/null
@@ -0,0 +1,139 @@
+<html><head><title>json2amb</title>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >
+</head>
+<body class='pod'>
+<!--
+  generated by Pod::Simple::HTML v3.22,
+  using Pod::Simple::PullParser v3.22,
+  under Perl v5.014002 at Tue Jan  7 15:05:00 2014 GMT.
+
+ If you want to change this HTML document, you probably shouldn't do that
+   by changing it directly.  Instead, see about changing the calling options
+   to Pod::Simple::HTML, and/or subclassing Pod::Simple::HTML,
+   then reconverting this document from the Pod source.
+   When in doubt, email the author of Pod::Simple::HTML for advice.
+   See 'perldoc Pod::Simple::HTML' for more info.
+
+-->
+
+<!-- start doc -->
+<a name='___top' class='dummyTopAnchor' ></a>
+
+<h1><a class='u'
+name="NAME"
+>NAME</a></h1>
+
+<p>json2amb - JSON to Automotive Message Broker plugin generator.</p>
+
+<h1><a class='u'
+name="SYNOPSIS"
+>SYNOPSIS</a></h1>
+
+<p><b>json2amb</b> <b>-e|-E</b> | <b>-d|-D</b> <i>infile</i> [ <i>outdir</i> ]</p>
+
+<h1><a class='u'
+name="DESCRIPTION"
+>DESCRIPTION</a></h1>
+
+<p>Part of Automotive Message Broker Signal Mapper tool.</p>
+
+<p><b>json2amb</b> converts intermediate JSON file to Automotive Message Broker plugin.</p>
+
+<p><b>json2amb</b> - The command line interface for Intel::IviPoc::AmbPluginGenerator.</p>
+
+<h1><a class='u'
+name="OPTIONS"
+>OPTIONS</a></h1>
+
+<dl>
+<dt><a name="-e|-E"
+><b>-e|-E</b></a></dt>
+
+<dd>
+<p>Signal encryption enabled.</p>
+
+<dt><a name="-d|-D"
+><b>-d|-D</b></a></dt>
+
+<dd>
+<p>Signal encryption disabled</p>
+
+<dt><a name="filename"
+><i>filename</i></a></dt>
+
+<dd>
+<p>Input json file.</p>
+
+<dt><a name="[_outdir_]"
+>[ <i>outdir</i> ]</a></dt>
+
+<dd>
+<pre>    This parameter is optional. Target directory where the plugin is generated to.
+    Otherwise current directory.</pre>
+</dd>
+</dl>
+
+<h1><a class='u'
+name="FILES"
+>FILES</a></h1>
+
+<h1><a class='u'
+name="REQUIRES"
+>REQUIRES</a></h1>
+
+<p>Perl 5.006, Cwd, Intel::IviPoc::AmbPluginGenerator</p>
+
+<h1><a class='u'
+name="SEE_ALSO"
+>SEE ALSO</a></h1>
+
+<p>perl(1), dbc2json(1)</p>
+
+<h2><a class='u'
+name="printUsage"
+>printUsage</a></h2>
+
+<p>Prints out basic usage help</p>
+
+<h1><a class='u'
+name="AUTHOR"
+>AUTHOR</a></h1>
+
+<p>IntelIVIPoc, <code>&#60;ivipoc at intel.com&#62;</code></p>
+
+<h1><a class='u'
+name="SUPPORT"
+>SUPPORT</a></h1>
+
+<p>You can find documentation for this module with the perldoc command.</p>
+
+<pre>    perldoc json2amb</pre>
+
+<h1><a class='u'
+name="ACKNOWLEDGEMENTS"
+>ACKNOWLEDGEMENTS</a></h1>
+
+<h1><a class='u'
+name="LICENSE_AND_COPYRIGHT"
+>LICENSE AND COPYRIGHT</a></h1>
+
+
+<p>Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA</p>
+
+<!-- end doc -->
+
+</body></html>
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/AmbCommon.pm b/tools/AmbSignalMapper/lib/Intel/IviPoc/AmbCommon.pm
new file mode 100644 (file)
index 0000000..b2957a3
--- /dev/null
@@ -0,0 +1,212 @@
+#Copyright (C) 2014  Intel Corporation
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#Lesser General Public License for more details.
+#
+#You should have received a copy of the GNU Lesser General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+package Intel::IviPoc::AmbCommon;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(evaluateType readFileContent);
+
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Exporter;
+
+=head1 NAME
+
+Intel::IviPoc::AmbCommon - The great new Intel::IviPoc::AmbCommon!
+
+=head1 VERSION
+
+Version 0.01
+
+=cut
+
+our $VERSION = '0.01';
+
+
+=head1 SYNOPSIS
+
+Module provides subroutines for reading input JSON file and generating Automotive Message Broker
+plugin project.
+
+The following little code snippet shows the module usage.
+
+    use Intel::IviPoc::AmbCommon;
+
+    $signal->{'AMBPropertyType'} = &evaluateType($signal);
+    ...
+
+=head1 EXPORT
+
+The following convenience methods are provided by this module. They are
+exported by default:
+
+=over 4
+
+=item C<processPlugin $signal>
+
+For given signal file name generates the Automotive Message Broker plugin
+
+=back
+
+=head1 SUBROUTINES/METHODS
+
+=head2 evaluateType
+
+Copies all template files into target folder while replacing the name
+with newly generated plugin name. Then generates C++ and IDL definitions
+based on information comming from input JSON file.
+
+=cut
+
+sub evaluateType {
+    my $signal = $_[0];
+    my $type = undef;
+
+    if ($signal->{'factor'} == 1) {
+        if ($signal->{'length'} == 1) {
+            $type = 'bool';
+        } else {
+            my $count = -1;
+            if ( exists( $signal->{'values'} ) ) {
+                $count = @{$signal->{'values'}};
+            }
+            if ($count == (2**$signal->{'length'})) {
+                $type = 'enum';
+            } else {
+                $type = &evalIntType( $signal );
+            }
+        }
+    }
+    else {
+        if ( $signal->{'factor'} =~ /\.|[eE]/ ) {
+            $type = 'double';
+        } else {
+            $type = &evalIntType( $signal );
+        }
+    }
+
+return $type;
+}
+
+=head2 evalIntType
+
+Copies one template file into target folder while replacing the name
+with newly generated plugin name. Then generates definitions
+based on information comming from input JSON file.
+
+=cut
+
+sub evalIntType {
+    my $signal = $_[0];
+    my $type = '';
+
+    my $signedness = '';
+
+    my $min = 0;
+    my $max = 0;
+    if ($signal->{'signedness'} eq '+') {
+        # unsigned
+        $min = $signal->{'offset'} + $signal->{'factor'} * 0;
+        $max = $signal->{'offset'} + $signal->{'factor'} * ((2**$signal->{'length'} ) - 1);
+    }  else {
+        # signed
+        $min = $signal->{'offset'} - $signal->{'factor'} * (2**$signal->{'length'} - 1);
+        $max = $signal->{'offset'} + $signal->{'factor'} * (2**$signal->{'length'} - 1);
+    }
+
+    if ( 0 <= $min && $max < (2**8) ) {
+        $type = "uint8_t";
+    } elsif ( -1*(2**7) <= $min && $max < (2**7) ) {
+        $type = "int8_t";
+    } elsif ( 0 <= $min && $max < (2**16) ) {
+        $type = "uint16_t";
+    } elsif ( -1*(2**15) <= $min && $max < (2**15)  ) {
+        $type = "int16_t";
+    } elsif ( 0 <= $min && $max < (2**32) ) {
+        $type = "uint32_t";
+    } elsif ( -1*(2**31) <= $min && $max < (2**31)  ) {
+        $type = "int32_t";
+    } elsif ( 0 <= $min && $max < (2**64) ) {
+        $type = "uint64_t";
+    } else {
+        $type = "int64_t";
+    }
+
+    return $type;
+}
+
+=head2 readFileContent
+
+Reads and returns the whole content of given file.
+
+=cut
+
+sub readFileContent {
+    my $fileName = $_[0];
+    open(my $tmpl, '<', $fileName)
+        or die "Could not open file '$fileName' $!";
+
+    # Copy data from one file to another.
+    my $fileContent = <$tmpl>;
+
+    close $tmpl;
+
+    return $fileContent;
+}
+
+##############################################################################
+
+=head1 AUTHOR
+
+IntelIVIPoc, C<< <ivipoc at intel.com> >>
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc Intel::IVIPoc::AmbCommon
+
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 LICENSE AND COPYRIGHT
+
+INTEL CONFIDENTIAL
+Copyright 2011 - 2013 Intel Corporation All Rights Reserved.
+
+The source code contained or described herein and all documents related to the
+source code("Material") are owned by Intel Corporation or its suppliers or
+licensors.Title to the Material remains with Intel Corporation or its
+suppliers and licensors.The Material may contain trade secrets and proprietary
+and confidential information of Intel Corporation and its suppliers and
+licensors, and is protected by worldwide copyright and trade secret laws and
+treaty provisions.No part of the Material may be used, copied, reproduced,
+modified, published, uploaded, posted, transmitted, distributed, or disclosed
+in any way without Intels prior express written permission.
+No license under any patent, copyright, trade secret or other intellectual
+property right is granted to or conferred upon you by disclosure or delivery
+of the Materials, either expressly, by implication, inducement, estoppel or
+otherwise.Any license under such intellectual property rights must be
+express and approved by Intel in writing.
+
+Unless otherwise agreed by Intel in writing, you may not remove or alter this
+notice or any other notice embedded in Materials by Intel or Intels suppliers
+or licensors in any way.
+
+
+=cut
+
+1; # End of Intel::IviPoc::AmbCommon
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/AmbPluginGenerator.pm b/tools/AmbSignalMapper/lib/Intel/IviPoc/AmbPluginGenerator.pm
new file mode 100644 (file)
index 0000000..88fb708
--- /dev/null
@@ -0,0 +1,718 @@
+#Copyright (C) 2014  Intel Corporation
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#Lesser General Public License for more details.
+#
+#You should have received a copy of the GNU Lesser General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+package Intel::IviPoc::AmbPluginGenerator;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(processPlugin);
+
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Exporter;
+
+use JSON;
+use Data::UUID;
+use File::Spec;
+use Digest::SHA qw(sha1_hex);
+use Intel::IviPoc::AmbCommon  qw(readFileContent);
+
+=head1 NAME
+
+Intel::IviPoc::AmbPluginGenerator - The great new Intel::IviPoc::AmbPluginGenerator!
+
+=head1 VERSION
+
+Version 0.01
+
+=cut
+
+our $VERSION = '0.01';
+
+
+=head1 SYNOPSIS
+
+Module provides subroutines for reading input JSON file and generating Automotive Message Broker
+plugin project.
+
+The following little code snippet shows the module usage.
+
+    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 );
+    ...
+
+=head1 EXPORT
+
+The following convenience methods are provided by this module. They are
+exported by default:
+
+=over 4
+
+=item C<processPlugin $json_filename>
+
+For given json file name generates the Automotive Message Broker plugin
+
+=back
+
+=head1 SUBROUTINES/METHODS
+
+=head2 processPlugin
+
+Copies all template files into target folder while replacing the name
+with newly generated plugin name. Then generates C++ and IDL definitions
+based on information comming from input JSON file.
+
+=cut
+
+my $hashingAllowed = 'E';       # Enabled by default
+
+sub processPlugin {
+    $hashingAllowed = $_[0];
+    my $jsonfile = $_[1];
+    my $targetDir = $_[2];
+    
+    # Load the json
+    my $json_text = &readFileContent( $jsonfile );
+
+    my $json = JSON->new;
+    $json = $json->utf8;
+
+    my $dbcjson = $json->decode( $json_text );
+    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"
+                         );
+
+    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"
+                      );
+
+    my @generationSubs = ( undef
+                         , undef
+                         , undef
+                         , \&generateUuid
+                         , \&generateCppImplTypes
+                         , \&generateSignalsTypes
+                         , \&generateIdlTypes
+                         );
+
+    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]);
+    }
+}
+
+=head2 generatePluginFile
+
+Copies one template file into target folder while replacing the name
+with newly generated plugin name. Then generates definitions
+based on information comming from input JSON file.
+
+=cut
+
+sub generatePluginFile {
+    my $srcFileName = $_[0];
+    my $dstFileName = $_[1];
+    my $dbcjson = $_[2];
+    my $generationSub = $_[3];
+
+    my $pluginName = $dbcjson->{'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;
+    }
+
+    # Create new file
+    my $pluginFileHandle = &createFile( $dstFileName );
+
+    # Copy data from one file to another.
+    print $pluginFileHandle $content;
+
+    # close the file
+    close ($pluginFileHandle);
+}
+
+=head2 createDirectory
+
+Creates directory for plugin.
+
+=cut
+
+sub createDirectory {
+    my $dirName = $_[0];
+
+    unless(-e $dirName or mkdir $dirName) {
+        die "Unable to create directory '$dirName' $!";
+    }
+}
+
+=head2 createFile
+
+Creates file and returns a file handle to it.
+
+=cut
+
+sub createFile {
+    my $fileName = $_[0];
+
+    # Open file or die
+    open(my $fileHandle, '>', $fileName)
+        or die "Could not open file '$fileName' $!";
+
+    return $fileHandle;
+}
+
+=head2 replaceTemplateStrings
+
+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;
+}
+
+=head2 generateUuid
+
+For all signals generates C++ property instantiation.
+Returns C++ code to be placed into the target plugin.
+
+=cut
+
+sub generateUuid {
+    my $dbcjson = $_[0];
+
+    my $ug = new Data::UUID;
+    my $uuidText = $ug->create_str();
+
+    return $uuidText;
+}
+
+=head2 generateCppImplTypes
+
+For all signals generates C++ property instantiation.
+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;
+}
+
+=head2 generateCppProperty
+
+For given signal generates ADDPROPERTY calls and returns C++ property
+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;
+}
+
+=head2 generateSignalsTypes
+
+For all signals generates C++ property definitions.
+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;
+}
+
+=head2 generateEnumOrValues
+
+For given signal generates enums or c++ constants and returns C++ types
+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;
+}
+
+=head2 generatePropertyClasses
+
+For given signal generates documentation, VehicleProperty::Property
+properties with values of stringified properties names.
+lastly using CANSIGNAL macro generates C++ classes
+for given signal.
+
+Returns C++ definitions of one signal property.
+
+=cut
+
+sub generatePropertyClasses {
+    my $signal = $_[0];
+    my $type = $_[1];
+
+    my $generatedText = '';
+
+    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') {
+       $byteOrdering = "Endian::Motorola";                 # BigEndian
+    }
+
+    my $signedness;
+    if ($signal->{'signedness'} eq '+') {
+       $signedness = "Signedness::Unsigned";               # Unsigned
+    } 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;
+}
+
+=head2 generateIdlTypes
+
+For all signals generates WebIDL property documentation.
+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;
+}
+
+=head2 generateIdlProperty
+
+For given signal generates WebIDL documentation and returns WebIDL
+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;
+}
+
+=head2 encryptAmbPropertyNames
+
+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 );
+                }
+            }
+        }
+    }
+}
+
+=head2 removeDuplicates
+
+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;
+}
+
+=head2 calculateZone
+
+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;
+}
+
+##############################################################################
+
+=head1 AUTHOR
+
+IntelIVIPoc, C<< <ivipoc at intel.com> >>
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc Intel::IVIPoc::AMBPluginGenerator
+
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 LICENSE AND COPYRIGHT
+
+INTEL CONFIDENTIAL
+Copyright 2011 - 2013 Intel Corporation All Rights Reserved.
+
+The source code contained or described herein and all documents related to the
+source code("Material") are owned by Intel Corporation or its suppliers or
+licensors.Title to the Material remains with Intel Corporation or its
+suppliers and licensors.The Material may contain trade secrets and proprietary
+and confidential information of Intel Corporation and its suppliers and
+licensors, and is protected by worldwide copyright and trade secret laws and
+treaty provisions.No part of the Material may be used, copied, reproduced,
+modified, published, uploaded, posted, transmitted, distributed, or disclosed
+in any way without Intels prior express written permission.
+No license under any patent, copyright, trade secret or other intellectual
+property right is granted to or conferred upon you by disclosure or delivery
+of the Materials, either expressly, by implication, inducement, estoppel or
+otherwise.Any license under such intellectual property rights must be
+express and approved by Intel in writing.
+
+Unless otherwise agreed by Intel in writing, you may not remove or alter this
+notice or any other notice embedded in Materials by Intel or Intels suppliers
+or licensors in any way.
+
+
+=cut
+
+1; # End of Intel::IviPoc::AmbPluginGenerator
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/DbcGrammar b/tools/AmbSignalMapper/lib/Intel/IviPoc/DbcGrammar
new file mode 100644 (file)
index 0000000..80e6164
--- /dev/null
@@ -0,0 +1,218 @@
+#Copyright (C) 2014  Intel Corporation
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#Lesser General Public License for more details.
+#
+#You should have received a copy of the GNU Lesser General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+{
+    my @networks = ();
+    my @ecuList = ();
+    my %ecuMessages = ();
+    my %ecuValues = ();
+}
+
+DbcOutput: Line(s?) eofile
+    {
+        my @electronicControlUnits = ();
+        for my $ecui (0..scalar(@ecuList)-1) {
+            my %ecuField = ();
+            $ecuField{'canId'} = $ecuList[$ecui];
+
+            if ( exists( $ecuMessages{$ecuList[$ecui]} ) ) {
+                my $messagesRef = $ecuMessages{$ecuList[$ecui]};
+                my @messages = @{$messagesRef};
+
+                $ecuField{'messages'} = \@messages;
+                for my $msgi (0..scalar(@messages)-1) {
+                        my @signals = @{$messages[$msgi]{'signals'}};
+
+                        for my $si (0..scalar(@signals)-1) {
+                            my $signal = \%{$signals[$si]};
+                            my $msgid = $messages[$msgi]{'canId'};
+
+                            if ( exists( ${ecuValues{$msgid}} ) && defined ${$ecuValues{$msgid}{$signal->{'canId'}}} ) {
+                                my $valueListRef=${$ecuValues{$msgid}->{$signal->{'canId'}}};
+                                my @valueList = @$valueListRef;
+                                $signal->{'values'} = \@valueList;
+
+                                # Add AMBPropertyName prefix if valueName starts with number
+                                foreach my $vali (@{$signal->{'values'}}) {
+                                    if ( $vali->{'name'} =~ m/^[0-9]/ ) {
+                                        $vali->{'name'} = $signal->{'AMBPropertyName'} . '_' . $vali->{'name'};
+                                    }
+                                }
+                            }
+                            use Intel::IviPoc::AmbCommon;
+                            $signal->{'AMBPropertyType'} = &evaluateType($signal);
+                        }
+                    }
+                }
+                push (@electronicControlUnits, \%ecuField);
+            }
+
+        my %jsonroot = ();
+        $jsonroot{'pluginName'} = "pluginName";
+        $jsonroot{'electronicControlUnits'} = \@electronicControlUnits;
+
+        # Now return the whole internal json structure
+        return \%jsonroot;
+    }
+
+
+eofile: /^\Z/
+
+Line: CommentPrefix /.*\n/
+        # Not needed to output anything yet
+    | 'VERSION' DoubleQuotedId
+        # Not needed to output anything yet
+    | 'NS_' ':' NSList(s?) ...'BS_'
+        {
+            # We just read the list of NSs
+            @networks = @{$item[3]};
+        }
+    | 'BS_' /.*\n/
+        # Not needed to output anything yet
+    | 'BU_' ':' EcuList(s?) ...'BO_'
+        {
+            @ecuList = @{$item[3]};
+        }
+    | 'BO_' Number Identifier ':' Identifier Identifier Signal(s?)
+        {
+            my %msg = ();
+            $msg{'canId'} = $item[2];
+            $msg{'canName'} = $item[3];
+            $msg{'canDlc'} = $item[5];
+            $msg{'canMessageId'} = $item[6];
+            $msg{'signals'} = $item[7];
+
+            push ( @{$ecuMessages{$item[6]}}, \%msg );
+        }
+    | 'VAL_' Number Identifier ValuePair(s?) ';'
+        {
+            ${$ecuValues{$item[2]}->{$item[3]}} = $item[4];
+        }
+    | <error: Invalid dbc format at $thisline!>
+
+Signal: 'SG_' Identifier ':' DataPlacement FactorOffset Range DoubleQuotedId Receiver(s /,/)
+        {
+            my %signal;
+            $signal{'canId'} = $item[2];
+
+            my %placement = %{$item[4]};
+            $signal{'startbit'} = $placement{'startbit'};
+            $signal{'length'} = $placement{'length'};
+            $signal{'byteOrdering'} = $placement{'byteOrdering'};
+            $signal{'signedness'} = $placement{'signedness'};
+
+            my %fo=%{$item[5]};
+            $signal{'factor'} = $fo{'factor'};
+            $signal{'offset'} = $fo{'offset'};
+
+            my %range=%{$item[6]};
+            $signal{'minValue'} = $range{'minValue'};
+            $signal{'maxValue'} = $range{'maxValue'};
+
+            $signal{'unit'} = $item[7];
+
+            $signal{'receivers'} = $item[8];
+
+            my $ambPropertyName = $item[2];
+            $ambPropertyName =~ s/\_[HM]S$//;
+            $signal{'AMBPropertyName'} = $ambPropertyName;
+
+            $return=\%signal;
+        }
+
+EcuList: ...!'BO_' Identifier
+        {
+            $return = $item[2];
+        }
+
+NSList: ...!'BS_' Identifier
+        {
+            $return = $item[2];
+        }
+
+Receiver: Identifier
+        {
+            my %rx;
+            $rx{'name'} = $item[1];
+            $return = \%rx;
+        }
+
+ValuePair: Number DoubleQuotedId
+        {
+            my %valuepair;
+            $valuepair{'value'} = $item[1];
+            $valuepair{'description'} = $item[2];
+
+            my $s = $item[2];
+            $s =~ s!(^|\s)(\w)!$1\U$2!g;
+            $s =~ s/ |-/_/g;
+            $s =~ s/[^_a-zA-Z0-9]//g;
+            $s =~ s/_(?=[_]*$)//;
+            $s =~ s/(_)\1+/$1/g;
+            $s =~ s/^\_//;
+            $s =~ s/\_$//;
+            $valuepair{'name'} = $s;
+
+            $return=\%valuepair;
+        }
+
+DataPlacement: Number '|' Number '@' Number Sign
+        {
+            my %placement;
+            $placement{'startbit'} = $item[1];
+            $placement{'length'} = $item[3];
+            $placement{'byteOrdering'} = $item[5];
+            $placement{'signedness'} = $item[6];
+            $return=\%placement;
+        }
+
+FactorOffset: '(' RealNumber ',' RealNumber ')'
+        {
+            my %fo;
+            $fo{'factor'} = $item[2];
+            $fo{'offset'} = $item[4];
+            $return=\%fo;
+        }
+
+Range: '[' RealNumber '|' RealNumber ']'
+        {
+            my %range;
+            $range{'minValue'} = $item[2];
+            $range{'maxValue'} = $item[4];
+            $return=\%range;
+        }
+
+DoubleQuotedId: DoubleQuotation /[A-Za-z0-9°\!@#\$%\^&\*()\-_=\+\[\]\{\};:\'|,\.\/<>\?`~\ ]+/ DoubleQuotation
+        {
+            $return = $item[2];
+        }
+    | DoubleQuotation DoubleQuotation
+        {
+            $return = "";
+        }
+
+Identifier: /[A-Za-z0-9_\-]+/
+        {
+            $return = $item[1];
+        }
+
+Number: /[-+]?[0-9]*/
+RealNumber: /[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/
+Sign: /^[-+]?/
+
+CommentPrefix: /^\/\//
+
+DoubleQuotation: "\""
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/DbcGrammar.pod b/tools/AmbSignalMapper/lib/Intel/IviPoc/DbcGrammar.pod
new file mode 100644 (file)
index 0000000..b6d3e44
--- /dev/null
@@ -0,0 +1,90 @@
+#Copyright (C) 2014  Intel Corporation
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#Lesser General Public License for more details.
+#
+#You should have received a copy of the GNU Lesser General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+=head1 NAME
+
+Intel::IviPoc::DbcGrammar - Vector CANdb++ (*.dbc) file format parser
+
+=head1 SYNOPSIS
+
+    use Intel::IviPoc::DbcGrammar;
+
+       my $result;
+       $result = $parser->DbcOutput($text);
+       my %jsonroot = %{$result};
+
+=head1 REQUIRES
+
+Perl 5.006, Parse::RecDescent, Intel::IviPoc::AmbCommon
+
+=head1 EXPORTS
+
+new
+
+=head1 DESCRIPTION
+
+The Parse::RecDescent - Generate Recursive-Descent Parsers is Perl library for recursive top-down parsing(LL).
+
+=head1 METHODS
+
+=over 4
+
+=item DbcOutput $text
+
+Parses the provided string $text
+Returns the hash representing the entire $text.
+
+=item new
+
+Returns an instance of DbcParser.
+
+=back
+
+=head1 AUTHOR
+
+IntelIVIPoc, C<< <ivipoc at intel.com> >>
+
+=head1 SEE ALSO
+
+L<strict|http://search.cpan.org/~jtbraun/Parse-RecDescent-1.967009/lib/Parse/RecDescent.pm>
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 LICENSE AND COPYRIGHT
+
+INTEL CONFIDENTIAL
+Copyright 2011 - 2013 Intel Corporation All Rights Reserved.
+
+The source code contained or described herein and all documents related to the
+source code("Material") are owned by Intel Corporation or its suppliers or
+licensors.Title to the Material remains with Intel Corporation or its
+suppliers and licensors.The Material may contain trade secrets and proprietary
+and confidential information of Intel Corporation and its suppliers and
+licensors, and is protected by worldwide copyright and trade secret laws and
+treaty provisions.No part of the Material may be used, copied, reproduced,
+modified, published, uploaded, posted, transmitted, distributed, or disclosed
+in any way without Intels prior express written permission.
+No license under any patent, copyright, trade secret or other intellectual
+property right is granted to or conferred upon you by disclosure or delivery
+of the Materials, either expressly, by implication, inducement, estoppel or
+otherwise.Any license under such intellectual property rights must be
+express and approved by Intel in writing.
+
+Unless otherwise agreed by Intel in writing, you may not remove or alter this
+notice or any other notice embedded in Materials by Intel or Intels suppliers
+or licensors in any way.
+
+=cut
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/CMakeLists.txt b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6d392ee
--- /dev/null
@@ -0,0 +1,68 @@
+cmake_minimum_required(VERSION 2.8)
+
+set( CMAKE_VERBOSE_MAKEFILE on )
+
+# to install plugin into /usr instead of /usr/local
+set (CMAKE_INSTALL_PREFIX /usr)
+
+IF(CMAKE_BUILD_TYPE MATCHES DEBUG) 
+    message("debug mode") 
+ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG)
+IF(CMAKE_BUILD_TYPE MATCHES RELEASE) 
+    message("release mode")
+    add_definitions(-D_LOGGER_NO_LOG)
+ENDIF(CMAKE_BUILD_TYPE MATCHES RELEASE)
+
+include(FindPkgConfig)
+
+find_package(Boost REQUIRED)
+
+pkg_check_modules(glib REQUIRED glib-2.0)
+pkg_check_modules(json REQUIRED json)
+
+add_definitions(-std=gnu++0x -fPIC -fPIE)
+
+pkg_check_modules( amb REQUIRED automotive-message-broker )
+pkg_check_modules( amb-plugins-common REQUIRED amb-plugins-common )
+
+include_directories(${include_dirs} ${amb-plugins-common_INCLUDE_DIRS} ${amb_INCLUDE_DIRS} ${glib_INCLUDE_DIRS} ${gio_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${json_INCLUDE_DIRS} )
+
+set(ambtmpl_plugin_headers ambtmpl_plugin.h  ambtmpl_cansignals.h ambtmpl_cansignal.h)
+set(ambtmpl_plugin_sources ambtmpl_plugin.cpp ambtmpl_cansignal.cpp)
+
+if(ivipoc_tests)
+#########################################
+# ivipoc_tests START
+#########################################
+
+#find CppUTest headers ( CppUTest/CommandLineTestRunner.h ):
+find_path(cpputest_INCLUDE_DIR CppUTest/CommandLineTestRunner.h PATHS $ENV{CPPUTEST_HOME}/include DOC "CppUTest headers")
+
+include_directories(${include_dirs} ${cpputest_INCLUDE_DIR})
+
+#find libCppUTestExt.a (and libCppUTest.a) library:
+find_library(CppUTest_LIBRARY CppUTest PATHS $ENV{CPPUTEST_HOME}/lib DOC "CppUTest library")
+find_library(CppUTestExt_LIBRARY CppUTestExt PATHS $ENV{CPPUTEST_HOME}/lib DOC "CppUTestExt library")
+
+# test definitions
+add_definitions(-DUNIT_TESTS -fprofile-arcs -ftest-coverage)
+
+# test link libs
+set(link_libraries gcov ${CppUTest_LIBRARY} ${CppUTestExt_LIBRARY})
+
+# test sources
+add_subdirectory(test)
+
+#########################################
+# ivipoc_tests END
+#########################################
+endif(ivipoc_tests)
+
+add_library(ambtmpl_plugin MODULE ${ambtmpl_plugin_sources} ${ambtmpl_plugin_headers})
+set_target_properties(ambtmpl_plugin PROPERTIES PREFIX "")
+target_link_libraries(ambtmpl_plugin ${link_libraries} ${libamb_LIBRARY} ${amb_LIBRARIES} ${amb-plugins-common_LIBRARIES})
+
+install(TARGETS ambtmpl_plugin LIBRARY DESTINATION lib/automotive-message-broker)
+
+############################################################################################################################################
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignal.cpp b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignal.cpp
new file mode 100644 (file)
index 0000000..b44f36e
--- /dev/null
@@ -0,0 +1,188 @@
+/*****************************************************************
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************/
+
+#include "ambtmpl_cansignal.h"
+
+template<>
+bool convert<bool>( double temp )
+{
+    return abs(temp) > std::numeric_limits<double>::epsilon();
+}
+
+double fromGVariant(GVariant *value)
+{
+    GVariantClass c = g_variant_classify(value);
+    if(c == G_VARIANT_CLASS_BOOLEAN)
+        return g_variant_get_boolean(value) ? 1.0 : 0.0;
+
+    else if(c == G_VARIANT_CLASS_BYTE)
+        return static_cast<double>(g_variant_get_byte(value));
+
+    else if(c == G_VARIANT_CLASS_INT16)
+        return static_cast<double>(g_variant_get_int16(value));
+
+    else if(c == G_VARIANT_CLASS_UINT16)
+        return static_cast<double>(g_variant_get_uint16(value));
+
+    else if(c == G_VARIANT_CLASS_INT32)
+        return static_cast<double>(g_variant_get_int32(value));
+
+    else if(c ==  G_VARIANT_CLASS_UINT32)
+        return static_cast<double>(g_variant_get_uint32(value));
+
+    else if(c == G_VARIANT_CLASS_INT64)
+        return static_cast<double>(g_variant_get_int64(value));
+
+    else if(c == G_VARIANT_CLASS_UINT64)
+        return static_cast<double>(g_variant_get_uint64(value));
+
+    else if(c == G_VARIANT_CLASS_DOUBLE)
+        return static_cast<double>(g_variant_get_double(value));
+
+    else
+        return 0.0;
+
+}
+
+CANSignal::CANSignal(std::function<AbstractPropertyType* ()> factoryFunction) :
+    ambProperty(nullptr),
+    signature(static_cast<GVariantClass>(0)),
+    factoryFunction(factoryFunction)
+{
+}
+
+CANSignal::~CANSignal()
+{
+}
+
+void CANSignal::onMessage(const can_frame& frame, std::function<void (AbstractPropertyType*)> changeCallback)
+{
+    std::unique_ptr<GVariant, decltype(&g_variant_unref)> variant(processSignal(frame), &g_variant_unref);
+    if(variant){
+        std::unique_ptr<GVariant, decltype(&g_variant_unref)> oldValue(ambProperty->toVariant(), &g_variant_unref);
+        if(!g_variant_equal(variant.get(), oldValue.get())) {
+            ambProperty->fromVariant( variant.get() );
+            if(changeCallback)
+                changeCallback(ambProperty.get());
+        }
+    }
+}
+
+void CANSignal::setAmbProperty(std::shared_ptr<AbstractPropertyType> ambProperty)
+{
+    this->ambProperty = ambProperty;
+    std::unique_ptr<GVariant, decltype(&g_variant_unref)> variant(ambProperty->toVariant(), &g_variant_unref);
+    if(variant)
+        signature = g_variant_classify(variant.get());
+}
+
+template <>
+GVariant* CANSignal::processFrameBits<bool>( const can_frame& frame )
+{
+    bool value = getSignalBits( frame ) != 0ull;
+    return toGVariant<bool>(value, signature);
+}
+
+bool CANSignal::updateFrame(can_frame* frame)
+{
+    if(/*!value ||*/ !frame)
+        return false;
+
+    std::unique_ptr<GVariant, decltype(&g_variant_unref)> variant(ambProperty->toVariant(), &g_variant_unref);
+    //ambProperty->fromVariant(variant.get());
+
+    double val(fromGVariant(variant.get()));
+    double temp = (val - signalInfo.m_offset)/signalInfo.m_factor;
+
+    int64_t bits = conversionFunctionTo(val, static_cast<int64_t>(temp));
+
+    *(reinterpret_cast<uint64_t*>(&frame->data[0])) |= toSignalBits(bits);
+}
+
+int64_t CANSignal::getSignalBits( const can_frame& frame )
+{
+    int64_t bits = *reinterpret_cast<const int64_t* >(frame.data);
+    int startbit = signalInfo.m_startbit;
+
+    if (signalInfo.m_byteOrdering == Motorola ) {
+        // Motorola
+        bits = __bswap_64(bits);
+        int rounded = signalInfo.m_startbit & (~0x07); //(signalInfo.m_startbit/8)*8;
+        int remainder = signalInfo.m_startbit & 0x07; //signalInfo.m_startbit % 8;
+        startbit = (CANFrameDataSize - ( (8 - remainder) + rounded) - (signalInfo.m_length - 1) );
+    }
+    else{
+        // Intel - do nothing
+    }
+
+    bits = bits >> startbit;
+    uint64_t mask = ~(0ull);
+    if(signalInfo.m_length < 64){
+        mask = (1ull << static_cast<uint64_t>(signalInfo.m_length)) - 1ull;
+    }
+
+    bits &= mask;
+    if(signalInfo.m_signedness){
+        if(signalInfo.m_length <= 8 ){
+            bits = static_cast<int8_t>(bits);
+        }
+        else if(signalInfo.m_length <= 16 ){
+            bits = static_cast<int16_t>(bits);
+        }
+        else if(signalInfo.m_length <= 32 ){
+            bits = static_cast<int32_t>(bits);
+        }
+    }
+
+    return bits;
+}
+
+uint64_t CANSignal::toSignalBits( int64_t bits )
+{
+    uint64_t signBit(0ull);
+    if(signalInfo.m_signedness && bits < 0ull){
+        signBit = (1ull << static_cast<uint64_t>(signalInfo.m_length-1));
+    }
+
+    uint64_t mask = ~(0ull);
+    if(signalInfo.m_length < 64){
+        mask = (1ull << static_cast<uint64_t>(signalInfo.m_length)) - 1ull;
+    }
+    bits &= mask;
+    bits |= signBit;
+
+    int startbit = signalInfo.m_startbit;
+    if (signalInfo.m_byteOrdering == Motorola ) {
+        // Motorola
+        int rounded = signalInfo.m_startbit & (~0x07); //(signalInfo.m_startbit/8)*8;
+        int remainder = signalInfo.m_startbit & 0x07; //signalInfo.m_startbit % 8;
+        startbit = (CANFrameDataSize - ( (8 - remainder) + rounded) - (signalInfo.m_length - 1) );
+    }
+    else{
+        // Intel - do nothing
+    }
+
+    bits = bits << startbit;
+
+    if (signalInfo.m_byteOrdering == Motorola ) {
+        bits = __bswap_64(bits);
+    }
+
+    return bits;
+}
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignal.h b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignal.h
new file mode 100644 (file)
index 0000000..2ea563f
--- /dev/null
@@ -0,0 +1,231 @@
+/*****************************************************************
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************/
+
+#ifndef AMBTMPL_CANSIGNAL_H_
+#define AMBTMPL_CANSIGNAL_H_
+
+#include <map>
+#include <limits>
+#include <glib.h>
+#include <abstractpropertytype.h>
+#include <vehicleproperty.h>
+#include <byteswap.h>
+#include <boost/any.hpp>
+
+#include <canbus.h>
+#include <canobserver.h>
+
+enum Endian{
+    Motorola = 0x0,     // BigEndian
+    Intel = 0x1         // LittleEndian
+};
+
+enum Signedness{
+    Unsigned = 0x0,     // Unsigned
+    Signed = 0x1        // Signed
+};
+
+const int CANFrameDataSize = 8*sizeof(can_frame::data);
+
+template<typename T>
+T convert( double temp )
+{
+    return static_cast<T>(temp);
+}
+
+template<typename T>
+T convert( const boost::any& temp )
+{
+    return boost::any_cast<T>(temp);
+}
+
+template<typename T>
+GVariant* toGVariant(const T& value, const GVariantClass& c)
+{
+    if(c == G_VARIANT_CLASS_BOOLEAN)
+        return g_variant_new_boolean(static_cast<gboolean>(value));
+
+    else if(c == G_VARIANT_CLASS_BYTE)
+        return g_variant_new_byte(static_cast<guchar>(value));
+
+    else if(c == G_VARIANT_CLASS_INT16)
+        return g_variant_new_int16(static_cast<gshort>(value));
+
+    else if(c == G_VARIANT_CLASS_UINT16)
+        return g_variant_new_uint16(static_cast<gushort>(value));
+
+    else if(c == G_VARIANT_CLASS_INT32)
+        return g_variant_new_int32(static_cast<gint>(value));
+
+    else if(c ==  G_VARIANT_CLASS_UINT32)
+        return g_variant_new_uint32(static_cast<guint>(value));
+
+    else if(c == G_VARIANT_CLASS_INT64)
+        return g_variant_new_int64(static_cast<gint64>(value));
+
+    else if(c == G_VARIANT_CLASS_UINT64)
+        return g_variant_new_int64(static_cast<guint64>(value));
+
+    else if(c == G_VARIANT_CLASS_DOUBLE)
+        return g_variant_new_double(static_cast<gdouble>(value));
+
+    else
+        return nullptr;
+}
+
+class CANSignal {
+
+public:
+    explicit CANSignal(std::function<AbstractPropertyType* ()> factoryFunction);
+    virtual ~CANSignal();
+
+    virtual GVariant *processSignal( const can_frame& frame ) = 0;
+
+    virtual void onMessage( const can_frame& frame, std::function<void (AbstractPropertyType*)> changeCallback );
+
+    virtual bool updateFrame( can_frame* frame );
+
+    template <typename T>
+    GVariant* processFrameBits( const can_frame& frame )
+    {
+        int64_t bits = getSignalBits( frame );
+        double temp = static_cast<double>(bits)*signalInfo.m_factor + signalInfo.m_offset;
+        T value(convert<T>(conversionFunctionFrom(temp, bits)));
+        return toGVariant<T>(value, signature);
+    }
+
+    virtual boost::any conversionFunctionFrom(double value, int64_t bits) = 0;
+
+    virtual uint64_t conversionFunctionTo(double value, uint64_t bits) = 0;
+
+    void setAmbProperty(std::shared_ptr<AbstractPropertyType> ambProperty);
+
+    inline std::function<AbstractPropertyType* ()> factory()
+    {
+        return factoryFunction;
+    }
+
+protected:
+    int64_t getSignalBits( const can_frame& frame );
+    uint64_t toSignalBits( int64_t bits );
+
+protected:
+    struct SignalInfo {
+        uint8_t m_startbit;
+        uint8_t m_length;
+        Endian m_byteOrdering;
+        Signedness m_signedness;
+        double m_factor;
+        double m_offset;
+    };
+
+    SignalInfo signalInfo;
+    std::shared_ptr<AbstractPropertyType> ambProperty;
+    GVariantClass signature;
+    std::function<AbstractPropertyType* ()> factoryFunction;
+};
+
+class CANMessage
+{
+public:
+    CANMessage() = delete;
+
+    CANMessage(canid_t canId, __u8 canDlc) :
+        canId(canId),
+        canDlc(canDlc)
+    {
+    }
+
+    void addSignal(const VehicleProperty::Property& name, std::shared_ptr<CANSignal> signal)
+    {
+        if(signal)
+            canSignals[name] = signal;
+    }
+
+    void onMessage(const can_frame& frame, std::function<void (AbstractPropertyType*)> changeCallback)
+    {
+        if(frame.can_dlc != canDlc || frame.can_id != canId)
+            return;
+
+        for ( auto it = canSignals.begin(); it != canSignals.end(); ++it ) {
+            std::shared_ptr<CANSignal> signal(it->second);
+
+            if ( signal ) {
+                signal->onMessage(frame, changeCallback);
+            }
+        }
+    }
+
+    void setupFrame(can_frame* frame)
+    {
+        if(!frame)
+            return;
+
+        memset(frame, 0, sizeof(can_frame));
+        frame->can_id = canId;
+        frame->can_dlc = canDlc;
+
+        for ( auto it = canSignals.begin(); it != canSignals.end(); ++it ) {
+            it->second->updateFrame(frame);
+        }
+    }
+
+private:
+    canid_t canId;
+    __u8 canDlc;
+    std::map< VehicleProperty::Property , std::shared_ptr<CANSignal> > canSignals;
+};
+
+#define CANSIGNAL(property, valueType, startbit, length, byteOrdering, signedness, factor, offset, minValue, maxValue, convertFrom, convertTo) \
+    class property ## Type : public CANSignal { \
+    public: property ## Type() : \
+            CANSignal([](){ return new BasicPropertyType<valueType>(property); } ) \
+            , convertFromFunction(convertFrom) \
+            , convertToFunction(convertTo) \
+    {\
+        signalInfo.m_startbit = startbit; \
+        signalInfo.m_length = length; \
+        signalInfo.m_byteOrdering = byteOrdering; \
+        signalInfo.m_signedness = signedness; \
+        signalInfo.m_factor = factor; \
+        signalInfo.m_offset = offset; \
+        m_minValue = minValue; \
+        m_maxValue = maxValue; \
+    } \
+    GVariant *processSignal( const can_frame& frame ) { \
+        return processFrameBits<valueType>( frame ); \
+    } \
+    boost::any conversionFunctionFrom(double value, int64_t bits) { \
+        valueType targetValue(convert<valueType>(value)); \
+        if(convertFromFunction) \
+            return convertFromFunction(targetValue, bits); \
+        else return targetValue; \
+    } \
+    uint64_t conversionFunctionTo(double value, uint64_t bits) { \
+        if(convertToFunction) \
+            convertToFunction(convert<valueType>(value), bits); \
+        else return bits; \
+    } \
+    valueType m_minValue; \
+    valueType m_maxValue; \
+    std::function<valueType(valueType, int64_t)> convertFromFunction; \
+    std::function<uint64_t(valueType, uint64_t)> convertToFunction; \
+    typedef valueType value_type; \
+    };
+
+#endif /* AMBTMPL_CANSIGNAL_H_ */
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignals.h b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_cansignals.h
new file mode 100644 (file)
index 0000000..e41e9e2
--- /dev/null
@@ -0,0 +1,30 @@
+/*****************************************************************
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************/
+
+#ifndef AMBTMPL_CANSIGNALS_H_
+#define AMBTMPL_CANSIGNALS_H_
+
+#include "ambtmpl_plugin.h"
+#include "ambtmpl_cansignal.h"
+
+#include <glib.h>
+#include <vehicleproperty.h>
+
+/*GENERATED_CODE*/
+
+#endif /* AMBTMPL_CANSIGNALS_H_ */
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.cpp b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.cpp
new file mode 100644 (file)
index 0000000..6f41274
--- /dev/null
@@ -0,0 +1,289 @@
+/*****************************************************************
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************/
+
+#include <boost/assert.hpp>
+#include <glib.h>
+#include <cstdarg>
+
+#include <vehicleproperty.h>
+#include <listplusplus.h>
+
+#include <logger.h>
+
+#include "ambtmpl_plugin.h"
+#include "ambtmpl_cansignals.h"
+
+//using namespace AmbTmplPlugin;
+
+static const char* DEFAULT_CAN_IF_NAME = "vcan0";
+
+// library exported function for plugin loader
+extern "C" AbstractSource * create(AbstractRoutingEngine* routingengine, std::map<std::string, std::string> config)
+{
+#ifndef UNIT_TESTS
+    DEBUG_CONF("AmbTmplPlugin",
+        CUtil::Logger::file_off|CUtil::Logger::screen_on,
+        CUtil::Logger::EInfo, CUtil::Logger::EInfo
+    );
+#endif
+
+    std::unique_ptr< AmbPlugin<AmbTmplPlugin> > plugin(new AmbPlugin<AmbTmplPlugin>(routingengine, config));
+    plugin->init();
+    return plugin.release();
+}
+
+void AmbTmplPlugin::timerDestroyNotify(gpointer data)
+{
+    TimerData* timerData = reinterpret_cast<TimerData*>(data);
+    if(timerData){
+        AmbTmplPlugin* plugin = std::get<0>(*timerData);
+        const can_frame& frame = std::get<3>(*timerData);
+        plugin->eraseTimer(frame.can_id);
+        delete timerData;
+    }
+
+}
+
+gboolean AmbTmplPlugin::timeoutCallback(gpointer data)
+{
+    TimerData* timerData = reinterpret_cast<TimerData*>(data);
+    if(!timerData)
+        return false;
+
+    CANBus* bus = std::get<1>(*timerData);
+    int retries = --std::get<2>(*timerData);
+    const can_frame& frame = std::get<3>(*timerData);
+
+    if(retries > 0){
+        if(bus)
+            bus->sendStandardFrame(frame);
+        return true;
+    }
+    else return false;
+}
+
+//----------------------------------------------------------------------------
+// AmbTmplPlugin
+//----------------------------------------------------------------------------
+
+AmbTmplPlugin::AmbTmplPlugin(AbstractRoutingEngine* re, const map<string, string>& config, AbstractSink& parent) :
+      AmbPluginImpl(re, config, parent),
+      interface(DEFAULT_CAN_IF_NAME),
+      canBus(new CANBus(*static_cast<CANObserver*>(this))),
+      announcementIntervalTimer(1000),
+      announcementCount(20)
+{
+    auto it = config.find("interface");
+    if (it != config.end() && it->second.length())
+        interface = it->second;
+
+    it = config.find("announcementIntervalTimer");
+    if (it != config.end() && it->second.length())
+        announcementIntervalTimer = atoi(std::string(it->second).c_str());
+    if(announcementIntervalTimer < 20)
+        announcementIntervalTimer = 20;
+
+    it = config.find("announcementCount");
+    if (it != config.end() && it->second.length())
+        announcementCount = atoi(std::string(it->second).c_str());
+    if(announcementCount < 1)
+            announcementIntervalTimer = 1;
+
+    registerMessages();
+}
+
+AmbTmplPlugin::~AmbTmplPlugin()
+{
+    std::list<guint> timerList;
+
+    mutex.lock();
+    for(auto it=timers.begin();it!=timers.end();++it)
+        timerList.push_back(it->second);
+    mutex.unlock();
+
+    for(auto it=timerList.begin();it!=timerList.end();++it)
+        g_source_remove(*it);
+
+    canBus->stop();
+}
+
+void AmbTmplPlugin::init()
+{
+    canBus->start(interface.c_str());
+}
+
+AsyncPropertyReply *AmbTmplPlugin::setProperty(const AsyncSetPropertyRequest& request )
+{
+    AsyncPropertyReply* reply = new AsyncPropertyReply(request);
+    reply->success = false;
+    reply->error = AsyncPropertyReply::InvalidOperation;
+
+    AbstractPropertyType *value = findPropertyType(request.property, request.zoneFilter);
+    if (value && request.value) {
+        DebugOut(2) << "updating property "<< request.property << " to: " << request.value->toString() << endl;
+
+        std::unique_ptr<GVariant, decltype(&g_variant_unref)> variant(request.value->toVariant(), &g_variant_unref);
+        value->fromVariant(variant.get());
+
+        if(sendValue(request.value)) {
+            DebugOut(2) << "New value of property "<< request.property << " is: " << value->toString() << endl;
+            value->timestamp = amb::currentTime();
+            routingEngine->updateProperty(value, uuid());
+
+            reply->success = true;
+            reply->error = AsyncPropertyReply::NoError;
+        }
+    }
+
+    try {
+        if(reply->completed)
+            reply->completed(reply);
+    }
+    catch (...) { }
+
+    return reply;
+}
+
+int AmbTmplPlugin::supportedOperations() const
+{
+    return AbstractSource::Get | AbstractSource::Set;
+}
+
+void AmbTmplPlugin::onMessage(const can_frame& frame)
+{
+    auto messageIt = messages.find(frame.can_id);
+    if(messageIt == messages.end())
+        return;
+
+    CANMessage& message(messageIt->second);
+    const std::string guid = uuid();
+    AbstractRoutingEngine* re = routingEngine;
+    message.onMessage( frame, [&re, &guid](AbstractPropertyType* value){re->updateProperty(value, guid);} );
+}
+
+bool AmbTmplPlugin::sendValue(AbstractPropertyType* value)
+{
+    if(!value)
+        return false;
+
+    auto it = propertyToMessage.find(value->name);
+    if(it == propertyToMessage.end())
+        return false;
+
+    CANMessage* canMessage = it->second;
+    can_frame frame;
+    canMessage->setupFrame(&frame);
+    return sendStandardFrame(frame);
+}
+
+// from CANObserver
+void AmbTmplPlugin::errorOccured(CANObserver::CANError error)
+{
+    (void) error;
+    LOG_INFO( "AmbTmplPlugin::errorOccured() not implemented "<< std::endl );
+}
+
+void AmbTmplPlugin::standardFrameReceived(const can_frame& frame)
+{
+    LOG_INFO("AmbTmplPlugin::standardFrameReceived()");
+    printFrame( frame );
+
+    onMessage(frame);
+}
+
+void AmbTmplPlugin::extendedFrameReceived(const can_frame& frame)
+{
+    LOG_INFO("AmbTmplPlugin::extendedFrameReceived()");
+    printFrame(frame);
+
+    onMessage(frame);
+}
+
+void AmbTmplPlugin::errorFrameReceived(const can_frame& frame)
+{
+    LOG_INFO("AmbTmplPlugin::errorFrameReceived()");
+    printFrame(frame);
+}
+
+void AmbTmplPlugin::remoteTransmissionRequest(const can_frame& frame)
+{
+    (void) frame;
+    LOG_INFO( "AmbTmplPlugin::remoteTransmissionRequest() not implemented "<< std::endl );
+}
+
+bool AmbTmplPlugin::sendStandardFrame(const can_frame& frame)
+{
+    guint oldTimer(0);
+    mutex.lock();
+    auto it = timers.find(frame.can_id);
+    if(it != timers.end()){
+        oldTimer = it->second;
+        timers.erase(it);
+    }
+    mutex.unlock();
+
+    if(oldTimer != 0)
+        g_source_remove(oldTimer);
+
+    if ( canBus->sendStandardFrame(frame) ) {
+        LOG_TRACE( "AmbTmplPlugin::sendStandardFrame() success "<< std::endl );
+        scoped_lock<interprocess_recursive_mutex> lock(mutex);
+        std::unique_ptr< TimerData > timerData(new TimerData(this, canBus.get(), announcementCount, frame));
+        guint timer = g_timeout_add_full(G_PRIORITY_HIGH, announcementIntervalTimer, timeoutCallback, timerData.get(), timerDestroyNotify);
+        if(timer){
+            timers[frame.can_id] = timer;
+            timerData.release();
+        }
+        return true;
+    }
+    else {
+        LOG_WARNING( "AmbTmplPlugin::sendStandardFrame() failed "<< std::endl );
+        return false;
+    }
+}
+
+bool AmbTmplPlugin::sendExtendedFrame(const can_frame& frame)
+{
+    if ( canBus->sendExtendedFrame(frame) ) {
+        LOG_TRACE( "AmbTmplPlugin::sendExtendedFrame() success "<< std::endl );
+        return true;
+    }
+    else {
+        LOG_WARNING( "AmbTmplPlugin::sendExtendedFrame() failed "<< std::endl );
+        return false;
+    }
+}
+
+void AmbTmplPlugin::printFrame(const can_frame& frame) const
+{
+    LOG_INFO( "AmbTmplPlugin::printFrame can_id: " << std::hex << frame.can_id << std::dec );
+    LOG_INFO( "AmbTmplPlugin::printFrame can_dlc: " << int(frame.can_dlc) );
+
+    std::stringstream ss;
+    for(int i=0; i<frame.can_dlc; ++i){
+        ss << " " << std::hex << (int)(frame.data[i]);
+    }
+    ss << std::dec;
+
+    LOG_INFO( "AmbTmplPlugin::printFrame can data" << ss.str() );
+}
+
+void AmbTmplPlugin::registerMessages()
+{
+/*GENERATED_CODE*/
+}
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.h b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.h
new file mode 100644 (file)
index 0000000..9e22f55
--- /dev/null
@@ -0,0 +1,196 @@
+/*****************************************************************
+Copyright (C) 2014  Intel Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************/
+
+#ifndef AMBTMPL_PLUGIN_H_
+#define AMBTMPL_PLUGIN_H_
+
+#include <map>
+#include <memory>
+#include <tgmath.h>
+#include <limits>
+#include <byteswap.h>
+#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+
+#include <canbus.h>
+#include <canobserver.h>
+
+#include <ambpluginimpl.h>
+#include "ambtmpl_cansignal.h"
+
+using namespace boost::interprocess;
+
+// forward declaration
+class CANSignal;
+class CANMessage;
+
+class AmbTmplPlugin : public AmbPluginImpl, public CANObserver {
+
+public:
+    AmbTmplPlugin(AbstractRoutingEngine* re, const std::map<std::string, std::string>& config, AbstractSink& parent);
+    virtual ~AmbTmplPlugin(); // has to be virtual because of unit tests
+
+    // from AbstractSink
+public:
+
+    /*! uuid() is a unique identifier of the plugin
+      * @return a guid-style unique identifier
+      */
+    const std::string uuid() const { return "/*GENERATED_CODE*/"; }
+
+    /*!
+     * \brief setProperty is called when a sink requests to set a value for a given property.
+     * This is only called if the source supports the Set Operation.
+     * \param request the requested property to set.
+     * \return returns a pointer to the new value for the property.
+     */
+    AsyncPropertyReply *setProperty(const AsyncSetPropertyRequest& request );
+
+    /*!
+     * \brief supportedOperations
+     * \return returns the supported operations.
+     */
+    int supportedOperations() const;
+
+
+    // from CANObserver
+public:
+    /*!
+     * Called when error occurred on the bus.
+     * \fn errorOccured
+     * \param error \link CANObserver#CANError Bus error code \endlink
+     */
+    virtual void errorOccured(CANObserver::CANError error);/* socket error */
+    /*!
+     * Called when standard frame was is received from the bus.
+     * \fn standardFrameReceived
+     * \param frame Received frame
+     */
+    virtual void standardFrameReceived(const can_frame& frame);/* SFF was present */
+    /*!
+     * Called when extended frame was is received from the bus.
+     * \fn extendedFrameReceived
+     * \param frame Received frame
+     */
+    virtual void extendedFrameReceived(const can_frame& frame);/* EFF was present */
+    /*!
+     * Called when error frame was received from the bus.
+     * \fn errorFrameReceived
+     * \param frame Error frame
+     */
+    virtual void errorFrameReceived(const can_frame& frame);/* error frame */
+    /*!
+     * Called when remote transmission frame was received from the bus.
+     * \fn remoteTransmissionRequest
+     * \param frame RTR frame
+     */
+    virtual void remoteTransmissionRequest(const can_frame& frame);/* remote transmission request (SFF/EFF is still present)*/
+
+    /**
+    * Sends standard(11bit) CAN frame over the bus
+    * \fn sendStandardFrame
+    * \param frame CAN frame to be sent
+    * \return True if frame was sent
+    */
+    bool sendStandardFrame(const can_frame& frame);
+
+    /**
+    * Sends extended(29bit) CAN frame over the bus
+    * \fn sendExtendedFrame
+    * \param frame CAN frame to be sent
+    * \return True if frame was sent
+    */
+    bool sendExtendedFrame(const can_frame& frame);
+
+    /*!
+     * Second phase of the plugin initialization.
+     * \fn init
+     */
+    virtual void init();
+
+    void eraseTimer(const canid_t& id)
+    {
+        scoped_lock<interprocess_recursive_mutex> lock(mutex);
+        auto it = timers.find(id);
+        if(it != timers.end()){
+            timers.erase(it);
+        }
+    }
+
+protected:
+
+    void registerMessage(const canid_t& canId, const __u8& canDlc)
+    {
+        LOG_MESSAGE("registered message: " << canId);
+    }
+
+    template<typename Signal, typename... Rest>
+    void registerMessage(const canid_t& canId, const __u8& canDlc, Signal* canSignal, Rest... rest)
+    {
+        static_assert(std::is_base_of<CANSignal, Signal>::value, "CANSignal has to be a base of Signal");
+
+        if(!canSignal)
+            return;
+
+        std::shared_ptr<AbstractPropertyType> prop(AmbPluginImpl::addPropertySupport(Zone::None, canSignal->factory()));
+        if(prop) {
+            canSignal->setAmbProperty(prop);
+            auto messageIt = messages.find(canId);
+            if(messageIt == messages.end()){
+                messageIt = messages.insert(make_pair(canId, CANMessage(canId, canDlc))).first;
+            }
+            auto& message = messageIt->second;
+            message.addSignal(prop->name, std::shared_ptr<CANSignal>(canSignal));
+            propertyToMessage[prop->name] = &message;
+        }
+
+        registerMessage(canId, canDlc, rest...);
+    }
+
+private:
+
+    void printFrame(const can_frame& frame) const;
+    void onMessage(const can_frame& frame);
+    bool sendValue(AbstractPropertyType* value);
+    void registerMessages();
+
+    static void timerDestroyNotify(gpointer data);
+    static gboolean timeoutCallback(gpointer data);
+//
+// data:
+//
+    std::map< canid_t, CANMessage > messages;
+    std::map< VehicleProperty::Property, CANMessage* > propertyToMessage;
+
+    std::string interface;
+
+    /**
+    * CANBus class instance
+    * \property canBus
+    * \private
+    */
+    std::unique_ptr<CANBus> canBus;
+
+    typedef std::tuple<AmbTmplPlugin*, CANBus*, int, const can_frame> TimerData;
+    std::map< canid_t, guint > timers;
+    interprocess_recursive_mutex mutex;
+    uint announcementIntervalTimer;
+    uint announcementCount;
+};
+
+#endif /* AMBTMPL_PLUGIN_H_ */
diff --git a/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.idl b/tools/AmbSignalMapper/lib/Intel/IviPoc/templates/ambtmpl_plugin.idl
new file mode 100644 (file)
index 0000000..fcc0bfc
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+
+
+Details. 
+
+\def-api-feature http://tizen.org/api/vehicle 
+\brief Allows access to the AmbTmplPlugin API
+
+
+
+*/
+
+module AmbTmplPlugin {
+
+/*GENERATED_CODE*/
+
+};
+
diff --git a/tools/AmbSignalMapper/t/00-load.t b/tools/AmbSignalMapper/t/00-load.t
new file mode 100644 (file)
index 0000000..e781cd6
--- /dev/null
@@ -0,0 +1,13 @@
+#!perl -T
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+plan tests => 1;
+
+BEGIN {
+    use_ok( 'Intel::IviPoc::AmbPluginGenerator' ) || print "Bail out!\n";
+}
+
+diag( "Testing Intel::IviPoc::AmbPluginGenerator $Intel::IviPoc::AmbPluginGenerator::VERSION, Perl $], $^X" );
diff --git a/tools/AmbSignalMapper/t/ambsignalmapper.t b/tools/AmbSignalMapper/t/ambsignalmapper.t
new file mode 100644 (file)
index 0000000..e266d35
--- /dev/null
@@ -0,0 +1,18 @@
+#!perl -T
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+use Intel::IviPoc::AmbPluginGenerator;
+
+plan tests => 1;
+
+# TEST
+{
+       my $src_text = "This is a text strig to check if AmbTmpl, AMBTMPL and ambtmpl are replaced with myplugin respectively and with proper caseing";
+       my $replace_text = "MyPlugin";
+       my $dst_text = "This is a text strig to check if MyPlugin, MYPLUGIN and myplugin are replaced with myplugin respectively and with proper caseing";
+       my $ret = Intel::IviPoc::AmbPluginGenerator::replaceTemplateStrings($src_text, $replace_text);
+       ok ( $ret eq $dst_text, "  replaceTemplateStrings works" );
+}
+
diff --git a/tools/AmbSignalMapper/t/boilerplate.t b/tools/AmbSignalMapper/t/boilerplate.t
new file mode 100644 (file)
index 0000000..35d1da6
--- /dev/null
@@ -0,0 +1,57 @@
+#!perl -T
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+plan tests => 3;
+
+sub not_in_file_ok {
+    my ($filename, %regex) = @_;
+    open( my $fh, '<', $filename )
+        or die "couldn't open $filename for reading: $!";
+
+    my %violated;
+
+    while (my $line = <$fh>) {
+        while (my ($desc, $regex) = each %regex) {
+            if ($line =~ $regex) {
+                push @{$violated{$desc}||=[]}, $.;
+            }
+        }
+    }
+
+    if (%violated) {
+        fail("$filename contains boilerplate text");
+        diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
+    } else {
+        pass("$filename contains no boilerplate text");
+    }
+}
+
+sub module_boilerplate_ok {
+    my ($module) = @_;
+    not_in_file_ok($module =>
+        'the great new $MODULENAME'   => qr/ - The great new /,
+        'boilerplate description'     => qr/Quick summary of what the module/,
+        'stub function definition'    => qr/function[12]/,
+    );
+}
+
+TODO: {
+  local $TODO = "Need to replace the boilerplate text";
+
+  not_in_file_ok(README =>
+    "The README is used..."       => qr/The README is used/,
+    "'version information here'"  => qr/to provide version information/,
+  );
+
+  not_in_file_ok(Changes =>
+    "placeholder date/time"       => qr(Date/time)
+  );
+
+  module_boilerplate_ok('lib/Intel/IviPoc/AmbPluginGenerator.pm');
+
+
+}
+
diff --git a/tools/AmbSignalMapper/t/manifest.t b/tools/AmbSignalMapper/t/manifest.t
new file mode 100644 (file)
index 0000000..6ddfe36
--- /dev/null
@@ -0,0 +1,15 @@
+#!perl -T
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+unless ( $ENV{RELEASE_TESTING} ) {
+    plan( skip_all => "Author tests not required for installation" );
+}
+
+my $min_tcm = 0.9;
+eval "use Test::CheckManifest $min_tcm";
+plan skip_all => "Test::CheckManifest $min_tcm required" if $@;
+
+ok_manifest();
diff --git a/tools/AmbSignalMapper/t/pod-coverage.t b/tools/AmbSignalMapper/t/pod-coverage.t
new file mode 100644 (file)
index 0000000..866fac2
--- /dev/null
@@ -0,0 +1,20 @@
+#!perl -T
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+# Ensure a recent version of Test::Pod::Coverage
+my $min_tpc = 1.08;
+eval "use Test::Pod::Coverage $min_tpc";
+plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
+    if $@;
+
+# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
+# but older versions don't recognize some common documentation styles
+my $min_pc = 0.18;
+eval "use Pod::Coverage $min_pc";
+plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
+    if $@;
+
+all_pod_coverage_ok();
diff --git a/tools/AmbSignalMapper/t/pod.t b/tools/AmbSignalMapper/t/pod.t
new file mode 100644 (file)
index 0000000..a0054e9
--- /dev/null
@@ -0,0 +1,12 @@
+#!perl -T
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+# Ensure a recent version of Test::Pod
+my $min_tp = 1.22;
+eval "use Test::Pod $min_tp";
+plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
+
+all_pod_files_ok();