--- /dev/null
+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
--- /dev/null
+Revision history for AmbSignalMapper
+
+0.01 Date/time
+ First version, released on an unsuspecting world.
+
--- /dev/null
+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
--- /dev/null
+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
+}
+
+
--- /dev/null
+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
+
+
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+<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><ivipoc at intel.com></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>
--- /dev/null
+<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><ivipoc at intel.com></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>
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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: "\""
--- /dev/null
+#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
--- /dev/null
+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)
+
+############################################################################################################################################
--- /dev/null
+/*****************************************************************
+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;
+}
--- /dev/null
+/*****************************************************************
+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_ */
--- /dev/null
+/*****************************************************************
+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_ */
--- /dev/null
+/*****************************************************************
+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*/
+}
--- /dev/null
+/*****************************************************************
+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_ */
--- /dev/null
+/**
+
+
+Details.
+
+\def-api-feature http://tizen.org/api/vehicle
+\brief Allows access to the AmbTmplPlugin API
+
+
+
+*/
+
+module AmbTmplPlugin {
+
+/*GENERATED_CODE*/
+
+};
+
--- /dev/null
+#!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" );
--- /dev/null
+#!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" );
+}
+
--- /dev/null
+#!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');
+
+
+}
+
--- /dev/null
+#!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();
--- /dev/null
+#!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();
--- /dev/null
+#!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();