summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Sagnes <guy.sagnes@continental-corporation.com>2014-02-25 10:32:29 +0100
committerRalf Anton Beier <ralf.anton.beier@continental-corporation.com>2014-02-25 11:33:41 +0100
commit880e7ffe185e5b410ee6183c4ce355a8a204ab28 (patch)
tree9c18d6aecfaf69a6753b4c2f251583cfe9f3722e
parent94b07e2221c3333a5a54f689eca4249667892f74 (diff)
downloadpersistence-common-object-880e7ffe185e5b410ee6183c4ce355a8a204ab28.tar.gz
persistence-common-object-880e7ffe185e5b410ee6183c4ce355a8a204ab28.tar.bz2
persistence-common-object-880e7ffe185e5b410ee6183c4ce355a8a204ab28.zip
Added version 1.0.1
12.12.2013 * add missing licenses information / update after review feedback 20131212 - J.Kowalski 03.12.2013 * Persistence Common Object - OIP BL 0.9.130 08.08.2013 * Add instrumentation for debug purposes (low level db access) 18.06.2013 * persistence-common version 1.0.1 - Add makefile to allow creation of auto-generated code - Default error handler causes the termination of the calling process - de-central build of the common part 02.05.2013 * initial version of the common persistence libraries Change-Id: I6ac6b7f1fe453537835ac32f664c04d537d732db Signed-off-by: Guy Sagnes <guy.sagnes@continental-corporation.com>
-rw-r--r--AUTHORS3
-rw-r--r--COPYING373
-rw-r--r--ChangeLog0
-rw-r--r--INSTALL370
-rw-r--r--Makefile.am19
-rw-r--r--NEWS3
-rw-r--r--autogen.sh19
-rw-r--r--configure.ac118
-rw-r--r--dbus_config/org.genivi.persistence.admin.conf16
-rw-r--r--dbus_specifications/org.genivi.persistence.admin.xml46
-rw-r--r--dbus_specifications/org.genivi.persistence.admin_generate.txt1
-rw-r--r--generated/Makefile.am29
-rw-r--r--inc/private/pers_ipc_dbus_if.h127
-rw-r--r--inc/private/pers_low_level_db_access_if.h157
-rw-r--r--inc/protected/persComDataOrg.h265
-rw-r--r--inc/protected/persComDbAccess.h154
-rw-r--r--inc/protected/persComErrors.h69
-rw-r--r--inc/protected/persComIpc.h309
-rw-r--r--inc/protected/persComRct.h226
-rw-r--r--inc/protected/persComTypes.h213
-rw-r--r--pkgconfig/libperscommon.pc.in11
-rw-r--r--src/Makefile.am70
-rw-r--r--src/pers_data_organization.c101
-rw-r--r--src/pers_ipc.c316
-rw-r--r--src/pers_ipc_dbus.c1590
-rw-r--r--src/pers_local_shared_db_access.c287
-rw-r--r--src/pers_low_level_db_access.c1515
-rw-r--r--src/pers_resource_config_table.c247
28 files changed, 6654 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..a776944
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Ionut Ieremie <Ionut.Ieremie@continental-corporation.com>
+Guy Sagnes <Guy.Sagnes@continental-corporation.com>
+Petrica Manoila <Petrica.Manoila@continental-corporation.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..14e2f77
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ChangeLog
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..a1e89e1
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,370 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
+Inc.
+
+ Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package. Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below. The lack of an optional feature in a given package is not
+necessarily a bug. More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+ The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package, generally using the just-built uninstalled binaries.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation. When installing into a prefix owned by root, it is
+ recommended that the package be configured and built as a regular
+ user, and only the `make install' phase executed with root
+ privileges.
+
+ 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ this time using the binaries in their final installed location.
+ This target does not install anything. Running this target as a
+ regular user, particularly if the prior `make install' required
+ root privileges, verifies that the installation completed
+ correctly.
+
+ 6. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 7. Often, you can also type `make uninstall' to remove the installed
+ files again. In practice, not all packages have tested that
+ uninstallation works correctly, even though it is required by the
+ GNU Coding Standards.
+
+ 8. Some packages, particularly those that use Automake, provide `make
+ distcheck', which can by used by developers to test that all other
+ targets like `make install' and `make uninstall' work correctly.
+ This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'. This
+is known as a "VPATH" build.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them. In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+ The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+ The first method involves providing an override variable for each
+affected directory. For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'. Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the `DESTDIR' variable. For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names. The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters. On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+ Some packages offer the ability to configure how verbose the
+execution of `make' will be. For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved. Use GNU `make'
+instead.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS
+ KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..b18571e
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,19 @@
+#######################################################################################################################
+#
+# Copyright (C) 2012 Continental Automotive Systems, Inc.
+#
+# Author: Ana.Chisca@continental-corporation.com
+#
+# Makefile template for the persistence common library
+#
+# Process this file with automake to produce a Makefile.in.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#######################################################################################################################
+
+# Build trough subfolders. Make sure "generated" is called before "src".
+ACLOCAL_AMFLAGS=-I m4
+SUBDIRS = generated src
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e7f671b
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,3 @@
+1.0.1
+=====
+* Initial release of the persistence common interface
diff --git a/autogen.sh b/autogen.sh
new file mode 100644
index 0000000..daeaa51
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+#
+#
+# Copyright (C) 2012 Continental Automotive Systems, Inc.
+#
+# Author: Ana.Chisca@continental-corporation.com
+#
+# Script to create necessary files/folders from a fresh git check out.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+###############################################################################
+
+mkdir -p m4
+
+autoreconf --verbose --install --force
+./configure $@ \ No newline at end of file
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..f9a62e8
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,118 @@
+#######################################################################################################################
+#
+# Copyright (C) 2012 Continental Automotive Systems, Inc.
+#
+# Author: Ana.Chisca@continental-corporation.com
+#
+# Configure template for the persistence-common library
+#
+# Process this file with autoconf to produce a configure script.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#######################################################################################################################
+
+dnl **************************************************************************
+dnl *** First, define all of the version numbers up front ***
+dnl *** In particular, this allows the version macro to be used in AC_INIT ***
+dnl **************************************************************************
+m4_define([LIBPERSOCOMMON_VERSION_S],[1.0.1])
+m4_define([LIBPERSOCOMMON_VERSION_N],[1000001])
+
+dnl ***************************
+dnl *** Initialize autoconf ***
+dnl ***************************
+AC_INIT([persistence-common],[LIBPERSOCOMMON_VERSION_S()])
+AC_COPYRIGHT([Copyright (c) 2012 Continental Automotive GmbH])
+AC_PREREQ([2.50])
+
+dnl ***************************
+dnl *** Initialize automake ***
+dnl ***************************
+AM_INIT_AUTOMAKE()
+AC_USE_SYSTEM_EXTENSIONS()
+AC_CONFIG_MACRO_DIR([m4])
+AC_SUBST([ACLOCAL_AMFLAGS], ["$ACLOCAL_FLAGS -I m4"])
+
+dnl *********************************
+dnl *** Shared library versioning ***
+dnl *********************************
+PERSCOMMON_MAJOR=$((((LIBPERSOCOMMON_VERSION_N() / 1000) / 1000) % 1000 ))
+PERSCOMMON_MINOR=$(( (LIBPERSOCOMMON_VERSION_N() / 1000) % 1000 ))
+PERSCOMMON_MICRO=$(( LIBPERSOCOMMON_VERSION_N() % 1000 ))
+GENERIC_LIBRARY_VERSION=$PERSCOMMON_MAJOR:$PERSCOMMON_MINOR:$PERSCOMMON_MICRO
+AC_SUBST(GENERIC_LIBRARY_VERSION)
+
+dnl ********************************
+dnl *** Check for basic programs ***
+dnl ********************************
+AC_PROG_CC()
+AM_PROG_CC_C_O()
+AC_PROG_CXX()
+AC_PROG_INSTALL()
+
+dnl ***************************
+dnl *** Initialize lib tool ***
+dnl ***************************
+AC_DISABLE_STATIC()
+AC_PROG_LIBTOOL()
+
+dnl ***************************************
+dnl *** Check for standard header files ***
+dnl ***************************************
+AC_CHECK_HEADERS([string.h])
+
+dnl ***********************************
+dnl *** Check for library functions ***
+dnl ***********************************
+AC_FUNC_STRNLEN
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([memcpy])
+AC_CHECK_FUNCS([memset])
+
+dnl ********************************************************************
+dnl *** Check for typedefs, structures, and compiler characteristics ***
+dnl ********************************************************************
+AC_HEADER_STDBOOL
+AC_TYPE_SIZE_T
+AC_TYPE_UINT8_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+
+dnl ***********************************
+dnl *** Check for required packages ***
+dnl ***********************************
+PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([DLT], [automotive-dlt >= 2.2.0])
+PKG_CHECK_MODULES([ITZAM], [libitzam >= 6.0.4])
+ITZAM_LIBS="-litzam"
+
+dnl *************************************
+dnl *** Define extra paths ***
+dnl *************************************
+AC_ARG_WITH([dbuspolicydir],
+ AS_HELP_STRING([--with-dbuspolicydirdir=DIR], [Directory for D-Bus system policy files]),
+ [],
+ [with_dbuspolicydir=$(pkg-config --silence-errors --variable=sysconfdir dbus-1)/dbus-1/system.d])
+AC_SUBST([dbuspolicydir], [$with_dbuspolicydir])
+
+# Derive path for storing 'dbus' interface files (e. g. /usr/share/dbus-1/interfaces)
+AC_ARG_WITH([dbusinterfacesdir],
+ AS_HELP_STRING([--with-dbusinterfacesdir=DIR], [Directory for D-Bus interface files]),
+ [],
+ [with_dbusinterfacesdir=$(pkg-config --silence-errors --variable=interfaces_dir dbus-1)])
+AC_SUBST([dbusinterfacesdir], [$with_dbusinterfacesdir])
+
+dnl *******************************
+dnl *** Define configure output ***
+dnl *******************************
+AC_CONFIG_FILES(Makefile src/Makefile generated/Makefile pkgconfig/libperscommon.pc)
+
+AC_OUTPUT
+
+
diff --git a/dbus_config/org.genivi.persistence.admin.conf b/dbus_config/org.genivi.persistence.admin.conf
new file mode 100644
index 0000000..fac05f9
--- /dev/null
+++ b/dbus_config/org.genivi.persistence.admin.conf
@@ -0,0 +1,16 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root can own the service -->
+ <policy user="root">
+ <allow own="org.genivi.persistence.admin"/>
+ <allow send_destination="org.genivi.persistence.admin"/>
+ <allow send_interface="org.genivi.persistence.admin"/>
+ </policy>
+ <policy context="default">
+ <allow send_destination="org.genivi.persistence.admin"/>
+ <allow send_interface="org.genivi.persistence.admin"/>
+ </policy>
+</busconfig> \ No newline at end of file
diff --git a/dbus_specifications/org.genivi.persistence.admin.xml b/dbus_specifications/org.genivi.persistence.admin.xml
new file mode 100644
index 0000000..57ce885
--- /dev/null
+++ b/dbus_specifications/org.genivi.persistence.admin.xml
@@ -0,0 +1,46 @@
+<!--
+*
+* Copyright (C) 2012-2013 Continental Automotive GmbH.
+*
+* Author: guy.sagnes@continental-corporation.com
+*
+* XML model of the dbus interfaces for the test NodeStateMachine
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2012.11.27 uidu0250 Initial version
+*
+-->
+<node>
+ <interface name="org.genivi.persistence.admin">
+ <method name="RegisterPersAdminNotification">
+ <arg name="BusName" type="s" direction="in"/>
+ <arg name="ObjName" type="s" direction="in"/>
+ <arg name="NotificationFlag" type="i" direction="in"/>
+ <arg name="TimeoutMs" type="u" direction="in"/>
+ <arg name="ErrorCode" type="i" direction="out"/>
+ </method>
+ <method name="UnRegisterPersAdminNotification">
+ <arg name="BusName" type="s" direction="in"/>
+ <arg name="ObjName" type="s" direction="in"/>
+ <arg name="NotificationFlag" type="i" direction="in"/>
+ <arg name="TimeoutMs" type="u" direction="in"/>
+ <arg name="ErrorCode" type="i" direction="out"/>
+ </method>
+ <method name="PersistenceAdminRequestCompleted">
+ <arg name="RequestId" type="u" direction="in"/>
+ <arg name="Status" type="i" direction="in"/>
+ <arg name="ErrorCode" type="i" direction="out"/>
+ </method>
+ </interface>
+ <interface name="org.genivi.persistence.adminconsumer">
+ <method name="PersistenceAdminRequest">
+ <arg name="Request" type="i" direction="in"/>
+ <arg name="RequestId" type="i" direction="in"/>
+ <arg name="ErrorCode" type="i" direction="out"/>
+ </method>
+ </interface>
+</node> \ No newline at end of file
diff --git a/dbus_specifications/org.genivi.persistence.admin_generate.txt b/dbus_specifications/org.genivi.persistence.admin_generate.txt
new file mode 100644
index 0000000..4f374ef
--- /dev/null
+++ b/dbus_specifications/org.genivi.persistence.admin_generate.txt
@@ -0,0 +1 @@
+gdbus-codegen --interface-prefix="org.genivi.persistence." --c-namespace="OipPersistence" --generate-c-code="PasClientNotificationGen" org.genivi.persistence.admin.xml \ No newline at end of file
diff --git a/generated/Makefile.am b/generated/Makefile.am
new file mode 100644
index 0000000..52192d4
--- /dev/null
+++ b/generated/Makefile.am
@@ -0,0 +1,29 @@
+#######################################################################################################################
+#
+# Copyright (C) 2012 Continental Automotive Systems, Inc.
+#
+# Author: Ana.Chisca@continental-corporation.com
+#
+# Makefile template for the Persistence Administration Service generated sources
+#
+# Process this file with automake to produce a Makefile.in.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#######################################################################################################################
+
+# List generated sources here to assert that they are available at build start
+BUILT_SOURCES = PasClientNotificationGen.c \
+ PasClientNotificationGen.h
+
+# Delete all generated files on 'make clean'
+CLEANFILES = PasClientNotificationGen.c \
+ PasClientNotificationGen.h
+
+
+# Targets to create generated sources during the build
+
+PasClientNotificationGen.c PasClientNotificationGen.h: $(top_srcdir)/dbus_specifications/org.genivi.persistence.admin.xml
+ gdbus-codegen --interface org.genivi.persistence. --c-namespace OipPersistence --generate-c-code PasClientNotificationGen $(top_srcdir)/dbus_specifications/org.genivi.persistence.admin.xml
diff --git a/inc/private/pers_ipc_dbus_if.h b/inc/private/pers_ipc_dbus_if.h
new file mode 100644
index 0000000..d6d8786
--- /dev/null
+++ b/inc/private/pers_ipc_dbus_if.h
@@ -0,0 +1,127 @@
+#ifndef OSS_PERSISTENCE_COMMON_IPC_DBUS_H
+#define OSS_PERSISTENCE_COMMON_IPC_DBUS_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Petrica.Manoila@continental-corporation.com
+*
+* Interface: private - specifies the DBus interface for PersCommonIPC
+*
+* The file defines contains the defines according to
+* https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Version Reason
+* 2013.04.03 uidu0250 1.0.0.0 CSP_WZ#2739 : Initial version of the interface
+*
+**********************************************************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* #ifdef __cplusplus */
+
+#include "persComTypes.h"
+
+#define PERSIST_IPC_DBUS_INTERFACE_VERSION (0x01000000U)
+
+
+#define PERSISTENCE_ADMIN_BUS_TYPE G_BUS_TYPE_SYSTEM
+#define PERSISTENCE_ADMIN_BUS_NAME "org.genivi.persistence.admin"
+#define PERSISTENCE_ADMIN_OBJ_PATH "/org/genivi/persistence/admin"
+#define PERSISTENCE_ADMIN_IFACE "org.genivi.persistence.admin"
+#define PERSISTENCE_ADMIN_CONSUMER_OBJ_PATH "/org/genivi/persistence/adminconsumer"
+
+/* TO DO: remove when PCL implementation is adapted to PersCommonIPC */
+#define PERSISTENCE_ADMIN_CONSUMER_IFACE "org.genivi.persistence.adminconsumer"
+#define PERSISTENCE_ADMIN_CONSUMER_METHOD_PERS_ADMIN_REQ "PersistenceAdminRequest"
+
+/**
+ * \brief Initialize PAS IPC DBus component
+ *
+ * \note : The function creates the DBus connection and tries to obtain the DBus name
+ * and exports the org.genivi.persistence.admin interface.
+ * It runs the DBus main loop on a second thread.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPASInitInfo_s structure containing
+ * the supported callbacks
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcInitPAS_DBus_high(PersAdminPASInitInfo_s *pInitInfo);
+
+
+/**
+ * \brief Sends over DBus a request to the PCL client specified by clientId.
+ *
+ * \note : Each requestId should be unique.
+ *
+ * \param clientID [in] the client ID returned by the supplied pRegCB callback
+ * \param requestID [in] a unique identifier generated for every request
+ * \param request [in] the request to be sent (bitfield using a valid
+ * combination of any of the following flags :
+ * ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcSendRequestToPCL_DBus_high( sint_t clientID,
+ sint_t requestID,
+ uint_t request);
+
+
+/**
+ * \brief Register PCL client to PAS over DBus
+ *
+ * \note : An additional thread is created for communication purposes.
+ * Initialize members of the supplied PersAdminPCLInitInfo_s structure before calling this function.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPCLInitInfo_s structure containing
+ * the supported callbacks
+ * \param flags [in] supported notification flags
+ * \param timeout [in] maximum time needed to process any supported request
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcRegisterToPAS_DBus_high( PersAdminPCLInitInfo_s * pInitInfo,
+ uint_t flags,
+ uint_t timeout);
+
+
+/**
+ * \brief Un-Register PCL client application from PAS over DBus
+ *
+ * \note : The additional thread created for communication purposes is stopped.
+ *
+ * \param flags [in] supported notification flags
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcUnRegisterFromPAS_DBus_high( uint_t flags);
+
+
+/**
+ * \brief Send 'request processed' confirmation to PAS over DBus
+ * \note : Send confirmation to PAS that the request specified by requestId has been processed.
+ * The status parameter should reflect this request and could also return an error.
+ *
+ * \param requestID [in] the ID of the processed request
+ * \param status [in] the status of the request processed by PCL
+ * - In case of success: bitfield using any of the following flags, depending on the request : ::PERSISTENCE_STATUS_LOCKED.
+ * - In case of error: the sum of ::PERSISTENCE_STATUS_ERROR and an error code \ref PERS_COM_IPC_DEFINES_ERROR is returned.
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcSendConfirmationToPAS_DBus_high( sint_t requestID,
+ uint_t status);
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" { */
+
+#endif /* OSS_PERSISTENCE_COMMON_IPC_DBUS_H */
+
diff --git a/inc/private/pers_low_level_db_access_if.h b/inc/private/pers_low_level_db_access_if.h
new file mode 100644
index 0000000..c09838e
--- /dev/null
+++ b/inc/private/pers_low_level_db_access_if.h
@@ -0,0 +1,157 @@
+#ifndef PERSISTENCE_LOW_LEVEL_DB_ACCESS_H
+#define PERSISTENCE_LOW_LEVEL_DB_ACCESS_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Interface TODO
+*
+* The file defines the interfaces TODO
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Version Reason
+* 2013.02.05 uidl9757 1.0.0.0 CSP_WZ#2220: Adaptation for open source
+* 2013.01.03 uidl9757 1.0.0.0 CSP_WZ#2060: Remove "cursor" interface
+* 2012.12.17 uidl9757 1.0.0.0 CSP_WZ#2060: Changes to allow optimized access to DB
+* 2012.12.10 uidl9757 1.0.0.0 CSP_WZ#2060: Initial version of the interface
+*
+**********************************************************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* #ifdef __cplusplus */
+
+#include "persComTypes.h"
+
+#define PERSIST_LOW_LEVEL_DB_ACCESS_INTERFACE_VERSION (0x03000000U)
+
+/* The supported purposes of low level DBs
+ * Needed to allow different setups of DBs according to their purposes
+ */
+typedef enum pers_lldb_purpose_e_
+{
+ PersLldbPurpose_RCT = 0, /* Resource-Configuration-Table */
+ PersLldbPurpose_DB, /* Local/Shared DB */
+ /* add new entries here */
+ PersLldbPurpose_LastEntry
+}pers_lldb_purpose_e ;
+
+
+/**
+ * @brief write a key-value pair into database
+ * @note : DB type is identified from dbPathname (based on extension)
+ *
+ * @param dbPathname [in] absolute path to DB
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ * @param bForceCreationIfNotPresent [in] if true, the DB is created if it does not exist
+ *
+ * @return >=0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_open(str_t const * dbPathname, pers_lldb_purpose_e ePurpose, bool_t bForceCreationIfNotPresent) ;
+
+
+/**
+ * @brief write a key-value pair into database
+ * @note : DB type is identified from dbPathname (based on extension)
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ *
+ * @return 0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_close(sint_t handlerDB) ;
+
+/**
+ * @brief write a key-value pair into database
+ * @note : DB type is identified from dbPathname (based on extension)
+ * @note : DB is created if it does not exist
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ * @param key [in] key's name
+ * @param data [in] buffer with key's data
+ * @param dataSize [in] size of key's data
+ *
+ * @return 0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_write_key(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key, str_t const * data, sint_t dataSize) ;
+
+
+/**
+ * @brief read a key's value from database
+ * @note : DB type is identified from dbPathname (based on extension)
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ * @param key [in] key's name
+ * @param dataBuffer_out [out]buffer where to return the read data
+ * @param bufSize [in] size of dataBuffer_out
+ *
+ * @return read size, or negative value in case of error (see pers_error_codes.h)
+ */
+sint_t pers_lldb_read_key(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key, pstr_t dataBuffer_out, sint_t bufSize) ;
+
+/**
+ * @brief read a key's value from database
+ * @note : DB type is identified from dbPathname (based on extension)
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ * @param key [in] key's name
+ * @return key's size, or negative value in case of error (see pers_error_codes.h)
+ */
+sint_t pers_lldb_get_key_size(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key) ;
+
+/**
+ * @brief delete key from database
+ * @note : DB type is identified from dbPathname (based on extension)
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ * @param key [in] key's name
+ *
+ * @return 0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_delete_key(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key) ;
+
+
+/**
+ * @brief Find the buffer's size needed to accomodate the listing of keys' names in database
+ * @note : DB type is identified from dbPathname (based on extension)
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ *
+ * @return needed size, or negative value in case of error (see pers_error_codes.h)
+ */
+sint_t pers_lldb_get_size_keys_list(sint_t handlerDB, pers_lldb_purpose_e ePurpose) ;
+
+
+/**
+ * @brief List the keys' names in database
+ * @note : DB type is identified from dbPathname (based on extension)
+ * @note : keys are separated by '\0'
+ *
+ * @param handlerDB [in] handler obtained with pers_lldb_open
+ * @param ePurpose [in] see pers_lldb_purpose_e
+ * @param listingBuffer_out [out]buffer where to return the listing
+ * @param bufSize [in] size of listingBuffer_out
+ *
+ * @return listing size, or negative value in case of error (see pers_error_codes.h)
+ */
+ sint_t pers_lldb_get_keys_list(sint_t handlerDB, pers_lldb_purpose_e ePurpose, pstr_t listingBuffer_out, sint_t bufSize) ;
+
+
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" { */
+/** \} */ /* End of API */
+#endif /* PERSISTENCE_LOW_LEVEL_DB_ACCESS_H */
+
diff --git a/inc/protected/persComDataOrg.h b/inc/protected/persComDataOrg.h
new file mode 100644
index 0000000..0c9a4bb
--- /dev/null
+++ b/inc/protected/persComDataOrg.h
@@ -0,0 +1,265 @@
+#ifndef OSS_PERSISTENCE_COMMON_DATA_ORGANIZATION_H
+#define OSS_PERSISTENCE_COMMON_DATA_ORGANIZATION_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Interface: protected - specifies the organization of Genivi's persistence data
+*
+* The file defines contains the defines according to
+* https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.03.21 uidl9757 3.1.0.0 CSP_WZ#2798: Updates according to changes in data organization
+* 2013.01.23 uidl9757 3.0.0.0 CSP_WZ#2060: CoC_SSW:Persistence: common interface to be used by both PCL and PAS
+*
+**********************************************************************************************************************/
+
+/** \defgroup PERS_COM_DATA_ORG Data organization API
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /** #ifdef __cplusplus */
+
+/** \defgroup PERS_DATA_ORG_IF_VERSION Interface version
+ * \{
+ */
+#define PERS_COM_DATA_ORG_INTERFACE_VERSION (0x03010000U)
+/** \} */
+
+/** \defgroup PERS_ORG_DEFINES Max path length
+ * \{
+ */
+/** max path length when accessing a file (absolute path + filename) */
+#define PERS_ORG_MAX_LENGTH_PATH_FILENAME 255
+/** \} */
+
+/** \defgroup PERS_ORG_DATABASE_NAMES Databases' names
+ * \{
+ */
+
+/** resource configuration table name */
+#define PERS_ORG_RCT_NAME "resource-table-cfg.itz"
+#define PERS_ORG_RCT_NAME_ "/"PERS_ORG_RCT_NAME
+extern const char* gResTableCfg; /**< PERS_ORG_RCT_NAME_ */
+
+/** local factory-default database */
+#define PERS_ORG_LOCAL_FACTORY_DEFAULT_DB_NAME "default-data.itz"
+#define PERS_ORG_LOCAL_FACTORY_DEFAULT_DB_NAME_ "/"PERS_ORG_LOCAL_FACTORY_DEFAULT_DB_NAME
+extern const char* gLocalFactoryDefault; /**< PERS_ORG_LOCAL_FACTORY_DEFAULT_DB_NAME_ */
+
+/** local configurable-default database */
+#define PERS_ORG_LOCAL_CONFIGURABLE_DEFAULT_DB_NAME "configurable-default-data.itz"
+#define PERS_ORG_LOCAL_CONFIGURABLE_DEFAULT_DB_NAME_ "/"PERS_ORG_LOCAL_CONFIGURABLE_DEFAULT_DB_NAME
+extern const char* gLocalConfigurableDefault; /**< PERS_ORG_LOCAL_CONFIGURABLE_DEFAULT_DB_NAME_ */
+
+
+/** shared cached default database */
+#define PERS_ORG_SHARED_CACHE_DEFAULT_DB_NAME "cached-default.itz"
+#define PERS_ORG_SHARED_CACHE_DEFAULT_DB_NAME_ "/"PERS_ORG_SHARED_CACHE_DEFAULT_DB_NAME
+extern const char* gSharedCachedDefault; /**< PERS_ORG_SHARED_CACHE_DEFAULT_DB_NAME_ */
+
+
+/** shared cached database */
+#define PERS_ORG_SHARED_CACHE_DB_NAME "cached.itz"
+#define PERS_ORG_SHARED_CACHE_DB_NAME_ "/"PERS_ORG_SHARED_CACHE_DB_NAME
+extern const char* gSharedCached; /**< PERS_ORG_SHARED_CACHE_DB_NAME_ */
+
+
+/** shared write through default database */
+#define PERS_ORG_SHARED_WT_DEFAULT_DB_NAME "wt-default.itz"
+#define PERS_ORG_SHARED_WT_DEFAULT_DB_NAME_ "/"PERS_ORG_SHARED_WT_DEFAULT_DB_NAME
+extern const char* gSharedWtDefault; /**< PERS_ORG_SHARED_WT_DEFAULT_DB_NAME_ */
+
+
+/** shared write through database */
+#define PERS_ORG_SHARED_WT_DB_NAME "wt.itz"
+#define PERS_ORG_SHARED_WT_DB_NAME_ "/"PERS_ORG_SHARED_WT_DB_NAME
+extern const char* gSharedWt; /**< PERS_ORG_SHARED_WT_DB_NAME_ */
+
+
+/** local cached default database */
+#define PERS_ORG_LOCAL_CACHE_DEFAULT_DB_NAME "cached-default.itz"
+#define PERS_ORG_LOCAL_CACHE_DEFAULT_DB_NAME_ "/" PERS_ORG_LOCAL_CACHE_DEFAULT_DB_NAME
+extern const char* gLocalCachedDefault; /**< PERS_ORG_LOCAL_CACHE_DEFAULT_DB_NAME_ */
+
+
+/** local cached database */
+#define PERS_ORG_LOCAL_CACHE_DB_NAME "cached.itz"
+#define PERS_ORG_LOCAL_CACHE_DB_NAME_ "/"PERS_ORG_LOCAL_CACHE_DB_NAME
+extern const char* gLocalCached; /**< PERS_ORG_LOCAL_CACHE_DB_NAME_ */
+
+
+/** local write through default database */
+#define PERS_ORG_LOCAL_WT_DEFAULT_DB_NAME "wt-default.itz"
+#define PERS_ORG_LOCAL_WT_DEFAULT_DB_NAME_ "/"PERS_ORG_LOCAL_WT_DEFAULT_DB_NAME
+extern const char* gLocalWtDefault; /**< PERS_ORG_LOCAL_WT_DEFAULT_DB_NAME_ */
+
+/** local write through default database */
+#define PERS_ORG_LOCAL_WT_DB_NAME "wt.itz"
+#define PERS_ORG_LOCAL_WT_DB_NAME_ "/" PERS_ORG_LOCAL_WT_DB_NAME
+extern const char* gLocalWt; /**< PERS_ORG_LOCAL_WT_DB_NAME_ */
+
+/** \} */
+
+
+/** \defgroup PERS_ORG_FOLDER_NAMES Folders' names
+ * \{
+ */
+
+/** directory structure node name definition */
+#define PERS_ORG_NODE_FOLDER_NAME "node"
+#define PERS_ORG_NODE_FOLDER_NAME_ "/" PERS_ORG_NODE_FOLDER_NAME
+extern const char* gNode; /**< PERS_ORG_NODE_FOLDER_NAME_ */
+
+
+/** directory structure user name definition */
+#define PERS_ORG_USER_FOLDER_NAME "user"
+#define PERS_ORG_USER_FOLDER_NAME_ "/"PERS_ORG_USER_FOLDER_NAME "/"
+extern const char* gUser; /**< PERS_ORG_USER_FOLDER_NAME_ */
+
+
+/** directory structure seat name definition */
+#define PERS_ORG_SEAT_FOLDER_NAME "seat"
+#define PERS_ORG_SEAT_FOLDER_NAME_ "/"PERS_ORG_SEAT_FOLDER_NAME "/"
+extern const char* gSeat; /**< PERS_ORG_SEAT_FOLDER_NAME_ */
+
+/** directory structure shared name definition */
+#define PERS_ORG_SHARED_FOLDER_NAME "shared"
+#define PERS_ORG_SHARED_FOLDER_NAME_ "/"PERS_ORG_SHARED_FOLDER_NAME
+extern const char* gSharedPathName; /**< PERS_ORG_SHARED_FOLDER_NAME */
+
+/** directory structure group name definition */
+#define PERS_ORG_GROUP_FOLDER_NAME "group"
+#define PERS_ORG_GROUP_FOLDER_NAME_ "/"PERS_ORG_GROUP_FOLDER_NAME
+
+/** directory structure public name definition */
+#define PERS_ORG_PUBLIC_FOLDER_NAME "public"
+#define PERS_ORG_PUBLIC_FOLDER_NAME_ "/"PERS_ORG_PUBLIC_FOLDER_NAME
+
+/** directory structure defaultData name definition */
+#define PERS_ORG_DEFAULT_DATA_FOLDER_NAME "defaultData"
+#define PERS_ORG_DEFAULT_DATA_FOLDER_NAME_ "/"PERS_ORG_DEFAULT_DATA_FOLDER_NAME
+
+/** directory structure configurableDefaultData name definition */
+#define PERS_ORG_CONFIG_DEFAULT_DATA_FOLDER_NAME "configurableDefaultData"
+#define PERS_ORG_CONFIG_DEFAULT_DATA_FOLDER_NAME_ "/"PERS_ORG_CONFIG_DEFAULT_DATA_FOLDER_NAME
+
+
+/** directory structure cached name definition */
+#define PERS_ORG_CACHE_FOLDER_NAME "mnt-c"
+#define PERS_ORG_CACHE_FOLDER_NAME_ "/"PERS_ORG_CACHE_FOLDER_NAME
+/** directory structure write-through name definition */
+#define PERS_ORG_WT_FOLDER_NAME "mnt-wt"
+#define PERS_ORG_WT_FOLDER_NAME_ "/"PERS_ORG_WT_FOLDER_NAME
+
+
+/** path prefix for all data: /Data */
+#define PERS_ORG_ROOT_PATH "/Data"
+extern const char* gRootPath; /**< PERS_ORG_ROOT_PATH */
+
+/** \} */
+
+
+/** \defgroup PERS_ORG_PATHS Paths
+ * \{
+ */
+
+/** cache root path application: /Data/mnt-c */
+#define PERS_ORG_LOCAL_APP_CACHE_PATH PERS_ORG_ROOT_PATH PERS_ORG_CACHE_FOLDER_NAME_
+#define PERS_ORG_LOCAL_APP_CACHE_PATH_ PERS_ORG_LOCAL_APP_CACHE_PATH"/"
+/** wt root path application: /Data/mnt-wt */
+#define PERS_ORG_LOCAL_APP_WT_PATH PERS_ORG_ROOT_PATH PERS_ORG_WT_FOLDER_NAME_
+#define PERS_ORG_LOCAL_APP_WT_PATH_ PERS_ORG_LOCAL_APP_WT_PATH"/"
+
+/** cache root path shared: /Data/mnt-c/shared */
+#define PERS_ORG_SHARED_CACHE_PATH PERS_ORG_ROOT_PATH PERS_ORG_CACHE_FOLDER_NAME_ PERS_ORG_SHARED_FOLDER_NAME_
+#define PERS_ORG_SHARED_CACHE_PATH_ PERS_ORG_SHARED_CACHE_PATH"/"
+/** wt root path shared: /Data/mnt-wt/shared */
+#define PERS_ORG_SHARED_WT_PATH PERS_ORG_ROOT_PATH PERS_ORG_WT_FOLDER_NAME_ PERS_ORG_SHARED_FOLDER_NAME_
+#define PERS_ORG_SHARED_WT_PATH_ PERS_ORG_SHARED_WT_PATH"/"
+
+/** cache root path shared group: /Data/mnt-c/shared/group */
+#define PERS_ORG_SHARED_GROUP_CACHE_PATH PERS_ORG_SHARED_CACHE_PATH PERS_ORG_GROUP_FOLDER_NAME_
+#define PERS_ORG_SHARED_GROUP_CACHE_PATH_ PERS_ORG_SHARED_GROUP_CACHE_PATH"/"
+/** wt root path application: /Data/mnt-wt/shared/group */
+#define PERS_ORG_SHARED_GROUP_WT_PATH PERS_ORG_SHARED_WT_PATH PERS_ORG_GROUP_FOLDER_NAME_
+#define PERS_ORG_SHARED_GROUP_WT_PATH_ PERS_ORG_SHARED_GROUP_WT_PATH"/"
+
+/** cache root path shared public: /Data/mnt-c/shared/public */
+#define PERS_ORG_SHARED_PUBLIC_CACHE_PATH PERS_ORG_SHARED_CACHE_PATH PERS_ORG_PUBLIC_FOLDER_NAME_
+#define PERS_ORG_SHARED_PUBLIC_CACHE_PATH_ PERS_ORG_SHARED_PUBLIC_CACHE_PATH"/"
+/** wt root path application: /Data/mnt-wt/shared/public */
+#define PERS_ORG_SHARED_PUBLIC_WT_PATH PERS_ORG_SHARED_WT_PATH PERS_ORG_PUBLIC_FOLDER_NAME_
+#define PERS_ORG_SHARED_PUBLIC_WT_PATH_ PERS_ORG_SHARED_PUBLIC_WT_PATH"/"
+
+/** path prefix for local cached database: /Data/mnt-c/\<appId\>/\<database_name\> */
+#define PERS_ORG_LOCAL_CACHE_PATH_FORMAT PERS_ORG_LOCAL_APP_CACHE_PATH"/%s%s"
+extern const char* gLocalCachePath; /**< PERS_ORG_LOCAL_CACHE_PATH_FORMAT */
+
+/** path prefix for local write through database /Data/mnt-wt/\<appId\>/\<database_name\> */
+#define PERS_ORG_LOCAL_WT_PATH_FORMAT PERS_ORG_LOCAL_APP_WT_PATH "/%s%s"
+extern const char* gLocalWtPath; /**< PERS_ORG_LOCAL_WT_PATH_FORMAT */
+
+/** path prefix for shared cached database: /Data/mnt-c/shared/group/ */
+extern const char* gSharedCachePathRoot; /**< PERS_ORG_SHARED_GROUP_CACHE_PATH_ */
+
+/** path format for shared cached database: /Data/mnt-c/shared/group/\<group_no\>/\<database_name\> */
+#define PERS_ORG_SHARED_CACHE_PATH_FORMAT PERS_ORG_SHARED_GROUP_CACHE_PATH_"%x%s"
+extern const char* gSharedCachePath; /**< PERS_ORG_SHARED_CACHE_PATH_FORMAT */
+
+/** path prefix for shared cached database: /Data/mnt-c/shared/group/\<group_no\>/\<database_name\> */
+#define PERS_ORG_SHARED_CACHE_PATH_STRING_FORMAT PERS_ORG_SHARED_GROUP_CACHE_PATH_"%s%s"
+extern const char* gSharedCachePathString; /**< PERS_ORG_SHARED_CACHE_PATH_STRING_FORMAT */
+
+/** path prefix for shared write through database: /Data/mnt-wt/shared/group/ */
+extern const char* gSharedWtPathRoot; /**< PERS_ORG_SHARED_GROUP_WT_PATH_ */
+
+/** path prefix for shared write through database: /Data/mnt_wt/Shared/Group/\<group_no\>/\<database_name\> */
+#define PERS_ORG_SHARED_WT_PATH_FORMAT PERS_ORG_SHARED_GROUP_WT_PATH_"%x%s"
+extern const char* gSharedWtPath ; /**< PERS_ORG_SHARED_WT_PATH_FORMAT */
+
+/** path prefix for shared write through database: /Data/mnt-wt/shared/group/\<group_no\>/\<database_name\> */
+#define PERS_ORG_SHARED_WT_PATH_STRING_FORMAT PERS_ORG_SHARED_GROUP_WT_PATH_"%s%s"
+extern const char* gSharedWtPathString; /**< PERS_ORG_SHARED_WT_PATH_STRING_FORMAT */
+
+/** path prefix for shared public cached database: /Data/mnt-c/shared/public/\<database_name\> */
+#define PERS_ORG_SHARED_PUBLIC_CACHE_PATH_FORMAT PERS_ORG_SHARED_PUBLIC_CACHE_PATH"%s"
+extern const char* gSharedPublicCachePath; /**< PERS_ORG_SHARED_PUBLIC_CACHE_PATH_FORMAT */
+
+/** path prefix for shared public write through database: /Data/mnt-wt/shared/public/\<database_name\> */
+#define PERS_ORG_SHARED_PUBLIC_WT_PATH_FORMAT PERS_ORG_SHARED_PUBLIC_WT_PATH"%s"
+extern const char* gSharedPublicWtPath; /**< PERS_ORG_SHARED_PUBLIC_WT_PATH_FORMAT */
+
+/** \} */
+
+
+
+/** \defgroup PERS_ORG_LINKS_NAMES Links' names
+ * \{
+ */
+
+/** symlinks to shared group folder have the format "shared_group_XX", e.g. "shared_group_0A" */
+#define PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX "shared_group_"
+
+/** symlinks to shared public folder */
+#define PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME "shared_public"
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif /** extern "C" { */
+
+/** \} */ /** End of PERS_COM_DATA_ORG */
+#endif /** OSS_PERSISTENCE_COMMON_DATA_ORGANIZATION_H */
diff --git a/inc/protected/persComDbAccess.h b/inc/protected/persComDbAccess.h
new file mode 100644
index 0000000..0a169fd
--- /dev/null
+++ b/inc/protected/persComDbAccess.h
@@ -0,0 +1,154 @@
+#ifndef OSS_PERSISTENCE_COMMON_DB_ACCESS_H
+#define OSS_PERSISTENCE_COMMON_DB_ACCESS_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Interface: protected - Access to local and shared DBs
+*
+* For additional details see
+* https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.01.23 uidl9757 4.0.0.0 CSP_WZ#2798: Change PERS_DB_MAX_SIZE_KEY_DATA to 16KB
+* 2013.01.23 uidl9757 3.0.0.0 CSP_WZ#2060: CoC_SSW:Persistence: common interface to be used by both PCL and PAS
+*
+**********************************************************************************************************************/
+
+/** \defgroup PERS_COM_DB_ACCESS Database access API
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* #ifdef __cplusplus */
+
+/** \defgroup PERS_DB_ACCESS_IF_VERSION Interface version
+ * \{
+ */
+#define PERS_COM_DB_ACCESS_INTERFACE_VERSION (0x04000000U)
+/** \} */
+
+
+
+/** \defgroup PERS_DB_ACCESS_CONFIG Database configurations
+ * \{
+ */
+/* maximum data size for a key type resourceID */
+#define PERS_DB_MAX_LENGTH_KEY_NAME 128 /**< Max. length of the key identifier */
+#define PERS_DB_MAX_SIZE_KEY_DATA 16384 /**< Max. size of the key entry (slot definition) */
+/** \} */
+
+
+/** \defgroup PERS_DB_ACCESS_FUNCTIONS Functions
+ * \{
+ */
+
+
+/**
+ * \brief Obtain a handler to DB indicated by dbPathname
+ * \note : DB is created if it does not exist and (bForceCreationIfNotPresent != 0)
+ *
+ * \param dbPathname [in] absolute path to database (length limited to \ref PERS_ORG_MAX_LENGTH_PATH_FILENAME)
+ * \param bForceCreationIfNotPresent [in] if !=0x0, the database is created if it does not exist
+ *
+ * \return >= 0 for valid handler, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbOpen(char const * dbPathname, unsigned char bForceCreationIfNotPresent) ;
+
+/**
+ * \brief Close handler to DB
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbClose(signed int handlerDB) ;
+
+/**
+ * \brief write a key-value pair into local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ * \param data [in] buffer with key's data
+ * \param dataSize [in] size of key's data (max allowed \ref PERS_DB_MAX_SIZE_KEY_DATA)
+ *
+ * \return 0 for success, negative value otherwise (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbWriteKey(signed int handlerDB, char const * key, char const * data, signed int dataSize) ;
+
+
+/**
+ * \brief read a key's value from local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ * \param dataBuffer_out [out]buffer where to return the read data
+ * \param dataBufferSize [in] size of dataBuffer_out
+ *
+ * \return read size, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbReadKey(signed int handlerDB, char const * key, char* dataBuffer_out, signed int dataBufferSize) ;
+
+/**
+ * \brief read a key's value from local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ *
+ * \return key's size, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbGetKeySize(signed int handlerDB, char const * key) ;
+
+/**
+ * \brief delete key from local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ *
+ * \return 0 for success, negative value otherwise (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbDeleteKey(signed int handlerDB, char const * key) ;
+
+
+/**
+ * \brief Find the buffer's size needed to accomodate the list of keys' names in local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ *
+ * \return needed size, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbGetSizeKeysList(signed int handlerDB) ;
+
+
+/**
+ * \brief Obtain the list of the keys' names in local/shared database
+ * \note : keys in the list are separated by '\0'
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param listBuffer_out [out]buffer where to return the list of keys
+ * \param listBufferSize [in] size of listingBuffer_out
+ * \return >=0 for size of the list, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbGetKeysList(signed int handlerDB, char* listBuffer_out, signed int listBufferSize) ;
+
+/** \} */ /* End of PERS_DB_ACCESS_FUNCTIONS */
+
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" { */
+/** \} */ /* End of PERS_COM_DB_ACCESS */
+#endif /* OSS_PERSISTENCE_COMMON_DB_ACCESS_H */
+
+
+
+
diff --git a/inc/protected/persComErrors.h b/inc/protected/persComErrors.h
new file mode 100644
index 0000000..ca447bb
--- /dev/null
+++ b/inc/protected/persComErrors.h
@@ -0,0 +1,69 @@
+#ifndef OSS_PERSISTENCE_COMMON_ERROR_CODES_ACCESS_H
+#define OSS_PERSISTENCE_COMMON_ERROR_CODES_ACCESS_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Interface: protected - Error codes that can be returned by PersCommon's functions
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.10.24 uidu0250 3.0.1.0 CSP_WZ#6327: CoC_SSW:Persistence: add IPC specific error code
+* 2013.01.23 uidl9757 3.0.0.0 CSP_WZ#2060: CoC_SSW:Persistence: common interface to be used by both PCL and PAS
+*
+**********************************************************************************************************************/
+
+/** \defgroup PERS_COM_ERRORS Error Codes API
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* #ifdef __cplusplus */
+
+/** \defgroup PERS_COM_ERROR_CODES_IF_VERSION Interface version
+ * \{
+ */
+#define PERS_COM_ERROR_CODES_INTERFACE_VERSION (0x03000000U)
+/** \} */
+
+
+
+/** \defgroup PERS_COM_ERROR_CODES_DEFINES Error codes PERS_COM_ERR_
+ * \{
+ */
+/* Error code return by the SW Package, related to SW_PackageID. */
+#define PERS_COM_PACKAGEID 0x014 //!< Software package identifier, use for return value base
+#define PERS_COM_BASERETURN_CODE (PERS_COM_PACKAGEID << 16) //!< Basis of the return value containing SW PackageID
+
+#define PERS_COM_SUCCESS 0x00000000 //!< the function call succeded
+
+#define PERS_COM_ERROR_CODE (-(PERS_COM_BASERETURN_CODE)) //!< basis of the error (negative values)
+#define PERS_COM_ERR_INVALID_PARAM (PERS_COM_ERROR_CODE - 1) //!< An invalid param was passed
+#define PERS_COM_ERR_BUFFER_TOO_SMALL (PERS_COM_ERROR_CODE - 2) //!< The data found is too large to fit in the provided buffer
+#define PERS_COM_ERR_NOT_FOUND (PERS_COM_ERROR_CODE - 3) //!< Tried to access an unexistent key, database, file
+#define PERS_COM_ERR_SIZE_TOO_LARGE (PERS_COM_ERROR_CODE - 4) //!< Tried to write a too large data
+#define PERS_COM_ERR_OPERATION_NOT_SUPPORTED (PERS_COM_ERROR_CODE - 5) //!< Operation is not (yet) supported
+#define PERS_COM_ERR_MALLOC (PERS_COM_ERROR_CODE - 6) //!< Dynamic memory allocation failed
+#define PERS_COM_ERR_ACCESS_DENIED (PERS_COM_ERROR_CODE - 7) //!< Insufficient rights to perform opperation
+#define PERS_COM_ERR_OUT_OF_MEMORY (PERS_COM_ERROR_CODE - 8) //!< Not enough resources for an opperation
+
+/* IPC specific error codes */
+#define PERS_COM_IPC_ERR_PCL_NOT_AVAILABLE (PERS_COM_ERROR_CODE - 255) //!< PCL client not available (application was killed)
+/* end of IPC specific error codes */
+
+#define PERS_COM_FAILURE (PERS_COM_ERROR_CODE - 0xFFFF) //!< Generic error code - for situations not covered by the defined error codes
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" { */
+/** \} */ /* End of PERS_COM_ERRORS */
+#endif /* OSS_PERSISTENCE_COMMON_ERROR_CODES_ACCESS_H */
diff --git a/inc/protected/persComIpc.h b/inc/protected/persComIpc.h
new file mode 100644
index 0000000..d04bdb6
--- /dev/null
+++ b/inc/protected/persComIpc.h
@@ -0,0 +1,309 @@
+#ifndef OSS_PERSISTENCE_COMMON_IPC_H
+#define OSS_PERSISTENCE_COMMON_IPC_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2013 Continental Automotive Systems, Inc.
+*
+* Author: petrica.manoila@continental-corporation.com
+*
+* Interface: protected - IPC protocol for communication between PAS and PCL
+*
+* The file defines contains the defines according to
+* https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.02.26 uidu0250 1.0.0.0 CR CSP_WZ#2739
+*
+**********************************************************************************************************************/
+
+/** \defgroup PERS_COM_IPC IPC protocol API
+ * \{
+ * Persistence Common library IPC component provides centralized access to the communication between
+ * PAS (Persistence Administration Service) and PCL (Persistence Client Library) trough C functions.
+ * This IPC protocol is based on the Genivi administration / DBUS interface specification.
+ * The interface is independent of the IPC stack, that can be specified as a symbol in the build process,
+ * and by default will use the GLib DBus binding.
+ *
+ * \image html PersCommonIPC.png "PersCommonIPC"
+ */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* #ifdef __cplusplus */
+
+/** \defgroup PERS_COM_IPC_IF_VERSION Interface version
+ * \{
+ */
+#define PERS_COM_IPC_INTERFACE_VERSION (0x01000000U)
+/** \} */
+
+/** \defgroup PERS_COM_IPC_DEFINES_MODE Persistence mode flags
+ * Persistence mode flags
+ * \{
+ */
+#define PERSISTENCE_MODE_LOCK (0x0001U) /**< Request to lock access to device */
+#define PERSISTENCE_MODE_SYNC (0x0002U) /**< Request to synchronize the cache */
+#define PERSISTENCE_MODE_UNLOCK (0x0004U) /**< Request to unlock access to device */
+/** \} */ /* End of PERS_COM_IPC_DEFINES */
+
+/** \defgroup PERS_COM_IPC_DEFINES_STATUS Persistence status flags
+ * Persistence status flags
+ * \{
+ */
+#define PERSISTENCE_STATUS_LOCKED (0x0001U) /**< Access to device locked status flag */
+#define PERSISTENCE_STATUS_ERROR (0x8000U) /**< Error present status flag */
+/** \} */ /* End of PERS_COM_IPC_DEFINES_STATUS */
+
+
+/** \defgroup PERS_COM_IPC_DEFINES_ERROR Persistence status error codes
+ * Persistence status error codes
+ * \{
+ */
+#define PERSISTENCE_STATUS_ERROR_LOCK_FAILED (0x01U) /**< Lock request failed */
+#define PERSISTENCE_STATUS_ERROR_SYNC_FAILED (0x02U) /**< Sync request failed */
+/** \} */ /* End of PERS_COM_IPC_DEFINES_ERROR */
+
+
+
+
+/*------------------------------------------------------------------------------------
+ * Interface to be used by PAS (Persistence Administration Service)
+ *------------------------------------------------------------------------------------
+ */
+
+/** \defgroup PERS_COM_IPC_PAS API for Persistence Administrator
+ * \{
+ * Definition of the callbacks, structures and functions used by the Persistence Administration Service
+ */
+
+/** \defgroup PERS_COM_IPC_PAS_CALLBACKS Callbacks
+ * \{
+ * The callbacks specified here should be implemented by the Persistence Administration Service and
+ * supplied to the \ref persIpcInitPAS call trough the \ref PersAdminPASInitInfo_s
+ * initialization structure.
+ */
+
+/* Register callback signature (to be implemented by PAS) */
+/**
+ * \brief PCL client registration callback
+ * \note Should be implemented by PAS (Persistence Administration Service) and used to populate the
+ * \ref PersAdminPASInitInfo_s structure passed to \ref persIpcInitPAS.
+ * Called when a client registers to PAS.
+ * The values of the input parameters (flags, timeout) are the values that the PCL client specified when
+ * calling \ref persIpcRegisterToPAS.
+ *
+ * \param clientID [in] unique identifier assigned to the registered client
+ * \param flags [in] flags specifying the notifications to register for (bitfield using any of the flags : ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ * \param timeout [in] maximum time needed to process any supported request (in milliseconds)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+typedef int (*persIpcRegisterToPAS_f)( int clientID,
+ unsigned int flags,
+ unsigned int timeout);
+
+/* Un-register callback signature (to be implemented by PAS) */
+/**
+ * \brief PCL client un-registration callback
+ * \note Should be implemented by PAS (Persistence Administration Service) and used to populate the
+ * \ref PersAdminPASInitInfo_s structure passed to \ref persIpcInitPAS.
+ * Called when a client un-registers from PAS.
+ * The values of the input parameter flags is the value that the PCL client specified when
+ * calling \ref persIpcUnRegisterFromPAS.
+ *
+ * \param clientID [in] unique identifier assigned to the registered client
+ * \param flags [in] flags specifying the notifications to un-register from (bitfield using any of the flags : ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+typedef int (*persIpcUnRegisterFromPAS_f)( int clientID,
+ unsigned int flags);
+
+/* PersAdminRequestCompleted callback signature (to be implemented by PAS) */
+/**
+ * \brief PCL request confirmation callback
+ * \note Should be implemented by PAS (Persistence Administration Service) and used to populate the
+ * \ref PersAdminPASInitInfo_s structure passed to \ref persIpcInitPAS.
+ * Called when a client confirms a request sent by PAS.
+ * The values of the input parameters (requestID, status) are the values that the PCL client specified when
+ * calling \ref persIpcSendConfirmationToPAS.
+ *
+ * \param clientID [in] unique identifier assigned to the registered client
+ * \param requestID [in] unique identifier of the request sent by PAS. Should have the same value
+ * as the parameter requestID specified by PAS when calling
+ \ref persIpcSendRequestToPCL
+ * \param status [in] the status of the request processed by PCL
+ * - In case of success: bitfield using any of the flags, depending on the request : ::PERSISTENCE_STATUS_LOCKED.
+ * - In case of error: the sum of ::PERSISTENCE_STATUS_ERROR and an error code \ref PERS_COM_IPC_DEFINES_ERROR is returned.
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+typedef int (*persIpcSendConfirmationToPAS_f)( int clientID,
+ int requestID,
+ unsigned int status);
+/** \} */ /* End of PERS_COM_IPC_PAS_CALLBACKS */
+
+/** \defgroup PERS_COM_IPC_PAS_STRUCTURES Structures
+ * \{
+ */
+/* PAS init struct */
+typedef struct PersIpcPASInitInfo_s_
+{
+ persIpcRegisterToPAS_f pRegCB; /* callback for RegisterPersAdminNotification */
+ persIpcUnRegisterFromPAS_f pUnRegCB; /* callback for UnRegisterPersAdminNotification */
+ persIpcSendConfirmationToPAS_f pReqCompleteCB; /* callback for PersistenceAdminRequestCompleted*/
+}PersAdminPASInitInfo_s;
+/** \} */ /* End of PERS_COM_IPC_PAS_STRUCTURES */
+
+
+/** \defgroup PERS_COM_IPC_PAS_FUNCTIONS Functions
+ * \{
+ */
+
+/**
+ * \brief Initialize PAS IPC component
+ * \note An additional thread is created for communication purposes.
+ * Initialize members of the supplied PersAdminPASInitInfo_s structure before calling this function.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPASInitInfo_s structure containing
+ * the supported callbacks
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcInitPAS( PersAdminPASInitInfo_s * pInitInfo);
+
+
+/**
+ * \brief Sends a request to the PCL client specified by clientID.
+ * \note Each requestID should be unique.
+ *
+ * \param clientID [in] the client ID returned by the supplied pRegCB callback
+ * \param requestID [in] a unique identifier generated for every request
+ * \param request [in] the request to be sent (bitfield using a valid
+ * combination of any of the following flags :
+ * ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcSendRequestToPCL( int clientID,
+ int requestID,
+ unsigned int request);
+
+/** \} */ /* End of PERS_COM_IPC_PAS_FUNCTIONS */
+
+/** \} */ /* End of PERS_COM_IPC_PAS */
+
+
+/*------------------------------------------------------------------------------------
+ * Interface to be used by PCL (Persistence Client Library)
+ *------------------------------------------------------------------------------------
+ */
+
+/** \defgroup PERS_COM_IPC_PCL API for Persistence Client Library
+ * \{
+ * Definition of the callbacks, structures and functions used by the Persistence Client Library
+ */
+
+/** \defgroup PERS_COM_IPC_PCL_CALLBACKS Callbacks
+ * \{
+ * The callbacks specified here should be implemented by the Persistence Client Library and
+ * supplied to the \ref persIpcRegisterToPAS call trough the \ref PersAdminPCLInitInfo_s
+ * initialization structure.
+ */
+
+/* PersAdminRequest callback signature (to be implemented by PCL) */
+/**
+ * \brief PAS request callback
+ * \note Should be implemented by PCL (Persistence Client Library) and used to populate the
+ * \ref PersAdminPCLInitInfo_s structure passed to \ref persIpcRegisterToPAS.
+ * Called when PAS performs a request by calling \ref persIpcSendRequestToPCL.
+ * The values of the input parameters (requestID, request) are the values that PAS specified when
+ * calling \ref persIpcSendRequestToPCL.
+ *
+ * \param requestID [in] a unique identifier generated for every request
+ * \param request [in] the request received (bitfield using a valid combination of
+ * any of the following flags :
+ ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+typedef int (*persIpcSendRequestToPCL_f)( int requestID,
+ unsigned int request);
+/** \} */ /* End of PERS_COM_IPC_PCL_CALLBACKS */
+
+
+/** \defgroup PERS_COM_IPC_PCL_STRUCTURES Structures
+ * \{
+ */
+/* PCL init struct */
+typedef struct PersAdminPCLInitInfo_s_
+{
+ persIpcSendRequestToPCL_f pReqCB; /* callback for PersistenceAdminRequest */
+}PersAdminPCLInitInfo_s;
+/** \} */ /* End of PERS_COM_IPC_PCL_STRUCTURES */
+
+
+/** \defgroup PERS_COM_IPC_PCL_FUNCTIONS Functions
+ * \{
+ */
+
+/**
+ * \brief Register PCL client application to PAS
+ * \note Registers the PCL (Persistence Client Library) client application to PAS (Persistence Administration Service)
+ * in order to receive persistence mode change notifications (i.e. the memory access blocked/un-blocked).
+ * The initialization is performed based on the supplied pInitInfo parameter.
+ * Call \ref persIpcUnRegisterFromPAS to unregister from PAS when closing the application.
+ * Initialize members of the supplied PersAdminPCLInitInfo_s structure before calling this function.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPCLInitInfo_s structure containing
+ * the supported callbacks
+ * \param flags [in] bitfield using a valid combination of any of the following flags : ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK
+ * \param timeout [in] maximum time needed to process any supported request (in milliseconds)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcRegisterToPAS(PersAdminPCLInitInfo_s * pInitInfo,
+ unsigned int flags,
+ unsigned int timeout);
+
+/**
+ * \brief Un-Register PCL client application from PAS
+ * \note Un-registers the PCL (Persistence Client Library) client application from PAS (Persistence Administration Service) for
+ * the notifications specified trough flags.
+ * The PCL client application will no longer receive from PAS the notifications specified in flags.
+ *
+ * \param flags [in] bitfield using a valid combination of any of the following flags : ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcUnRegisterFromPAS( unsigned int flags );
+
+/**
+ * \brief Send 'request processed' confirmation to PAS.
+ * \note Sends confirmation to PAS that the request specified by requestID has been processed.
+ * The status parameter should reflect this request and could also return an error.
+ *
+ * \param requestID [in] the ID of the processed request
+ * \param status [in] the status of the request processed by PCL
+ * - In case of success: bitfield using any of the following flags, depending on the request : ::PERSISTENCE_STATUS_LOCKED.
+ * - In case of error: the sum of ::PERSISTENCE_STATUS_ERROR and an error code \ref PERS_COM_IPC_DEFINES_ERROR is returned.
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcSendConfirmationToPAS( int requestID,
+ unsigned int status);
+
+/** \} */ /* End of PERS_COM_IPC_PCL_FUNCTIONS */
+
+/** \} */ /* End of PERS_COM_IPC_PCL */
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" { */
+/** \} */ /* End of PERS_COM_IPC */
+#endif /* OSS_PERSISTENCE_COMMON_IPC_H */
diff --git a/inc/protected/persComRct.h b/inc/protected/persComRct.h
new file mode 100644
index 0000000..79e8fa4
--- /dev/null
+++ b/inc/protected/persComRct.h
@@ -0,0 +1,226 @@
+#ifndef OSS_PERSISTENCE_RESOURCE_CONFIG_TABLE_H
+#define OSS_PERSISTENCE_RESOURCE_CONFIG_TABLE_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Interface: protected - Access to resource configuration table
+*
+* For additional details see
+* https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.04.02 uidl9757 5.0.0.0 CSP_WZ#3321: Update of PersistenceConfigurationKey_s.permission
+* 2013.03.21 uidl9757 4.0.0.0 CSP_WZ#2798: Update of PersistenceConfigurationKey_s
+* 2013.01.23 uidl9757 3.0.0.0 CSP_WZ#2060: CoC_SSW:Persistence: common interface to be used by both PCL and PAS
+*
+**********************************************************************************************************************/
+
+/**
+ * \brief For details see https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+ */
+
+
+/** \defgroup PERS_COM_RCT Resource Config Table API
+ * \{
+ */
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* #ifdef __cplusplus */
+
+/** \defgroup PERS_RCT_IF_VERSION Interface version
+ * \{
+ */
+#define PERS_COM_RESOURCE_CONFIG_TABLE_INTERFACE_VERSION (0x05000000U)
+/** \} */ /* end of PERS_RCT_IF_VERSION */
+
+
+
+/** \defgroup PERS_RCT_CONFIG Configuration parameters
+ * see the defines below for their meaning
+ * \{
+ */
+
+#define PERS_RCT_MAX_LENGTH_RESOURCE_ID 64 /**< Max. length of the resource identifier */
+#define PERS_RCT_MAX_LENGTH_RESPONSIBLE 64 /**< Max. length of the responsible application */
+#define PERS_RCT_MAX_LENGTH_CUSTOM_NAME 64 /**< Max. length of the customer plugin */
+#define PERS_RCT_MAX_LENGTH_CUSTOM_ID 64 /**< Max. length of the custom ID */
+
+/** \} */ /* End of PERS_RCT_CONFIG */
+
+
+
+/** \defgroup PERS_RCT_ENUM Enumerators managed in the RCT
+ * \{
+ */
+/** data policies */
+typedef enum PersistencePolicy_e_
+{
+ PersistencePolicy_wc = 0, /**< the data is managed write cached */
+ PersistencePolicy_wt, /**< the data is managed write through */
+ PersistencePolicy_na, /**< the data is not applicable */
+
+ /** insert new entries here ... */
+ PersistencePolicy_LastEntry /**< last entry */
+
+} PersistencePolicy_e;
+
+
+/** storages to manage the data */
+typedef enum PersistenceStorage_e_
+{
+ PersistenceStorage_local = 0, /**< the data is managed local */
+ PersistenceStorage_shared, /**< the data is managed shared */
+ PersistenceStorage_custom, /**< the data is managed over custom client implementation */
+
+ /** insert new entries here ... */
+ PersistenceStorage_LastEntry /**< last entry */
+
+} PersistenceStorage_e;
+
+/** specifies the type of the resource */
+typedef enum PersistenceResourceType_e_
+{
+ PersistenceResourceType_key = 0, /**< key type resource */
+ PersistenceResourceType_file, /**< file type resourced */
+
+ /** insert new entries here ... */
+ PersistenceResourceType_LastEntry /**< last entry */
+
+} PersistenceResourceType_e;
+
+/** specifies the permission on resource's data */
+typedef enum PersistencePermission_e_
+{
+ PersistencePermission_ReadWrite = 0, /**< random access to data is allowed */
+ PersistencePermission_ReadOnly, /**< only read access to data is allowed */
+ PersistencePermission_WriteOnly, /**< only write access to data is allowed */
+
+ /** insert new entries here ... */
+ PersistencePermission_LastEntry /**< last entry */
+} PersistencePermission_e;
+
+/** \} */ /* End of PERS_RCT_ENUM */
+
+
+
+/** \defgroup PERS_RCT_STRUCT Structures managed in the RCT
+ * \{
+ */
+/** resource configuration */
+typedef struct PersistenceConfigurationKey_s_
+{
+ PersistencePolicy_e policy; /**< policy */
+ PersistenceStorage_e storage; /**< definition of storage to use */
+ PersistenceResourceType_e type; /**< type of the resource */
+ PersistencePermission_e permission; /**< access right */
+ unsigned int max_size; /**< max size expected for the key */
+ char reponsible[PERS_RCT_MAX_LENGTH_RESPONSIBLE]; /**< name of responsible application */
+ char custom_name[PERS_RCT_MAX_LENGTH_CUSTOM_NAME]; /**< name of the customer plugin */
+ char customID[PERS_RCT_MAX_LENGTH_CUSTOM_ID]; /**< internal ID for the custom type resource */
+} PersistenceConfigurationKey_s;
+/** \} */ /* End of PERS_RCT_STRUCT */
+
+
+
+/** \defgroup PERS_RCT_FUNCTIONS Functions
+ * \{
+ */
+
+
+/**
+ * \brief Obtain a handler to RCT indicated by rctPathname
+ * \note : RCT is created if it does not exist and (bForceCreationIfNotPresent != 0)
+ *
+ * \param rctPathname [in] absolute path to RCT (length limited to \ref PERS_ORG_MAX_LENGTH_PATH_FILENAME)
+ * \param bForceCreationIfNotPresent [in] if !=0x0, the RCT is created if it does not exist
+ *
+ * \return >= 0 for valid handler, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctOpen(char const * rctPathname, unsigned char bForceCreationIfNotPresent) ;
+
+/**
+ * \brief Close handler to RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctClose(signed int handlerRCT) ;
+
+/**
+ * \brief write a resourceID-value pair into RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param resourceID [in] resource's identifier (length limited to \ref PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ * \param psConfig [in] configuration for resourceID
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctWrite(signed int handlerRCT, char const * resourceID, PersistenceConfigurationKey_s const * psConfig) ;
+
+
+/**
+ * \brief read a resourceID's configuration from RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param resourceID [in] resource's identifier (length limited to \ref PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ * \param psConfig_out [out]where to return the configuration for resourceID
+ *
+ * \return read size [byte], or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctRead(signed int handlerRCT, char const * resourceID, PersistenceConfigurationKey_s const * psConfig_out) ;
+
+
+/**
+ * \brief delete a resourceID's configuration from RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param resourceID [in] resource's identifier (length limited to \ref PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ *
+ * \return 0 for success, or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctDelete(signed int handlerRCT, char const * resourceID) ;
+
+
+/**
+ * \brief Find the buffer's size needed to accomodate the listing of resourceIDs in RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ *
+ * \return needed size [byte], or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctGetSizeResourcesList(signed int handlerRCT) ;
+
+
+/**
+ * \brief Get the list of the resourceIDs in RCT
+ * \note : resourceIDs in the list are separated by '\0'
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param listBuffer_out [out]buffer where to return the list of resourceIDs
+ * \param listBufferSize [in] size of listBuffer_out
+ *
+ * \return list size [byte], or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctGetResourcesList(signed int handlerRCT, char* listBuffer_out, signed int listBufferSize) ;
+
+
+/** \} */ /* End of PERS_RCT_FUNCTIONS */
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" { */
+
+/** \} */ /* End of PERS_COM_RCT */
+#endif /* OSS_PERSISTENCE_DATA_ORGANIZATION_H */
diff --git a/inc/protected/persComTypes.h b/inc/protected/persComTypes.h
new file mode 100644
index 0000000..4fc0ff7
--- /dev/null
+++ b/inc/protected/persComTypes.h
@@ -0,0 +1,213 @@
+#ifndef PERS_COM_TYPES_H
+#define PERS_COM_TYPES_H
+
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Interface: protected - Type and constant definitions.
+*
+* For additional details see
+* https://collab.genivi.org/wiki/display/genivi/SysInfraEGPersistenceConceptInterface
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.02.05 uidl9757 1.0.0.0 CSP_WZ#TODO: CoC_SSW:Persistence: interface that defines type and constants
+*
+**********************************************************************************************************************/
+
+#include <stdbool.h>
+
+#ifndef char_t
+typedef char char_t ;
+#endif
+
+#ifndef NIL
+/**
+ * \brief Definition of the NIL value to be used.
+ */
+#define NIL (0)
+#endif /* #ifndef NIL */
+
+#ifndef NULL
+/**
+ * \brief Definition of NULL to be the same as NIL.
+ * \note
+ * It is not allowed to use NULL furthermore, use NIL instead. NULL
+ * is defined for legacy code only.
+ */
+#define NULL NIL
+#endif /* #ifndef NULL */
+
+
+
+
+/**
+ * \brief Definition to make boolean type common for C and C++
+ */
+typedef unsigned char bool_t;
+
+/**
+ * \brief Definition of false for boolean type in C.
+ */
+#ifndef false
+#define false ((bool_t)0)
+#endif
+
+/**
+ * \brief Definition of true for boolean type in C.
+ */
+#ifndef true
+#define true ((bool_t)1)
+#endif
+
+
+#include <linux/types.h> /* from within kernel source-tree ! */
+
+typedef __s8 INT8;
+typedef __s16 INT16;
+typedef __s32 INT32;
+typedef __s64 INT64;
+
+typedef __u8 uint8_t;
+typedef __u16 uint16_t;
+typedef __u32 uint32_t;
+typedef __u64 uint64_t;
+
+/**
+ * \brief 8 bit signed
+ */
+typedef INT8 sint8_t;
+
+/**
+ * \brief 16 bit signed
+ */
+typedef INT16 sint16_t;
+
+/**
+ * \brief 32 bit signed
+ */
+typedef INT32 sint32_t;
+
+/**
+ * \brief 64 bit signed
+ */
+typedef INT64 sint64_t;
+
+
+/**
+ * \brief Storage for unsigned characters (8 bit).
+ */
+typedef unsigned char uc8_t;
+/**
+ * \brief Pointer to storage for unsigned characters (8 bit).
+ */
+typedef uc8_t * puc8_t;
+
+/**
+ * \brief Storage for signed characters (8 bit).
+ */
+typedef signed char sc8_t;
+/**
+ * \brief Pointer to storage for signed characters (8 bit).
+ */
+typedef sc8_t * psc8_t;
+
+/**
+ * \brief Definition of a single string element.
+ */
+typedef char str_t;
+/**
+ * \brief Pointer to string (to differentiate between characters and strings).
+ */
+typedef str_t * pstr_t;
+/**
+ * \brief Pointer to constant string.
+ */
+typedef const str_t * pconststr_t;
+/**
+ * \brief Constant pointer to string.
+ */
+typedef str_t *const constpstr_t;
+/**
+ * \brief Constant pointer to constant string.
+ */
+typedef const str_t *const constpconststr_t;
+
+/**
+ * \brief Storage for wide characters (16 bit) to support Unicode.
+ */
+typedef unsigned short uc16_t;
+/**
+ * \brief Pointer to storage for wide characters (16 bit) to support Unicode.
+ */
+typedef uc16_t * puc16_t;
+
+/**
+ * \brief Pointer to wide string (to differentiate between wide characters
+ * and wide strings).
+ */
+typedef puc16_t pwstr_t;
+/**
+ * \brief Pointer to constant wide string.
+ */
+typedef const uc16_t * pconstwstr_t;
+/**
+ * \brief Constant pointer to wide string.
+ */
+typedef uc16_t *const constpwstr_t;
+/**
+ * \brief Constant pointer to constant wide string.
+ */
+typedef const uc16_t *const constpconstwstr_t;
+
+/**
+ * \brief Pointer to UNSIGNED-8-Bit
+ */
+typedef uint8_t* puint8_t;
+/**
+ * \brief Pointer to SIGNED-8-Bit
+ */
+typedef sint8_t* psint8_t;
+
+/**
+ * \brief Pointer to UNSIGNED-16-Bit
+ */
+typedef uint16_t* puint16_t;
+/**
+ * \brief Pointer to SIGNED-16-Bit
+ */
+typedef sint16_t* psint16_t;
+
+/**
+ * \brief Pointer to UNSIGNED-32-Bit
+ */
+typedef uint32_t* puint32_t;
+/**
+ * \brief Pointer to SIGNED-32-Bit
+ */
+typedef sint32_t* psint32_t;
+
+/**
+ * \brief Pointer to UNSIGNED-64-Bit
+ */
+typedef uint64_t* puint64_t;
+/**
+ * \brief Pointer to SIGNED-64-Bit
+ */
+typedef sint64_t* psint64_t;
+
+
+typedef unsigned int uint_t;
+
+
+typedef signed int sint_t;
+
+
+#endif /* #ifndef PERS_COM_TYPES_H */
+
diff --git a/pkgconfig/libperscommon.pc.in b/pkgconfig/libperscommon.pc.in
new file mode 100644
index 0000000..907eb3e
--- /dev/null
+++ b/pkgconfig/libperscommon.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libperscommon
+Description: library that specifies the organization of Genivi's persistence data and provides access to the resource configuration table and to the local and shared data bases
+Version: @VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -lpers_common
+Libs.private: @LIBS@
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c8bf708
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,70 @@
+#######################################################################################################################
+#
+# Copyright (C) 2012 Continental Automotive Systems, Inc.
+#
+# Author: Ana.Chisca@continental-corporation.com
+#
+# Makefile template for the persistence common library
+#
+# Process this file with automake to produce a Makefile.in.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#######################################################################################################################
+
+ACLOCAL_AMFLAGS=-I m4
+
+lib_LTLIBRARIES = libpers_common.la
+
+include_HEADERS= \
+ $(top_srcdir)/inc/protected/persComTypes.h \
+ $(top_srcdir)/inc/protected/persComDataOrg.h \
+ $(top_srcdir)/inc/protected/persComDbAccess.h \
+ $(top_srcdir)/inc/protected/persComErrors.h \
+ $(top_srcdir)/inc/protected/persComRct.h \
+ $(top_srcdir)/inc/protected/persComIpc.h
+
+libpers_common_la_CFLAGS = \
+ -I $(top_srcdir)/inc/private -I $(top_srcdir)/inc/protected -I $(top_srcdir)/generated\
+ $(DLT_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GOBJECT_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(ITZAM_CFLAGS)
+
+libpers_common_la_SOURCES = \
+ $(top_srcdir)/generated/PasClientNotificationGen.c\
+ $(top_srcdir)/src/pers_data_organization.c\
+ $(top_srcdir)/src/pers_local_shared_db_access.c\
+ $(top_srcdir)/src/pers_low_level_db_access.c\
+ $(top_srcdir)/src/pers_resource_config_table.c\
+ $(top_srcdir)/src/pers_ipc.c\
+ $(top_srcdir)/src/pers_ipc_dbus.c
+
+libpers_common_la_LDFLAGS = -version-info $(GENERIC_LIBRARY_VERSION)
+
+libpers_common_la_LIBADD = \
+ $(DLT_LIBS) \
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ $(GLIB_LIBS) \
+ $(DBUS_LIBS) \
+ $(GOBJECT_LIBS) \
+ $(ITZAM_LIBS)
+
+dbuspolicy_DATA = $(top_srcdir)/dbus_config/org.genivi.persistence.admin.conf
+
+# Export interface description of org.genivi.persistence.admin DBus interface
+dbusinterfaces_DATA = $(top_srcdir)/dbus_specifications/org.genivi.persistence.admin.xml
+
+EXTRA_DIST = $(dbuspolicy_DATA) \
+ $(dbusinterfaces_DATA)
+
+# pkgconfig
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(top_srcdir)/pkgconfig/libperscommon.pc
+
diff --git a/src/pers_data_organization.c b/src/pers_data_organization.c
new file mode 100644
index 0000000..4c798e1
--- /dev/null
+++ b/src/pers_data_organization.c
@@ -0,0 +1,101 @@
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Implementation of persComDataOrg.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2012.12.10 uild9757 CSP_WZ#2798: Added gLocalFactoryDefault and gLocalConfigurableDefault
+* 2012.12.10 uild9757 CSP_WZ#388: Initial creation
+*
+**********************************************************************************************************************/
+
+#include "persComDataOrg.h"
+
+
+
+/* resource configuration table name */
+const char* gResTableCfg = PERS_ORG_RCT_NAME_ ;
+
+/** local factory-default database */
+const char* gLocalFactoryDefault = PERS_ORG_LOCAL_FACTORY_DEFAULT_DB_NAME_ ;
+
+/** local configurable-default database */
+const char* gLocalConfigurableDefault = PERS_ORG_LOCAL_CONFIGURABLE_DEFAULT_DB_NAME_ ;
+
+/* shared cached default database */
+const char* gSharedCachedDefault = PERS_ORG_SHARED_CACHE_DEFAULT_DB_NAME_ ;
+
+/* shared cached database */
+const char* gSharedCached = PERS_ORG_SHARED_CACHE_DB_NAME_ ;
+
+/* shared write through default database */
+const char* gSharedWtDefault = PERS_ORG_SHARED_WT_DEFAULT_DB_NAME_ ;
+
+/* shared write through database */
+const char* gSharedWt = PERS_ORG_SHARED_WT_DB_NAME_ ;
+
+/* local cached default database */
+const char* gLocalCachedDefault = PERS_ORG_LOCAL_CACHE_DEFAULT_DB_NAME_ ;
+
+/* local cached database */
+const char* gLocalCached = PERS_ORG_LOCAL_CACHE_DB_NAME_ ;
+
+/* local write through default database */
+const char* gLocalWtDefault = PERS_ORG_LOCAL_WT_DEFAULT_DB_NAME_ ;
+
+/* local write through default database */
+const char* gLocalWt = PERS_ORG_LOCAL_WT_DB_NAME_ ;
+
+/* directory structure node name definition */
+const char* gNode = PERS_ORG_NODE_FOLDER_NAME_ ;
+
+/* directory structure user name definition */
+const char* gUser = PERS_ORG_USER_FOLDER_NAME_ ;
+
+/* directory structure seat name definition */
+const char* gSeat = PERS_ORG_SEAT_FOLDER_NAME_ ;
+
+/* directory structure shared name definition */
+const char* gSharedPathName = PERS_ORG_SHARED_FOLDER_NAME ;
+
+/* path prefix for all data */
+const char* gRootPath = PERS_ORG_ROOT_PATH ;
+
+/* path prefix for local cached database: /Data/mnt-c/<appId>/<database_name> */
+const char* gLocalCachePath = PERS_ORG_LOCAL_CACHE_PATH_FORMAT ;
+
+/* path prefix for local write through database /Data/mnt-wt/<appId>/<database_name> */
+const char* gLocalWtPath = PERS_ORG_LOCAL_WT_PATH_FORMAT ;
+
+/* path prefix for shared cached database: /Data/mnt-c/shared/group/ */
+const char* gSharedCachePathRoot = PERS_ORG_SHARED_GROUP_CACHE_PATH_ ;
+
+/* path format for shared cached database: /Data/mnt-c/shared/group/<group_no>/<database_name> */
+const char* gSharedCachePath = PERS_ORG_SHARED_CACHE_PATH_FORMAT ;
+
+/* path prefix for shared cached database: /Data/mnt-c/shared/group/<group_no>/<database_name> */
+const char* gSharedCachePathString = PERS_ORG_SHARED_CACHE_PATH_STRING_FORMAT ;
+
+/* path prefix for shared write through database: /Data/mnt-wt/shared/group/ */
+const char* gSharedWtPathRoot = PERS_ORG_SHARED_GROUP_WT_PATH_ ;
+
+/* path prefix for shared write through database: /Data/mnt_wt/shared/group/<group_no>/<database_name> */
+const char* gSharedWtPath = PERS_ORG_SHARED_WT_PATH_FORMAT ;
+
+/* path prefix for shared write through database: /Data/mnt-wt/shared/group/<group_no>/<database_name> */
+const char* gSharedWtPathString = PERS_ORG_SHARED_WT_PATH_STRING_FORMAT ;
+
+/* path prefix for shared public cached database: /Data/mnt-c/shared/public/<database_name> */
+const char* gSharedPublicCachePath = PERS_ORG_SHARED_PUBLIC_CACHE_PATH_FORMAT ;
+
+/* path prefix for shared public write through database: /Data/mnt-wt/shared/public/<database_name> */
+const char* gSharedPublicWtPath = PERS_ORG_SHARED_PUBLIC_WT_PATH_FORMAT ;
+
+
diff --git a/src/pers_ipc.c b/src/pers_ipc.c
new file mode 100644
index 0000000..9e33138
--- /dev/null
+++ b/src/pers_ipc.c
@@ -0,0 +1,316 @@
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Petrica.Manoila@continental-corporation.com
+*
+* Implementation of persComIpc.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.04.03 uidu0250 CSP_WZ#2739 : Initial creation
+*
+**********************************************************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <dlt.h>
+#include "persComErrors.h"
+#include "persComTypes.h"
+#include "persComIpc.h"
+#include "pers_ipc_dbus_if.h"
+
+
+/* ---------- local defines, macros, constants and type definitions ------------ */
+
+typedef enum persIpcChannel_e_
+{
+ persIpcChannelDBus_high = 0,
+ persIpcChannelDBus_low,
+ persIpcChannelSysSyncObj,
+ persIpcChannelLastEntry
+}persIpcChannel_e;
+
+
+#ifndef PERS_COM_IPC_PROTOCOL
+#define PERS_COM_IPC_PROTOCOL persIpcChannelDBus_high
+#endif //PERS_COM_IPC_PROTOCOL
+
+
+typedef sint_t (*persIpcInitPAS_handler_f)(PersAdminPASInitInfo_s *);
+typedef sint_t (*persIpcSendRequestToPCL_handler_f)(sint_t, sint_t, uint_t);
+typedef sint_t (*persIpcRegisterToPAS_handler_f)(PersAdminPCLInitInfo_s *, uint_t, uint_t);
+typedef sint_t (*persIpcUnRegisterFromPAS_handler_f)(uint_t);
+typedef sint_t (*persIpcSendConfirmationToPAS_handler_f)(sint_t, uint_t);
+
+
+/* ----------global variables. initialization of global contexts ------------ */
+
+DLT_DECLARE_CONTEXT(persComIpcDLTCtx);
+
+#define LT_HDR "COMMON_IPC >>"
+
+static bool_t g_bDltCtxInitialized = false; /* PersCommonIPC DLT context initialized */
+
+static bool_t g_bPersCommonIPCInitPAS = false; /* PersCommonIPC module initialized for PAS */
+static bool_t g_bPersCommonIPCInitPCL = false; /* PersCommonIPC module initialized for PCL */
+
+
+static persIpcInitPAS_handler_f persIpcInitPAS_handler[persIpcChannelLastEntry] =
+{
+ &persIpcInitPAS_DBus_high,
+ NIL,
+ NIL
+};
+
+static persIpcSendRequestToPCL_handler_f persIpcSendRequestToPCL_handler[persIpcChannelLastEntry] =
+{
+ &persIpcSendRequestToPCL_DBus_high,
+ NIL,
+ NIL
+};
+
+static persIpcRegisterToPAS_handler_f persIpcRegisterToPAS_handler[persIpcChannelLastEntry] =
+{
+ &persIpcRegisterToPAS_DBus_high,
+ NIL,
+ NIL
+};
+
+static persIpcUnRegisterFromPAS_handler_f persIpcUnRegisterFromPAS_handler[persIpcChannelLastEntry] =
+{
+ &persIpcUnRegisterFromPAS_DBus_high,
+ NIL,
+ NIL
+};
+
+static persIpcSendConfirmationToPAS_handler_f persIpcSendConfirmationToPAS_handler[persIpcChannelLastEntry] =
+{
+ &persIpcSendConfirmationToPAS_DBus_high,
+ NIL,
+ NIL
+};
+
+
+
+/**
+ * \brief Initialize PAS IPC component
+ * \note An additional thread is created for communication purposes.
+ * Initialize members of the supplied PersAdminPASInitInfo_s structure before calling this function.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPASInitInfo_s structure containing
+ * the supported callbacks
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcInitPAS( PersAdminPASInitInfo_s *pInitInfo)
+{
+ int retVal = PERS_COM_SUCCESS;
+
+ if(false == g_bDltCtxInitialized)
+ {
+ /* Initialize the logging interface */
+ DLT_REGISTER_CONTEXT(persComIpcDLTCtx, "PCOM", "PersistenceCommonIPC Context");
+ g_bDltCtxInitialized = true;
+ }
+
+ if(true == g_bPersCommonIPCInitPAS)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_WARN, DLT_STRING(LT_HDR),
+ DLT_STRING("PAS IPC protocol already initialized."));
+ return PERS_COM_SUCCESS;
+ }
+
+ if(NIL == pInitInfo)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in persIpcInitPAS call."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ if(NIL == persIpcInitPAS_handler[PERS_COM_IPC_PROTOCOL])
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Internal configuration error. No handler for persIpcInitPAS."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ retVal = persIpcInitPAS_handler[PERS_COM_IPC_PROTOCOL](pInitInfo);
+ if(PERS_COM_SUCCESS == retVal)
+ {
+ g_bPersCommonIPCInitPAS = true;
+ }
+
+ return retVal;
+}
+
+
+/**
+ * \brief Sends a request to the PCL client specified by clientID.
+ * \note Each requestID should be unique.
+ *
+ * \param clientID [in] the client ID returned by the supplied pRegCB callback
+ * \param requestID [in] a unique identifier generated for every request
+ * \param request [in] the request to be sent (bitfield using a valid
+ * combination of any of the following flags :
+ * ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcSendRequestToPCL( int clientID,
+ int requestID,
+ unsigned int request)
+{
+ if(false == g_bPersCommonIPCInitPAS)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("PAS IPC protocol not initialized."));
+ return PERS_COM_FAILURE;
+ }
+
+ if(NIL == persIpcSendRequestToPCL_handler[PERS_COM_IPC_PROTOCOL])
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Internal configuration error. No handler for persIpcSendRequestToPCL."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ return persIpcSendRequestToPCL_handler[PERS_COM_IPC_PROTOCOL]( clientID,
+ requestID,
+ request);
+}
+
+
+/**
+ * \brief Register PCL client application to PAS
+ * \note Registers the PCL (Persistence Client Library) client application to PAS (Persistence Administration Service)
+ * in order to receive persistence mode change notifications (i.e. the memory access blocked/un-blocked).
+ * The initialization is performed based on the supplied pInitInfo parameter.
+ * Call \ref persIpcUnRegisterFromPAS to unregister from PAS when closing the application.
+ * Initialize members of the supplied PersAdminPCLInitInfo_s structure before calling this function.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPCLInitInfo_s structure containing
+ * the supported callbacks
+ * \param flags [in] bitfield using a valid combination of any of the following flags : ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK
+ * \param timeout [in] maximum time needed to process any supported request (in milliseconds)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcRegisterToPAS(PersAdminPCLInitInfo_s * pInitInfo,
+ unsigned int flags,
+ unsigned int timeout)
+{
+ int retVal = PERS_COM_SUCCESS;
+
+ if(false == g_bDltCtxInitialized)
+ {
+ /* Initialize the logging interface */
+ DLT_REGISTER_CONTEXT(persComIpcDLTCtx, "PCOM", "PersistenceCommonIPC Context");
+ g_bDltCtxInitialized = true;
+ }
+
+ if(true == g_bPersCommonIPCInitPCL)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_WARN, DLT_STRING(LT_HDR),
+ DLT_STRING("PCL IPC protocol already initialized."));
+ return PERS_COM_SUCCESS;
+ }
+
+ if(NIL == pInitInfo)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in persIpcRegisterToPAS call."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ if(NIL == persIpcRegisterToPAS_handler[PERS_COM_IPC_PROTOCOL])
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Internal configuration error. No handler for persIpcRegisterToPAS."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ retVal = persIpcRegisterToPAS_handler[PERS_COM_IPC_PROTOCOL]( pInitInfo,
+ flags,
+ timeout);
+ if(PERS_COM_SUCCESS == retVal)
+ {
+ g_bPersCommonIPCInitPCL = true;
+ }
+
+ return retVal;
+}
+
+
+/**
+ * \brief Un-Register PCL client application from PAS
+ * \note Un-registers the PCL (Persistence Client Library) client application from PAS (Persistence Administration Service) for
+ * the notifications specified trough flags.
+ * The PCL client application will no longer receive from PAS the notifications specified in flags.
+ *
+ * \param flags [in] bitfield using a valid combination of any of the following flags : ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcUnRegisterFromPAS( unsigned int flags )
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+
+ if(NIL == persIpcUnRegisterFromPAS_handler[PERS_COM_IPC_PROTOCOL])
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Internal configuration error. No handler for persIpcUnRegisterFromPAS."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ retVal = persIpcUnRegisterFromPAS_handler[PERS_COM_IPC_PROTOCOL](flags);
+ if(PERS_COM_SUCCESS == retVal)
+ {
+ g_bPersCommonIPCInitPCL = false;
+ }
+
+ /* Initialize the logging interface */
+ if(true == g_bDltCtxInitialized)
+ {
+ DLT_UNREGISTER_CONTEXT(persComIpcDLTCtx);
+ g_bDltCtxInitialized = false;
+ }
+
+ return retVal;
+}
+
+
+/**
+ * \brief Send 'request processed' confirmation to PAS.
+ * \note Sends confirmation to PAS that the request specified by requestID has been processed.
+ * The status parameter should reflect this request and could also return an error.
+ *
+ * \param requestID [in] the ID of the processed request
+ * \param status [in] the status of the request processed by PCL
+ * - In case of success: bitfield using any of the following flags, depending on the request : ::PERSISTENCE_STATUS_LOCKED.
+ * - In case of error: the sum of ::PERSISTENCE_STATUS_ERROR and an error code \ref PERS_COM_IPC_DEFINES_ERROR is returned.
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+int persIpcSendConfirmationToPAS( int requestID,
+ unsigned int status)
+{
+ if(false == g_bPersCommonIPCInitPCL)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("PCL IPC protocol not initialized."));
+ return PERS_COM_FAILURE;
+ }
+
+ if(NIL == persIpcSendConfirmationToPAS_handler[PERS_COM_IPC_PROTOCOL])
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Internal configuration error. No handler for persIpcSendConfirmationToPAS."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ return persIpcSendConfirmationToPAS_handler[PERS_COM_IPC_PROTOCOL](requestID, status);
+}
diff --git a/src/pers_ipc_dbus.c b/src/pers_ipc_dbus.c
new file mode 100644
index 0000000..cac136d
--- /dev/null
+++ b/src/pers_ipc_dbus.c
@@ -0,0 +1,1590 @@
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Petrica.Manoila@continental-corporation.com
+*
+* Implementation of pers_ipc_dbus_if.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.10.24 uidu0250 CSP_WZ#6327 : Change error handling for missing PCL clients
+* 2013.04.03 uidu0250 CSP_WZ#2739 : Initial creation
+*
+**********************************************************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <gio/gio.h>
+#include <dlt.h>
+
+#include "persComErrors.h"
+#include "persComTypes.h"
+#include "persComIpc.h"
+#include "PasClientNotificationGen.h"
+#include "pers_ipc_dbus_if.h"
+
+/* ---------- local defines, macros, constants and type definitions ------------ */
+
+#define PERS_IPC_INIT_DBUS_INFO_ARRAY_SIZE (uint32_t)24
+#define DBUS_MAIN_LOOP_THREAD_FLAG_SET 1
+
+typedef struct persIpcDBusClientInfo_s_
+{
+ pstr_t busName;
+ pstr_t objName;
+}persIpcDBusClientInfo_s;
+
+
+/* ----------global variables. initialization of global contexts ------------ */
+
+DLT_IMPORT_CONTEXT(persComIpcDLTCtx);
+
+#define LT_HDR "COMMON_IPC >>"
+
+
+static PersAdminPASInitInfo_s g_pPersIpcPASInfo; /* PAS IPC initialization struct */
+static PersAdminPCLInitInfo_s g_pPersIpcPCLInfo; /* PCL IPC initialization struct */
+
+static persIpcDBusClientInfo_s **g_persIpcDBusClientInfoArray = NIL;
+static uint32_t g_persIpcDBusClientInfoArraySize = 0;
+static uint32_t g_persIpcDBusClientInfoMaxArraySize = 0;
+static pthread_mutex_t g_persIpcDBusClientInfoArrayMtx; /* mutex for the access to the DBus client info array */
+
+static pthread_t g_hPASDBusThread = 0; /* PAS DBus main loop thread */
+static int g_PASDBusMainLoopThreadFlag;
+static pthread_cond_t g_PASDBusMainLoopThreadFlagCV;
+static pthread_mutex_t g_PASDBusMainLoopThreadFlagMtx;
+static pthread_t g_hPCLDBusThread = 0; /* PCL DBus main loop thread */
+static int g_PCLDBusMainLoopThreadFlag;
+static pthread_cond_t g_PCLDBusMainLoopThreadFlagCV;
+static pthread_mutex_t g_PCLDBusMainLoopThreadFlagMtx;
+
+
+static GMainLoop *g_pPASMainLoop = NIL; /* PAS DBus main loop */
+static GDBusConnection *g_pPASDBusConnection = NIL; /* PAS DBus connection */
+static GMainLoop *g_pPCLMainLoop = NIL; /* PCL DBus main loop */
+static GDBusConnection *g_pPCLDBusConnection = NIL; /* PCL DBus connection */
+static OipPersistenceAdminSkeleton *g_persIpcDBusPASSkeleton = NIL;
+static OipPersistenceAdminProxy *g_persIpcDBusPASProxy = NIL;
+static OipPersistenceAdminconsumerSkeleton *g_persIpcDBusPCLSkeleton = NIL;
+static volatile bool_t g_bPASDBusConnInit = false;
+static volatile bool_t g_bPCLDBusConnInit = false;
+
+
+/* ---------------------- local functions ---------------------------------- */
+
+static void OnBusAcquired_cb( GDBusConnection *connection, const gchar *name, gpointer user_data);
+static void OnNameAcquired_cb( GDBusConnection *connection, const gchar *name, gpointer user_data);
+static void OnNameLost_cb( GDBusConnection *connection, const gchar *name, gpointer user_data);
+
+/* RegisterPersAdminNotification */
+static gboolean OnHandleRegisterPersAdminNotification ( OipPersistenceAdmin *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *arg_BusName,
+ const gchar *arg_ObjName,
+ gint arg_NotificationFlag,
+ guint arg_TimeoutMs);
+
+/* UnregisterPersAdminNotification */
+static gboolean OnHandleUnregisterPersAdminNotification(OipPersistenceAdmin *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *arg_BusName,
+ const gchar *arg_ObjName,
+ gint arg_NotificationFlag,
+ guint arg_TimeoutMs);
+
+/* PersistenceAdminRequestCompleted */
+static gboolean OnHandlePersAdminRequestCompleted( OipPersistenceAdmin *object,
+ GDBusMethodInvocation *invocation,
+ guint arg_RequestId,
+ gint arg_StatusFlag);
+
+/* PersAdminRequest */
+static gboolean OnHandlePersAdminRequest( OipPersistenceAdminconsumer *object,
+ GDBusMethodInvocation *invocation,
+ guint arg_RequestId,
+ gint arg_StatusFlag );
+
+/* PAS DBus loop thread */
+static void* persIpcPASLoopThread(void *lpParam);
+
+/* PCL DBus loop thread */
+static void* persIpcPCLLoopThread(void *lpParam);
+
+/* PCL DBus initialization function */
+static sint_t persIpcInitPCL_DBus_high();
+
+/* Get DBus client ID */
+static sint_t persIpcGetIdForDBusInfo(const pstr_t busName,
+ const pstr_t objName,
+ uint32_t *clientID);
+
+/* Export org.genivi.persistence.admin interface */
+static bool_t ExportPersistenceAdminIF(GDBusConnection *connection);
+
+/* Export org.genivi.persistence.adminconsumer interface */
+static bool_t ExportPersistenceAdminConsumerIF(GDBusConnection *connection);
+
+
+
+/**
+ * \brief Initialize PAS IPC DBus component
+ *
+ * \note : The function creates the DBus connection and tries to obtain the DBus name
+ * and exports the org.genivi.persistence.admin interface.
+ * It runs the DBus main loop on a second thread.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPASInitInfo_s structure containing
+ * the supported callbacks
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcInitPAS_DBus_high(PersAdminPASInitInfo_s *pInitInfo)
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+
+ if(NIL == pInitInfo)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in persIpcInitPAS_DBus_high call."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ if((NIL == pInitInfo->pRegCB) ||
+ (NIL == pInitInfo->pUnRegCB) ||
+ (NIL == pInitInfo->pReqCompleteCB))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in persIpcInitPAS_DBus_high call."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ g_pPersIpcPASInfo.pRegCB = pInitInfo->pRegCB;
+ g_pPersIpcPASInfo.pUnRegCB = pInitInfo->pUnRegCB;
+ g_pPersIpcPASInfo.pReqCompleteCB = pInitInfo->pReqCompleteCB;
+
+ /* Init synchronization objects */
+ if(0 != pthread_mutex_init (&g_persIpcDBusClientInfoArrayMtx, NIL))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create mutex."));
+ return PERS_COM_FAILURE;
+ }
+ if(0 != pthread_mutex_init (&g_PASDBusMainLoopThreadFlagMtx, NIL))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create mutex."));
+ (void)pthread_mutex_destroy(&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_FAILURE;
+ }
+ if(0 != pthread_cond_init (&g_PASDBusMainLoopThreadFlagCV, NIL))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create thread cond."));
+ (void)pthread_mutex_destroy(&g_PASDBusMainLoopThreadFlagMtx);
+ (void)pthread_mutex_destroy(&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_FAILURE;
+ }
+ g_PASDBusMainLoopThreadFlag = 0;
+
+ /* Create DBus main loop thread */
+ if(0 != pthread_create(&g_hPASDBusThread, NIL, persIpcPASLoopThread, NIL))
+ {
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create thread."));
+ (void)pthread_cond_destroy(&g_PASDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_destroy(&g_PASDBusMainLoopThreadFlagMtx);
+ (void)pthread_mutex_destroy(&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_FAILURE;
+ }
+
+ /* Wait for DBus connection initialization */
+ if(0 != pthread_mutex_lock (&g_PASDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ return PERS_COM_FAILURE;
+ }
+ while (!g_PASDBusMainLoopThreadFlag)
+ {
+ (void)pthread_cond_wait (&g_PASDBusMainLoopThreadFlagCV, &g_PASDBusMainLoopThreadFlagMtx);
+ }
+ (void)pthread_mutex_unlock (&g_PASDBusMainLoopThreadFlagMtx);
+
+ if(false == g_bPASDBusConnInit)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("PAS DBus connection setup failed."));
+
+ (void)pthread_cond_destroy(&g_PASDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_destroy(&g_PASDBusMainLoopThreadFlagMtx);
+ (void)pthread_mutex_destroy(&g_persIpcDBusClientInfoArrayMtx);
+
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ return retVal;
+}
+
+
+/**
+ * \brief Sends over DBus a request to the PCL client specified by clientId.
+ * \note : Each requestId should be unique.
+ *
+ * \param clientID [in] the client ID returned by the supplied pRegCB callback
+ * \param requestID [in] a unique identifier generated for every request
+ * \param request [in] the request to be sent (bitfield using a valid
+ * combination of any of the following flags :
+ * ::PERSISTENCE_MODE_LOCK, ::PERSISTENCE_MODE_SYNC and ::PERSISTENCE_MODE_UNLOCK)
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcSendRequestToPCL_DBus_high( sint_t clientID,
+ sint_t requestID,
+ uint_t request)
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+/* gboolean gbRetVal = false; */
+ gint32 outErrorCode = PERS_COM_SUCCESS;
+ persIpcDBusClientInfo_s dbusClientInfo;
+/* OipPersistenceAdminconsumerProxy *pClientNotifProxy = NIL; */
+ GError *gError = NIL;
+ GVariant *gVarReturnVal = NIL;
+ gint clientTimeout = 500; /* default timeout in ms */
+
+ if(false == g_bPASDBusConnInit)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus connection not initialized."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_ERR_NO_CONNECTION */
+ }
+
+ (void)memset(&dbusClientInfo, 0, sizeof(dbusClientInfo));
+
+
+ /* Get client DBus info */
+
+ /* Acquire mutex on array of DBus client info */
+ if(0 != pthread_mutex_lock (&g_persIpcDBusClientInfoArrayMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ return PERS_COM_FAILURE;
+ }
+
+ if(clientID >= g_persIpcDBusClientInfoArraySize)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid client specified :"),
+ DLT_INT(clientID));
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ if(NIL != g_persIpcDBusClientInfoArray[clientID])
+ {
+ dbusClientInfo.busName = (pstr_t)malloc((strlen(g_persIpcDBusClientInfoArray[clientID]->busName) + 1) * sizeof(*(dbusClientInfo.busName)));
+ if(NIL == dbusClientInfo.busName)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Error allocating memory for client info data."));
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_ERR_MALLOC;
+ }
+ else
+ {
+ (void)memset(dbusClientInfo.busName, 0, (strlen(g_persIpcDBusClientInfoArray[clientID]->busName) + 1) * sizeof(*(dbusClientInfo.busName)));
+ (void)memcpy(dbusClientInfo.busName, g_persIpcDBusClientInfoArray[clientID]->busName, strlen(g_persIpcDBusClientInfoArray[clientID]->busName) * sizeof(*(dbusClientInfo.busName)));
+ }
+
+ dbusClientInfo.objName = (pstr_t)malloc((strlen(g_persIpcDBusClientInfoArray[clientID]->objName) + 1) * sizeof(*(dbusClientInfo.objName)));
+ if(NIL == dbusClientInfo.objName)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Error allocating memory for client info data."));
+ (void)free(dbusClientInfo.busName);
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_ERR_MALLOC;
+ }
+ else
+ {
+ (void)memset(dbusClientInfo.objName, 0, (strlen(g_persIpcDBusClientInfoArray[clientID]->objName) + 1) * sizeof(*(dbusClientInfo.objName)));
+ (void)memcpy(dbusClientInfo.objName, g_persIpcDBusClientInfoArray[clientID]->objName, strlen(g_persIpcDBusClientInfoArray[clientID]->objName) * sizeof(*(dbusClientInfo.objName)));
+ }
+ }
+
+ /* Release array mutex */
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+
+
+ /* Synchronous call to "PersistenceAdminRequest" */
+
+ /* Does not work using generated code because PCL does not contain an implementation of 'GetAll' : */
+ /*
+ * checkPersAdminMsg 'org.freedesktop.DBus.Properties' -> 'GetAll'
+ * handleObjectPathMessageFallback Object: ':1.11' -> Interface: 'org.freedesktop.DBus.Properties' -> Message: 'GetAll'
+ * handleObjectPathMessageFallback -> not a signal 'GetAll'
+ */
+
+ /* TO DO : un-comment when PCL implementation is adapted to PersCommonIPC */
+
+ /* Get the proxy object */
+// pClientNotifProxy = NIL;
+// pClientNotifProxy = (OipPersistenceAdminconsumerProxy *)oip_persistence_adminconsumer_proxy_new_sync( g_pPASDBusConnection,
+// G_DBUS_PROXY_FLAGS_NONE,
+// dbusClientInfo.busName,
+// dbusClientInfo.objName,
+// NIL,
+// NIL);
+// if(NIL == pClientNotifProxy)
+// {
+// DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+// DLT_STRING("DBus PersAdminConsumer proxy creation failed."));
+// (void)free(dbusClientInfo.busName);
+// (void)free(dbusClientInfo.objName);
+// return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+// }
+//
+// (void)free(dbusClientInfo.busName);
+// (void)free(dbusClientInfo.objName);
+//
+// /* Synchronous call to "PersistenceAdminRequest" */
+// gbRetVal = oip_persistence_adminconsumer_call_persistence_admin_request_sync( (OipPersistenceAdminconsumer *)pClientNotifProxy,
+// (gint)request,
+// (guint)requestID,
+// &outErrorCode,
+// NIL,
+// &gError);
+//
+// /* Release the created proxy object */
+// g_object_unref(pClientNotifProxy);
+// pClientNotifProxy = NIL;
+//
+// if(false == gbRetVal)
+// {
+// DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+// DLT_STRING("DBus PersistenceAdminRequest call failed with DBus error :"),
+// DLT_STRING(gError->message));
+// g_error_free(gError);
+// return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+// }
+
+ gVarReturnVal = g_dbus_connection_call_sync ( g_pPASDBusConnection,
+ dbusClientInfo.busName,
+ dbusClientInfo.objName,
+ PERSISTENCE_ADMIN_CONSUMER_IFACE,
+ PERSISTENCE_ADMIN_CONSUMER_METHOD_PERS_ADMIN_REQ,
+ g_variant_new ("(ii)", (sint32_t)request, (sint32_t)requestID),
+ G_VARIANT_TYPE ("(i)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ clientTimeout,
+ NIL,
+ &gError);
+ if(NIL == gVarReturnVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersistenceAdminRequest call failed with DBus error :"),
+ DLT_STRING(gError->message));
+ g_error_free(gError);
+ (void)free(dbusClientInfo.busName);
+ (void)free(dbusClientInfo.objName);
+
+ /* consider that PCL client is not available on DBus */
+ return PERS_COM_IPC_ERR_PCL_NOT_AVAILABLE;
+ }
+
+ outErrorCode = g_variant_get_int32(gVarReturnVal);
+
+ g_variant_unref(gVarReturnVal);
+
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG, DLT_STRING(LT_HDR),
+ DLT_STRING("Notified client identified by DBus Name : \""),
+ DLT_STRING(dbusClientInfo.busName),
+ DLT_STRING("\" and Object Path : \""),
+ DLT_STRING(dbusClientInfo.objName),
+ DLT_STRING("\" Flags="),
+ DLT_INT(request),
+ DLT_STRING(" RequestId="),
+ DLT_INT(requestID),
+ DLT_STRING("\". Client returned "),
+ DLT_INT(outErrorCode));
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersistenceAdminRequest call returned output error code :"),
+ DLT_INT(outErrorCode));
+
+ (void)free(dbusClientInfo.busName);
+ (void)free(dbusClientInfo.objName);
+
+ retVal = outErrorCode;
+
+ return retVal;
+}
+
+
+/**
+ * \brief Register PCL client to PAS over DBus
+ *
+ * \note : An additional thread is created for communication purposes.
+ * Initialize members of the supplied PersAdminPCLInitInfo_s structure before calling this function.
+ *
+ * \param pInitInfo [in] pointer to a \ref PersAdminPCLInitInfo_s structure containing
+ * the supported callbacks
+ * \param flags [in] supported notification flags
+ * \param timeout [in] maximum time needed to process any supported request
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcRegisterToPAS_DBus_high( PersAdminPCLInitInfo_s * pInitInfo,
+ uint_t flags,
+ uint_t timeout)
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+ gboolean gbRetVal = false;
+ const gchar *gUniqueName = NIL;
+ gint outErrorCode;
+ GError *gError = NIL;
+
+
+ if(NIL == pInitInfo)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in persIpcRegisterToPAS_DBus_high call."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ if(NIL == pInitInfo->pReqCB)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in persIpcRegisterToPAS_DBus_high call."));
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ g_pPersIpcPCLInfo.pReqCB = pInitInfo->pReqCB;
+
+ /* Init DBus connection */
+ if(false == g_bPCLDBusConnInit)
+ {
+ retVal = persIpcInitPCL_DBus_high();
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("persIpcRegisterToPAS_DBus_high call failed with error code :"),
+ DLT_INT(retVal));
+ return retVal;
+ }
+ }
+
+ if(NIL == g_persIpcDBusPASProxy)
+ {
+ /* Get the PAS proxy object */
+ g_persIpcDBusPASProxy = (OipPersistenceAdminProxy *)oip_persistence_admin_proxy_new_sync( g_pPCLDBusConnection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ PERSISTENCE_ADMIN_BUS_NAME,
+ PERSISTENCE_ADMIN_OBJ_PATH,
+ NIL,
+ NIL);
+ if(NIL == g_persIpcDBusPASProxy)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersAdmin proxy creation failed."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+ }
+
+ gUniqueName = g_dbus_connection_get_unique_name(g_pPCLDBusConnection);
+ if(NIL == gUniqueName)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to obtain the unique DBus name."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_ERR_NO_CONNECTION */
+ }
+ else
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG,DLT_STRING(LT_HDR),
+ DLT_STRING("Successfully obtained unique BusName :"),
+ DLT_STRING(gUniqueName));
+ }
+
+ /* Synchronous call to "RegisterPersAdminNotification" */
+ gbRetVal = oip_persistence_admin_call_register_pers_admin_notification_sync((OipPersistenceAdmin *)g_persIpcDBusPASProxy,
+ gUniqueName,
+ PERSISTENCE_ADMIN_CONSUMER_OBJ_PATH,
+ (gint)flags,
+ (guint)timeout,
+ &outErrorCode,
+ NIL,
+ &gError);
+ if(false == gbRetVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus RegisterPersAdminNotification call failed with DBus error :"),
+ DLT_STRING(gError->message));
+ g_error_free(gError);
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus RegisterPersAdminNotification call returned output error code :"),
+ DLT_INT(outErrorCode));
+
+ retVal = outErrorCode;
+
+ return retVal;
+}
+
+
+/**
+ * \brief Initialize PCL IPC DBus component
+ *
+ * \note : An additional thread is created for communication purposes.
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+static sint_t persIpcInitPCL_DBus_high()
+{
+
+ sint_t retVal = PERS_COM_SUCCESS;
+ bool_t bRetVal;
+
+ if(0 != pthread_mutex_init (&g_PCLDBusMainLoopThreadFlagMtx, NIL))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create mutex."));
+ return PERS_COM_FAILURE;
+ }
+
+ if(0 != pthread_cond_init (&g_PCLDBusMainLoopThreadFlagCV, NIL))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create thread cond."));
+ (void)pthread_mutex_destroy(&g_PCLDBusMainLoopThreadFlagMtx);
+ return PERS_COM_FAILURE;
+ }
+
+ g_PCLDBusMainLoopThreadFlag = 0;
+
+ if(0 != pthread_create(&g_hPCLDBusThread, NIL, persIpcPCLLoopThread, NIL))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create thread."));
+ (void)pthread_cond_destroy(&g_PCLDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_destroy(&g_PCLDBusMainLoopThreadFlagMtx);
+ return PERS_COM_FAILURE;
+ }
+
+ /* Wait for DBus connection */
+ if(0 != pthread_mutex_lock (&g_PCLDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ return PERS_COM_FAILURE;
+ }
+ while (!g_PCLDBusMainLoopThreadFlag)
+ {
+ pthread_cond_wait (&g_PCLDBusMainLoopThreadFlagCV, &g_PCLDBusMainLoopThreadFlagMtx);
+ }
+ (void)pthread_mutex_unlock (&g_PCLDBusMainLoopThreadFlagMtx);
+
+ /* Check DBus connection status */
+ if(false == g_bPCLDBusConnInit)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("PCL DBus connection setup failed."));
+ (void)pthread_cond_destroy(&g_PCLDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_destroy(&g_PCLDBusMainLoopThreadFlagMtx);
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ /* Export the org.genivi.persistence.adminconsumer interface over DBus */
+ bRetVal = ExportPersistenceAdminConsumerIF(g_pPCLDBusConnection);
+ if(false == bRetVal)
+ {
+ /* Error: the interface could not be exported. */
+ g_main_loop_quit(g_pPCLMainLoop);
+ }
+ else
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR),
+ DLT_STRING("Successfully connected to D-Bus and exported object."));
+ }
+
+ return retVal;
+}
+
+
+/**
+ * \brief Un-Register PCL client application from PAS over DBus
+ * \note : The additional thread created for communication purposes is stopped.
+ *
+ * \param flags [in] supported notification flags
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcUnRegisterFromPAS_DBus_high( uint_t flags)
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+ gboolean gbRetVal = false;
+ const gchar *gUniqueName = NIL;
+ gint outErrorCode;
+ GError *gError = NIL;
+
+ if(false == g_bPCLDBusConnInit)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus connection not initialized."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_ERR_NO_CONNECTION */
+ }
+
+ if(NIL == g_persIpcDBusPASProxy)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersAdmin proxy not available."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ gUniqueName = g_dbus_connection_get_unique_name(g_pPCLDBusConnection);
+ if(NIL == gUniqueName)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to obtain the unique DBus name."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_ERR_NO_CONNECTION */
+ }
+
+ /* Synchronous call to "UnRegisterPersAdminNotification" */
+ gbRetVal = oip_persistence_admin_call_un_register_pers_admin_notification_sync( (OipPersistenceAdmin *)g_persIpcDBusPASProxy,
+ gUniqueName,
+ PERSISTENCE_ADMIN_CONSUMER_OBJ_PATH,
+ (gint)flags,
+ (guint)0, // deprecated
+ &outErrorCode,
+ NIL,
+ &gError);
+ if(false == gbRetVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus UnRegisterPersAdminNotification call failed with DBus error :"),
+ DLT_STRING(gError->message));
+ g_error_free(gError);
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus UnRegisterPersAdminNotification call returned output error code :"),
+ DLT_INT(outErrorCode));
+
+ retVal = outErrorCode;
+
+ /* Quit DBus main loop */
+ g_main_loop_quit(g_pPCLMainLoop);
+
+ /* Wait for persIpcPCLLoopThread */
+ pthread_join(g_hPCLDBusThread, NIL);
+
+ /* Release any created proxy object */
+ if(NIL != g_persIpcDBusPASProxy)
+ {
+ g_object_unref(g_persIpcDBusPASProxy);
+ g_persIpcDBusPASProxy = NIL;
+ }
+
+ return retVal;
+}
+
+
+/**
+ * \brief Send 'request processed' confirmation to PAS over DBus
+ * \note : Send confirmation to PAS that the request specified by requestId has been processed.
+ * The status parameter should reflect this request and could also return an error.
+ *
+ * \param requestID [in] the ID of the processed request
+ * \param status [in] the status of the request processed by PCL
+ * - In case of success: bitfield using any of the following flags, depending on the request : ::PERSISTENCE_STATUS_LOCKED.
+ * - In case of error: the sum of ::PERSISTENCE_STATUS_ERROR and an error code \ref PERS_COM_IPC_DEFINES_ERROR is returned.
+ *
+ * \return 0 for success, negative value for error (see \ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+sint_t persIpcSendConfirmationToPAS_DBus_high( sint_t requestID,
+ uint_t status)
+{
+ gboolean gbRetVal = false;
+ gint outErrorCode;
+ GError *gError = NIL;
+
+ if(false == g_bPCLDBusConnInit)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus connection not initialized."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_ERR_NO_CONNECTION */
+ }
+
+ if(NIL == g_persIpcDBusPASProxy)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersAdmin proxy not available."));
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ /* Synchronous call to "PersistenceAdminRequestCompleted" */
+ gbRetVal = oip_persistence_admin_call_persistence_admin_request_completed_sync( (OipPersistenceAdmin *)g_persIpcDBusPASProxy,
+ (guint)requestID,
+ (gint)status,
+ &outErrorCode,
+ NIL,
+ &gError);
+ if(false == gbRetVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersistenceAdminRequestCompleted call failed with DBus error :"),
+ DLT_STRING(gError->message));
+ g_error_free(gError);
+ return PERS_COM_FAILURE; /* PERS_COM_IPC_DBUS_ERROR */
+ }
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus PersistenceAdminRequestCompleted call returned output error code :"),
+ DLT_INT(outErrorCode));
+
+ return (sint_t)outErrorCode;
+}
+
+
+/**
+ * \brief Connection to DBus callback
+ *
+ * \note The function is called when a connection to the D-Bus could be established.
+ * According to the documentation the objects should be exported here.
+ *
+ * \param connection [in] Connection, which was acquired
+ * \param name [in] Bus name
+ * \param user_data [in] Optionally user data
+ *
+ * \return void
+ */
+static void OnBusAcquired_cb( GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ bool_t bRetVal;
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG,DLT_STRING(LT_HDR),
+ DLT_STRING("Successfully connected to DBus"));
+
+ /* Store the connection. */
+ g_pPASDBusConnection = connection;
+
+ /* Export the org.genivi.persistence.admin interface over DBus */
+ bRetVal = ExportPersistenceAdminIF(connection);
+ if(false == bRetVal)
+ {
+ /* Error: the interface could not be exported. */
+ g_main_loop_quit(g_pPASMainLoop);
+ }
+ else
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR),
+ DLT_STRING("Successfully connected to D-Bus and exported object."));
+ }
+}
+
+
+/**
+ * \brief DBus name obtained callback
+ *
+ * \note The function is called when the "bus name" could be acquired on the D-Bus.
+ *
+ * \param connection [in] Connection over which the bus name was acquired
+ * \param name [in] Acquired bus name
+ * \param user_data [in] Optionally user data
+ *
+ * \return void
+ */
+static void OnNameAcquired_cb( GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR),
+ DLT_STRING("Successfully obtained D-Bus name:"), DLT_STRING(name));
+
+ /* DBus connection initialized */
+ g_bPASDBusConnInit = true;
+
+ /* Notify that the DBus connection is ready */
+ if(0 != pthread_mutex_lock (&g_PASDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ return;
+ }
+ g_PASDBusMainLoopThreadFlag = DBUS_MAIN_LOOP_THREAD_FLAG_SET;
+ (void)pthread_cond_signal (&g_PASDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_unlock (&g_PASDBusMainLoopThreadFlagMtx);
+}
+
+
+/**
+ * \brief DBus name lost callback
+ *
+ * \note The function is called if either no connection to D-Bus could be established or
+ * the bus name could not be acquired.
+ *
+ * \param connection [in] Connection. If it is NIL, no D-Bus connection could be established.
+ * Otherwise the bus name was lost.
+ * \param name [in] Bus name
+ * \param user_data [in] Optionally user data
+ *
+ * \return void
+ */
+static void OnNameLost_cb( GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data )
+{
+ uint32_t clientIdx;
+
+ if(NIL == connection)
+ {
+ /* Error: the connection could not be established. */
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to establish D-Bus connection."));
+ }
+ else
+ {
+ /* Error: connection established, but name not obtained. This might be a second instance of the application */
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to obtain / Lost D-Bus name :"),
+ DLT_STRING(name));
+ }
+
+ /* DBus connection lost */
+ g_bPASDBusConnInit = false;
+
+ /* In both cases leave the main loop. */
+ g_main_loop_quit(g_pPASMainLoop);
+
+ /* Notify the DBus connection is not ready */
+ if(0 != pthread_mutex_lock (&g_PASDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ return;
+ }
+ g_PASDBusMainLoopThreadFlag = DBUS_MAIN_LOOP_THREAD_FLAG_SET;
+ (void)pthread_cond_signal (&g_PASDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_unlock (&g_PASDBusMainLoopThreadFlagMtx);
+
+ /* Acquire mutex on array of DBus client info */
+ if(0 != pthread_mutex_lock(&g_persIpcDBusClientInfoArrayMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ }
+ else
+ {
+ for(clientIdx = 0; clientIdx < g_persIpcDBusClientInfoArraySize; clientIdx++)
+ {
+ if(NIL != g_persIpcDBusClientInfoArray[clientIdx])
+ {
+ if(NIL != g_persIpcDBusClientInfoArray[clientIdx]->busName)
+ {
+ (void)free(g_persIpcDBusClientInfoArray[clientIdx]->busName);
+ }
+ if(NIL != g_persIpcDBusClientInfoArray[clientIdx]->objName)
+ {
+ (void)free(g_persIpcDBusClientInfoArray[clientIdx]->objName);
+ }
+ }
+ }
+ (void)pthread_mutex_unlock(&g_persIpcDBusClientInfoArrayMtx);
+ }
+}
+
+/**
+ * \brief RegisterPersAdminNotification DBus method callback
+ *
+ * \note Handler for RegisterPersAdminNotification.
+ * Signature based on generated code.
+ */
+static gboolean OnHandleRegisterPersAdminNotification ( OipPersistenceAdmin *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *arg_BusName,
+ const gchar *arg_ObjName,
+ gint arg_NotificationFlag,
+ guint arg_TimeoutMs)
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+ uint32_t clientId;
+
+ persIpcDBusClientInfo_s **tmpPersIpcDBusClientInfoArray = NIL;
+ persIpcDBusClientInfo_s *pNewClientInfo = NIL;
+
+ if((NIL == arg_BusName) || (NIL == arg_ObjName))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in RegisterPersAdminNotification handler."));
+ retVal = PERS_COM_ERR_INVALID_PARAM;
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG, DLT_STRING(LT_HDR),
+ DLT_STRING("RegisterPersAdminNotification called for BusName :"),
+ DLT_STRING(arg_BusName),
+ DLT_STRING("and ObjName :"),
+ DLT_STRING(arg_ObjName),
+ DLT_STRING("with params : NotificationFlag="),
+ DLT_INT(arg_NotificationFlag),
+ DLT_STRING(" TimeoutMs="),
+ DLT_INT(arg_TimeoutMs));
+
+ /* Check if the client is already registered */
+ retVal = persIpcGetIdForDBusInfo( (pstr_t)arg_BusName,
+ (pstr_t)arg_ObjName,
+ &clientId);
+ if(PERS_COM_SUCCESS == retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_WARN, DLT_STRING(LT_HDR),
+ DLT_STRING("DBus client already registered with BusName :"),
+ DLT_STRING(arg_BusName),
+ DLT_STRING("and ObjName :"),
+ DLT_STRING(arg_ObjName));
+ retVal = PERS_COM_FAILURE; /* PERS_COM_IPC_ERR_ALREADY_DONE */
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+
+ /* Acquire mutex on array of DBus client info */
+ if(0 != pthread_mutex_lock (&g_persIpcDBusClientInfoArrayMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ retVal = PERS_COM_FAILURE;
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+
+ /* Add DBus info for the new client */
+ if(g_persIpcDBusClientInfoArraySize >= g_persIpcDBusClientInfoMaxArraySize)
+ {
+ if(g_persIpcDBusClientInfoArraySize > 0)
+ {
+ tmpPersIpcDBusClientInfoArray = g_persIpcDBusClientInfoArray;
+
+ g_persIpcDBusClientInfoMaxArraySize *= 2;
+ }
+ else
+ {
+ g_persIpcDBusClientInfoMaxArraySize = PERS_IPC_INIT_DBUS_INFO_ARRAY_SIZE;
+ }
+
+ g_persIpcDBusClientInfoArray = (persIpcDBusClientInfo_s**)malloc(g_persIpcDBusClientInfoMaxArraySize * sizeof(*g_persIpcDBusClientInfoArray));
+ if(NIL == g_persIpcDBusClientInfoArray)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Error allocating memory for client info mapping list."));
+ g_persIpcDBusClientInfoArray = tmpPersIpcDBusClientInfoArray;
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ retVal = PERS_COM_ERR_MALLOC;
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+ else
+ {
+ (void)memset(g_persIpcDBusClientInfoArray, 0, g_persIpcDBusClientInfoMaxArraySize * sizeof(*g_persIpcDBusClientInfoArray));
+ }
+
+ if(g_persIpcDBusClientInfoArraySize > 0)
+ {
+ (void)memcpy(g_persIpcDBusClientInfoArray, tmpPersIpcDBusClientInfoArray, g_persIpcDBusClientInfoArraySize * sizeof(*g_persIpcDBusClientInfoArray));
+ }
+ }
+
+ pNewClientInfo = NIL;
+ pNewClientInfo = (persIpcDBusClientInfo_s*)malloc(sizeof(*pNewClientInfo));
+ if(NIL == pNewClientInfo)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Error allocating memory for client info."));
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ retVal = PERS_COM_ERR_MALLOC;
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+ else
+ {
+ (void)memset(pNewClientInfo, 0, sizeof(*pNewClientInfo));
+ }
+
+ /* received Bus Name should be a null terminated string */
+ pNewClientInfo->busName = (pstr_t)malloc((strlen(arg_BusName) + 1) * sizeof(*(pNewClientInfo->busName)));
+ if(NIL == pNewClientInfo->busName)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Error allocating memory for client info data (busName)."));
+ (void)free(pNewClientInfo);
+ pNewClientInfo = NIL;
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ retVal = PERS_COM_ERR_MALLOC;
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+ else
+ {
+ (void)memset(pNewClientInfo->busName, 0, (strlen(arg_BusName) + 1) * sizeof(*(pNewClientInfo->busName)));
+ (void)memcpy(pNewClientInfo->busName, arg_BusName, (strlen(arg_BusName) * sizeof(*(pNewClientInfo->busName))));
+ }
+
+ // received object name should be a null terminated string
+ pNewClientInfo->objName = (pstr_t)malloc((strlen(arg_ObjName) + 1) * sizeof(*(pNewClientInfo->objName)));/*DG C8MR2R-MISRA-C:2004 Rule 20.4-SSW_Administrator_0002*/
+ if(NIL == pNewClientInfo->objName)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Error allocating memory for client info data (objName)."));
+ (void)free(pNewClientInfo->busName);
+ (void)free(pNewClientInfo);
+ pNewClientInfo = NIL;
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ retVal = PERS_COM_ERR_MALLOC;
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+ else
+ {
+ (void)memset(pNewClientInfo->objName, 0, (strlen(arg_ObjName) + 1) * sizeof(*(pNewClientInfo->objName)));
+ (void)memcpy(pNewClientInfo->objName, arg_ObjName, (strlen(arg_ObjName) * sizeof(*(pNewClientInfo->objName))));
+ }
+
+ g_persIpcDBusClientInfoArray[g_persIpcDBusClientInfoArraySize++] = pNewClientInfo;
+
+ clientId = g_persIpcDBusClientInfoArraySize - 1;
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG, DLT_STRING(LT_HDR),
+ DLT_STRING("ClientId :"),
+ DLT_UINT32(clientId),
+ DLT_STRING("for BusName :"),
+ DLT_STRING(arg_BusName),
+ DLT_STRING("and ObjName :"),
+ DLT_STRING(arg_ObjName));
+
+ /* Release array mutex */
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+
+ /* Forward the call to the PAS callback */
+ retVal = g_pPersIpcPASInfo.pRegCB( clientId, /* clientId is the array index */
+ arg_NotificationFlag,
+ arg_TimeoutMs);
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR),
+ DLT_STRING("RegisterPersAdminNotification client callback failed with error code :"),
+ DLT_INT(retVal));
+
+ /*
+ * remove the registered client if the PAS callback returned an error,
+ * and forward the error to the PCL client
+ */
+
+ if(0 != pthread_mutex_lock (&g_persIpcDBusClientInfoArrayMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ }else
+ {
+ (void)free(g_persIpcDBusClientInfoArray[clientId]->busName);
+ (void)free(g_persIpcDBusClientInfoArray[clientId]->objName);
+ (void)free(g_persIpcDBusClientInfoArray[clientId]);
+ g_persIpcDBusClientInfoArray[clientId] = NIL;
+ --g_persIpcDBusClientInfoArraySize;
+
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ }
+ }
+
+ oip_persistence_admin_complete_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+
+ return(TRUE);
+}
+
+
+/**
+ * \brief UnregisterPersAdminNotification DBus method callback
+ *
+ * \note Handler for UnregisterPersAdminNotification.
+ * Signature based on generated code.
+ */
+static gboolean OnHandleUnregisterPersAdminNotification(OipPersistenceAdmin *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *arg_BusName,
+ const gchar *arg_ObjName,
+ gint arg_NotificationFlag,
+ guint arg_TimeoutMs) /* currently not used */
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+ uint32_t clientId;
+
+ if((NIL == arg_BusName) || (NIL == arg_ObjName))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Invalid parameter in UnregisterPersAdminNotification handler."));
+ retVal = PERS_COM_ERR_INVALID_PARAM;
+ oip_persistence_admin_complete_un_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG, DLT_STRING(LT_HDR),
+ DLT_STRING("UnregisterPersAdminNotification called for BusName :"),
+ DLT_STRING(arg_BusName),
+ DLT_STRING("and ObjName :"),
+ DLT_STRING(arg_ObjName),
+ DLT_STRING("with params : NotificationFlag="),
+ DLT_INT(arg_NotificationFlag),
+ DLT_STRING(" TimeoutMs="),
+ DLT_INT(arg_TimeoutMs));
+
+ /* Check if client is registered */
+ retVal = persIpcGetIdForDBusInfo( (pstr_t)arg_BusName,
+ (pstr_t)arg_ObjName,
+ &clientId);
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_WARN, DLT_STRING(LT_HDR),
+ DLT_STRING("DBus client not registered. BusName :"),
+ DLT_STRING(arg_BusName),
+ DLT_STRING(" and ObjName :"),
+ DLT_STRING(arg_ObjName));
+ retVal = PERS_COM_ERR_NOT_FOUND;
+ oip_persistence_admin_complete_un_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+ }
+
+ /* Forward the call to the PAS callback */
+ retVal = g_pPersIpcPASInfo.pUnRegCB(clientId, /* clientId is the array index */
+ arg_NotificationFlag);
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR),
+ DLT_STRING("UnregisterPersAdminNotification client callback failed with error code :"),
+ DLT_INT(retVal));
+ }
+ else
+ {
+ /* remove the registered client if the PAS callback returned success */
+ if(0 != pthread_mutex_lock (&g_persIpcDBusClientInfoArrayMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ }
+ else
+ {
+ (void)free(g_persIpcDBusClientInfoArray[clientId]->busName);
+ (void)free(g_persIpcDBusClientInfoArray[clientId]->objName);
+ (void)free(g_persIpcDBusClientInfoArray[clientId]);
+ g_persIpcDBusClientInfoArray[clientId] = NIL;
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ }
+ }
+
+ oip_persistence_admin_complete_un_register_pers_admin_notification( object,
+ invocation,
+ (gint)retVal);
+ return(TRUE);
+}
+
+
+/**
+ * \brief PersAdminRequestCompleted DBus method callback
+ *
+ * \note Handler for PersistenceAdminRequestCompleted.
+ * Signature based on generated code.
+ */
+static gboolean OnHandlePersAdminRequestCompleted( OipPersistenceAdmin *object,
+ GDBusMethodInvocation *invocation,
+ guint arg_RequestId,
+ gint arg_StatusFlag)
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+ const gchar * senderBusName = NIL;
+ uint32_t clientId;
+
+ /* Get the sender BusName */
+ senderBusName = g_dbus_method_invocation_get_sender(invocation);
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG, DLT_STRING(LT_HDR),
+ DLT_STRING("PersistenceAdminRequestCompleted called by "),
+ DLT_STRING(senderBusName),
+ DLT_STRING("with params : RequestId="),
+ DLT_UINT32(arg_RequestId),
+ DLT_STRING("and StatusFlag="),
+ DLT_INT(arg_StatusFlag));
+
+ retVal = persIpcGetIdForDBusInfo( (pstr_t)senderBusName,
+ NIL,
+ &clientId);
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("DBus client not registered. BusName :"),
+ DLT_STRING(senderBusName));
+ retVal = PERS_COM_ERR_NOT_FOUND;
+ oip_persistence_admin_complete_persistence_admin_request_completed( object,
+ invocation,
+ (gint)retVal);
+ return (TRUE);
+ }
+
+ /* Forward the call to the PAS callback */
+ retVal = g_pPersIpcPASInfo.pReqCompleteCB( clientId,
+ arg_RequestId,
+ arg_StatusFlag);
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("PersistenceAdminRequestCompleted client callback failed with error code :"),
+ DLT_INT(retVal));
+ }
+
+ oip_persistence_admin_complete_persistence_admin_request_completed( object,
+ invocation,
+ (gint)retVal);
+
+ return (TRUE);
+}
+
+
+/**
+ * \brief PersAdminRequest DBus method callback
+ *
+ * \note Handler for PersistenceAdminRequest.
+ * Signature based on generated code.
+ */
+static gboolean OnHandlePersAdminRequest( OipPersistenceAdminconsumer *object,
+ GDBusMethodInvocation *invocation,
+ guint arg_RequestId,
+ gint arg_StatusFlag )
+{
+ sint_t retVal = PERS_COM_SUCCESS;
+
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_DEBUG, DLT_STRING(LT_HDR),
+ DLT_STRING("PersistenceAdminRequest called with params : RequestId="),
+ DLT_UINT(arg_RequestId),
+ DLT_STRING("and StatusFlag="),
+ DLT_INT(arg_StatusFlag));
+
+ /* Forward the call to the PCL callback */
+ retVal = g_pPersIpcPCLInfo.pReqCB( arg_RequestId,
+ arg_StatusFlag );
+ if(PERS_COM_SUCCESS != retVal)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("PersistenceAdminRequest client callback failed with error code :"),
+ DLT_INT(retVal));
+ }
+
+ oip_persistence_adminconsumer_complete_persistence_admin_request( object,
+ invocation,
+ (gint)retVal);
+
+ return (TRUE);
+}
+
+
+/**
+ * \brief Function that exports the org.genivi.persistence.admin interface over DBus
+ *
+ * \param connection: Connection over which the interface should be exported
+ *
+ * \return true if successful, false otherwise
+ */
+static bool_t ExportPersistenceAdminIF(GDBusConnection *connection)
+{
+ GError *pError = NIL;
+
+ /* Create object to offer on the DBus */
+ g_persIpcDBusPASSkeleton = NIL;
+ g_persIpcDBusPASSkeleton = (OipPersistenceAdminSkeleton*) oip_persistence_admin_skeleton_new();
+ if(NIL == g_persIpcDBusPASSkeleton)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create PersistenceAdmin object."));
+ return false;
+ }
+
+ (void)g_signal_connect(g_persIpcDBusPASSkeleton, "handle-register-pers-admin-notification", G_CALLBACK(&OnHandleRegisterPersAdminNotification), NIL);
+ (void)g_signal_connect(g_persIpcDBusPASSkeleton, "handle-un-register-pers-admin-notification", G_CALLBACK(&OnHandleUnregisterPersAdminNotification), NIL);
+ (void)g_signal_connect(g_persIpcDBusPASSkeleton, "handle-persistence-admin-request-completed", G_CALLBACK(&OnHandlePersAdminRequestCompleted), NIL);
+
+
+ /* Attach interfaces to the objects and export them */
+ if(FALSE == g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(g_persIpcDBusPASSkeleton),
+ connection,
+ PERSISTENCE_ADMIN_OBJ_PATH,
+ &pError))
+ {
+ /* Error: PersistenceAdmin interface could not be exported. */
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to export PersistenceAdmin interface. Error :"),
+ DLT_STRING(pError->message));
+ g_error_free(pError);
+ g_object_unref(g_persIpcDBusPASSkeleton);
+ g_persIpcDBusPASSkeleton = NIL;
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * \brief Function that exports the org.genivi.persistence.adminconsumer interface over DBus
+ *
+ * \param connection: Connection over which the interface should be exported
+ *
+ * \return true if successful, false otherwise
+ */
+static bool_t ExportPersistenceAdminConsumerIF(GDBusConnection *connection)
+{
+ GError *pError = NIL;
+
+ /* Create object to offer on the DBus */
+ g_persIpcDBusPCLSkeleton = NIL;
+ g_persIpcDBusPCLSkeleton = (OipPersistenceAdminconsumerSkeleton*)oip_persistence_adminconsumer_skeleton_new();
+ if(NIL == g_persIpcDBusPCLSkeleton)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create PersistenceAdminConsumer object."));
+ return false;
+ }
+
+ (void)g_signal_connect(g_persIpcDBusPCLSkeleton, "handle-persistence-admin-request", G_CALLBACK(&OnHandlePersAdminRequest), NIL);
+
+ /* Attach interfaces to the objects and export them */
+ if(FALSE == g_dbus_interface_skeleton_export( G_DBUS_INTERFACE_SKELETON(g_persIpcDBusPCLSkeleton),
+ connection,
+ PERSISTENCE_ADMIN_CONSUMER_OBJ_PATH,
+ &pError))
+ {
+ /* Error: PersistenceAdminConsumer interface could not be exported. */
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to export PersistenceAdminConsumer interface. Error :"),
+ DLT_STRING(pError->message));
+ g_error_free(pError);
+ g_object_unref(g_persIpcDBusPCLSkeleton);
+ g_persIpcDBusPCLSkeleton = NIL;
+ return false;
+ }
+ return true;
+}
+
+
+/* PAS DBus loop thread */
+static void* persIpcPASLoopThread(void *lpParam)
+{
+ uint32_t u32ConnectionId = 0;
+
+ /* Initialize glib */
+ g_type_init(); /* deprecated. Since GLib 2.36, the type system is initialized automatically and this function does nothing.*/
+
+ /* Create the main loop */
+ g_pPASMainLoop = g_main_loop_new(NIL, FALSE);
+ if(NIL == g_pPASMainLoop)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to create DBus main loop."));
+
+ /* Notify that the DBus connection is not ready */
+ if(0 != pthread_mutex_lock (&g_PASDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ }
+ else
+ {
+ g_PASDBusMainLoopThreadFlag = DBUS_MAIN_LOOP_THREAD_FLAG_SET;
+ (void)pthread_cond_signal (&g_PASDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_unlock (&g_PASDBusMainLoopThreadFlagMtx);
+ }
+ return NIL;
+ }
+
+ /* Connect to the D-Bus. Obtain a bus name to offer PAS objects */
+ u32ConnectionId = g_bus_own_name( PERSISTENCE_ADMIN_BUS_TYPE
+ , PERSISTENCE_ADMIN_BUS_NAME
+ , G_BUS_NAME_OWNER_FLAGS_NONE
+ , &OnBusAcquired_cb
+ , &OnNameAcquired_cb
+ , &OnNameLost_cb
+ , NIL
+ , NIL);
+
+ /* The main loop is only canceled if the Node is completely shut down or the D-Bus connection fails */
+ g_main_loop_run(g_pPASMainLoop);
+
+ /* If the main loop returned, clean up. Release bus name and main loop */
+ g_bus_unown_name(u32ConnectionId);
+ g_main_loop_unref(g_pPASMainLoop);
+ g_pPASMainLoop = NIL;
+
+ /* Release the skeleton object */
+ if(NIL != g_persIpcDBusPASSkeleton)
+ {
+ g_object_unref(g_persIpcDBusPASSkeleton);
+ g_persIpcDBusPASSkeleton = NIL;
+ }
+
+ return NIL;
+}
+
+
+/* PCL DBus loop thread */
+static void* persIpcPCLLoopThread(void *lpParam)
+{
+ GError *pGError = NIL;
+
+ /* Initialize glib */
+ g_type_init(); /* deprecated. Since GLib 2.36, the type system is initialized automatically and this function does nothing.*/
+
+ /* Create the main loop */
+ g_pPCLMainLoop = g_main_loop_new(NIL, FALSE);
+
+ /* Connect to D-Bus */
+ g_pPCLDBusConnection = g_bus_get_sync( PERSISTENCE_ADMIN_BUS_TYPE,
+ NULL,
+ &pGError);
+
+ if(NIL == g_pPCLDBusConnection)
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to obtain a DBus connection. Error :"),
+ DLT_STRING(pGError->message));
+ g_error_free(pGError);
+ g_main_loop_unref(g_pPCLMainLoop);
+ if(0 != pthread_mutex_lock (&g_PCLDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ }
+ else
+ {
+ g_PCLDBusMainLoopThreadFlag = DBUS_MAIN_LOOP_THREAD_FLAG_SET;
+ (void)pthread_cond_signal (&g_PCLDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_unlock (&g_PCLDBusMainLoopThreadFlagMtx);
+ }
+ return NIL;
+ }
+
+
+ /* DBus connection initialized */
+ g_bPCLDBusConnInit = true;
+
+ /* Notify the DBus connection is ready (or not available) */
+ if(0 != pthread_mutex_lock (&g_PCLDBusMainLoopThreadFlagMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ }
+ g_PCLDBusMainLoopThreadFlag = DBUS_MAIN_LOOP_THREAD_FLAG_SET;
+ (void)pthread_cond_signal (&g_PCLDBusMainLoopThreadFlagCV);
+ (void)pthread_mutex_unlock (&g_PCLDBusMainLoopThreadFlagMtx);
+
+ g_main_loop_run(g_pPCLMainLoop);
+
+ g_bPCLDBusConnInit = false;
+
+ /* If the main loop returned, clean up */
+ g_main_loop_unref(g_pPCLMainLoop);
+
+ /* Release the skeleton object */
+ if(NIL != g_persIpcDBusPCLSkeleton)
+ {
+ g_object_unref(g_persIpcDBusPCLSkeleton);
+ g_persIpcDBusPCLSkeleton = NIL;
+ }
+
+ /* Release any created proxy object */
+ if(NIL != g_persIpcDBusPASProxy)
+ {
+ g_object_unref(g_persIpcDBusPASProxy);
+ g_persIpcDBusPASProxy = NIL;
+ }
+
+ return NIL;
+}
+
+
+/* Get DBus client ID */
+static sint_t persIpcGetIdForDBusInfo(const pstr_t busName,
+ const pstr_t objName,
+ uint32_t *clientID)
+{
+ uint32_t clientIdx;
+
+ if((NIL == busName) || (NIL == clientID))
+ {
+ return PERS_COM_ERR_INVALID_PARAM;
+ }
+
+ /* Acquire mutex on array of DBus client info */
+ if(0 != pthread_mutex_lock (&g_persIpcDBusClientInfoArrayMtx))
+ {
+ DLT_LOG(persComIpcDLTCtx, DLT_LOG_ERROR,DLT_STRING(LT_HDR),
+ DLT_STRING("Failed to lock mutex."));
+ return PERS_COM_FAILURE;
+ }
+
+ /* Check if client already registered */
+ for(clientIdx = 0; clientIdx < g_persIpcDBusClientInfoArraySize; ++clientIdx)
+ {
+ if(NIL != g_persIpcDBusClientInfoArray[clientIdx])
+ {
+ if(0 == strcmp(busName, g_persIpcDBusClientInfoArray[clientIdx]->busName))
+ {
+ if(NIL != objName)
+ {
+ if(0 == strcmp(objName, g_persIpcDBusClientInfoArray[clientIdx]->objName))
+ {
+ (*clientID) = clientIdx;
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_SUCCESS;
+ }
+ }
+ else
+ {
+ (*clientID) = clientIdx;
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+ return PERS_COM_SUCCESS;
+ }
+ }
+ }
+ }
+
+ /* Release array mutex */
+ (void)pthread_mutex_unlock (&g_persIpcDBusClientInfoArrayMtx);
+
+ return PERS_COM_ERR_NOT_FOUND;
+}
diff --git a/src/pers_local_shared_db_access.c b/src/pers_local_shared_db_access.c
new file mode 100644
index 0000000..a7a4678
--- /dev/null
+++ b/src/pers_local_shared_db_access.c
@@ -0,0 +1,287 @@
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Implementation of persComDbAccess.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.02.05 uidl9757 CSP_WZ#2220: Adaptation for open source
+* 2013.01.03 uidl9757 CSP_WZ#2060: Remove "cursor" interface
+* 2012.12.17 uidl9757 CSP_WZ#2060: Changes to allow optimized access to DB
+* 2012.12.10 uidl9757 CSP_WZ#2060: Created
+*
+**********************************************************************************************************************/
+
+#include "persComTypes.h"
+#include <stdio.h>
+#include "string.h"
+
+#include "persComDataOrg.h"
+#include "pers_low_level_db_access_if.h"
+#include "persComDbAccess.h"
+#include "persComErrors.h"
+
+/**
+ * \brief Obtain a handler to DB indicated by dbPathname
+ * \note : DB is created if it does not exist and (bForceCreationIfNotPresent != 0)
+ *
+ * \param dbPathname [in] absolute path to database (length limited to \ref PERS_ORG_MAX_LENGTH_PATH_FILENAME)
+ * \param bForceCreationIfNotPresent [in] if !=0x0, the database is created if it does not exist
+ *
+ * \return >= 0 for valid handler, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbOpen(char const * dbPathname, unsigned char bForceCreationIfNotPresent)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if(NIL != dbPathname)
+ {
+ if(strlen(dbPathname) >= PERS_ORG_MAX_LENGTH_PATH_FILENAME)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+ else
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_open(dbPathname, PersLldbPurpose_DB, bForceCreationIfNotPresent) ;
+ }
+
+ return iErrCode ;
+}
+
+/**
+ * \brief Close handler to DB
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbClose(signed int handlerDB)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if(handlerDB < 0)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_close(handlerDB) ;
+ }
+
+ return iErrCode ;
+}
+
+/**
+ * \brief write a key-value pair into local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ * \param data [in] buffer with key's data
+ * \param dataSize [in] size of key's data (max allowed \ref PERS_DB_MAX_SIZE_KEY_DATA)
+ *
+ * \return 0 for success, negative value otherwise (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbWriteKey(signed int handlerDB, char const * key, char const * data, signed int dataSize)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerDB < 0)
+ || (NIL == key)
+ || (NIL == data)
+ || (dataSize <= 0)
+ || (dataSize > PERS_DB_MAX_SIZE_KEY_DATA)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(key) >= PERS_DB_MAX_LENGTH_KEY_NAME)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_write_key(handlerDB, PersLldbPurpose_DB, key, data, dataSize) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief read a key's value from local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ * \param dataBuffer_out [out]buffer where to return the read data
+ * \param dataBufferSize [in] size of dataBuffer_out
+ *
+ * \return read size, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbReadKey(signed int handlerDB, char const * key, char* dataBuffer_out, signed int dataBufferSize)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerDB < 0)
+ || (NIL == key)
+ || (NIL == dataBuffer_out)
+ || (dataBufferSize <= 0)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(key) >= PERS_DB_MAX_LENGTH_KEY_NAME)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_read_key(handlerDB, PersLldbPurpose_DB, key, dataBuffer_out, dataBufferSize) ;
+ }
+
+ return iErrCode ;
+}
+
+/**
+ * \brief read a key's value from local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ *
+ * \return key's size, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbGetKeySize(signed int handlerDB, char const * key)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerDB < 0)
+ || (NIL == key)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(key) >= PERS_DB_MAX_LENGTH_KEY_NAME)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_get_key_size(handlerDB, PersLldbPurpose_DB, key) ;
+ }
+
+ return iErrCode ;
+}
+
+/**
+ * \brief delete key from local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param key [in] key's name (length limited to \ref PERS_DB_MAX_LENGTH_KEY_NAME)
+ *
+ * \return 0 for success, negative value otherwise (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbDeleteKey(signed int handlerDB, char const * key)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerDB < 0)
+ || (NIL == key)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(key) >= PERS_DB_MAX_LENGTH_KEY_NAME)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_delete_key(handlerDB, PersLldbPurpose_DB, key) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief Find the buffer's size needed to accomodate the list of keys' names in local/shared database
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ *
+ * \return needed size, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbGetSizeKeysList(signed int handlerDB)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if(handlerDB < 0)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_get_size_keys_list(handlerDB, PersLldbPurpose_DB) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief Obtain the list of the keys' names in local/shared database
+ * \note : keys in the list are separated by '\0'
+ *
+ * \param handlerDB [in] handler obtained with persComDbOpen
+ * \param listBuffer_out [out]buffer where to return the list of keys
+ * \param listBufferSize [in] size of listingBuffer_out
+ * \return >=0 for size of the list, or negative value in case of error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComDbGetKeysList(signed int handlerDB, char* listBuffer_out, signed int listBufferSize)
+ {
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerDB < 0)
+ || (NIL == listBuffer_out)
+ || (listBufferSize <= 0)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_get_keys_list(handlerDB, PersLldbPurpose_DB, listBuffer_out, listBufferSize) ;
+ }
+
+ return iErrCode ;
+}
+
diff --git a/src/pers_low_level_db_access.c b/src/pers_low_level_db_access.c
new file mode 100644
index 0000000..f66fa6c
--- /dev/null
+++ b/src/pers_low_level_db_access.c
@@ -0,0 +1,1515 @@
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Implementation of persComDbAccess.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.09.14 uidl9757 CSP_WZ#4872: Improvements
+* - synchronization between threads of the same process
+* - number of maximum simultan open handles by a process is no longer limited
+* 2013.08.30 uidl9757 CSP_WZ#5356: persistency common library uses too much stack size
+* 2013.07.10 uidl9757 CSP_WZ#4586: Add instrumentation for debug purposes
+* 2013.03.21 uidl9757 CSP_WZ#3774: Default error handler causes the termination of the calling process
+* 2013.03.21 uidl9757 CSP_WZ#2798: Workaround - reading from an emptied itzam db returns error
+* 2013.02.05 uidl9757 CSP_WZ#2220: Adaptation for open source
+* 2013.01.03 uidl9757 CSP_WZ#2060: Remove "cursor" interface
+* 2012.12.17 uidl9757 CSP_WZ#2060: Changes to allow optimized access to DB
+* 2012.12.10 uidl9757 CSP_WZ#2060: Created
+*
+**********************************************************************************************************************/
+
+#include <pthread.h>
+#include <stdio.h> /*DG C7MR2R-MISRA-C:2004 Rule 20.9-SSW_PersCommon_1003*/
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "persComTypes.h"
+
+#include "itzam.h"
+
+#include "persComErrors.h"
+#include "persComDataOrg.h"
+#include "persComDbAccess.h"
+#include "persComRct.h"
+
+#include "pers_low_level_db_access_if.h"
+
+#include "dlt.h"
+/* L&T context */
+#define LT_HDR "[persComLLDB]"
+DLT_DECLARE_CONTEXT (persComLldbDLTCtx);
+
+/* ---------------------- local definition ---------------------------- */
+/* max number of open handlers per process */
+#define PERS_LLDB_NO_OF_STATIC_HANDLES 16
+#define PERS_LLDB_MAX_STATIC_HANDLES (PERS_LLDB_NO_OF_STATIC_HANDLES-1)
+
+/* ---------------------- local types --------------------------------- */
+typedef enum {
+ dbType_unknown = 0,
+ dbType_itzam
+ /* TODO: Add here IDs for supported DB engines */
+} dbType_e;
+
+typedef struct
+{
+ char m_key[PERS_DB_MAX_LENGTH_KEY_NAME];
+ char m_data[PERS_DB_MAX_SIZE_KEY_DATA];
+ int m_dataSize ;
+}
+KeyValuePair_LocalDB_s;
+
+typedef struct
+{
+ char m_key[PERS_RCT_MAX_LENGTH_RESOURCE_ID];
+ char m_data[sizeof(PersistenceConfigurationKey_s)];
+}
+KeyValuePair_RCT_s;
+
+typedef struct
+{
+ bool_t bIsAssigned ;
+ sint_t dbHandler ;
+ pers_lldb_purpose_e ePurpose ;
+ itzam_btree btree;
+ str_t dbPathname[PERS_ORG_MAX_LENGTH_PATH_FILENAME] ;
+}lldb_handler_s ;
+
+typedef struct lldb_handles_list_el_s_
+{
+ lldb_handler_s sHandle ;
+ struct lldb_handles_list_el_s_ * pNext ;
+}lldb_handles_list_el_s ;
+
+typedef struct
+{
+ lldb_handler_s asStaticHandles[PERS_LLDB_NO_OF_STATIC_HANDLES] ; /* static area should be enough for most of the processes*/
+ lldb_handles_list_el_s* pListHead ; /* for the processes with a large number of threads which use Persistency */
+}lldb_handlers_s ;
+
+/* ---------------------- local variables --------------------------------- */
+static const char ListItemsSeparator = '\0';
+
+/* shared by all the threads within a process */
+static lldb_handlers_s g_sHandlers = {{{0}}} ;
+static pthread_mutex_t g_mutexLldb = PTHREAD_MUTEX_INITIALIZER; /*DG C7MR2R-MISRA-C:2004 Rule 18.4-SSW_PersCommon_1013*/
+
+/* ---------------------- local macros --------------------------------- */
+
+
+
+/* ---------------------- local functions --------------------------------- */
+static sint_t DeleteDataFromItzamDB( sint_t dbHandler, pconststr_t key );
+static void ErrorHandler( pconststr_t function_name, itzam_error error);
+static sint_t GetAllKeysFromItzamLocalDB( sint_t dbHandler, pstr_t buffer, sint_t size );
+static sint_t GetAllKeysFromItzamRCT( sint_t dbHandler, pstr_t buffer, sint_t size );
+static sint_t GetKeySizeFromItzamLocalDB( sint_t dbHandler, pconststr_t key) ;
+static sint_t GetDataFromItzamLocalDB( sint_t dbHandler, pconststr_t key, pstr_t buffer_out, sint_t bufSize );
+static sint_t GetDataFromItzamRCT( sint_t dbHandler, pconststr_t key, PersistenceConfigurationKey_s* pConfig);
+static sint_t SetDataInItzamLocalDB( sint_t dbHandler, pconststr_t key, pconststr_t data, sint_t dataSize );
+static sint_t SetDataInItzamRCT( sint_t dbHandler, pconststr_t key, PersistenceConfigurationKey_s const * pConfig);
+/* access to resources shared by the threads within a process */
+static bool_t lldb_handles_Lock(void);
+static bool_t lldb_handles_Unlock(void);
+static lldb_handler_s* lldb_handles_FindInUseHandle(sint_t dbHandler) ;
+static lldb_handler_s* lldb_handles_FindAvailableHandle(void) ;
+static void lldb_handles_InitHandle(lldb_handler_s* psHandle_inout, pers_lldb_purpose_e ePurpose, str_t const * dbPathname);
+static bool_t lldb_handles_DeinitHandle(sint_t dbHandler);
+
+
+/**
+ * \brief write a key-value pair into database
+ * \note : DB type is identified from dbPathname (based on extension)
+ *
+ * \param dbPathname [in] absolute path to DB
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ * \param bForceCreationIfNotPresent [in] if true, the DB is created if it does not exist
+ *
+ * \return >=0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_open(str_t const * dbPathname, pers_lldb_purpose_e ePurpose, bool_t bForceCreationIfNotPresent)
+{
+ sint_t returnValue = PERS_COM_FAILURE ;
+ bool_t bCanContinue = true ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+
+ static bool_t bFirstCall = true ;
+
+ if(bFirstCall)
+ {
+ pid_t pid = getpid() ;
+ str_t dltContextID[16] ; /* should be at most 4 characters string, but colissions occure */
+
+ /* set an error handler - the default one will cause the termination of the calling process */
+ bFirstCall = false ;
+ itzam_set_default_error_handler(&ErrorHandler) ;
+ /* init DLT */
+ (void)snprintf(dltContextID, sizeof(dltContextID), "Pers_%04d", pid) ;
+ DLT_REGISTER_CONTEXT(persComLldbDLTCtx, dltContextID, "PersCommonLLDB");
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("register context PersCommonLLDB ContextID="); DLT_STRING(dltContextID));
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("<<"); DLT_STRING(dbPathname); DLT_STRING(">>, ");
+ ((PersLldbPurpose_RCT == ePurpose) ? DLT_STRING("RCT, ") : DLT_STRING("DB, "));
+ ((true == bForceCreationIfNotPresent) ? DLT_STRING("forced, ") : DLT_STRING("unforced, "));
+ DLT_STRING(" ... ")) ;
+
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindAvailableHandle() ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ returnValue = PERS_COM_ERR_OUT_OF_MEMORY ;
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ }
+
+ if(bCanContinue)
+ {
+ itzam_state state = ITZAM_NOT_FOUND;
+ size_t treeEntrySize = (PersLldbPurpose_RCT == ePurpose) ? sizeof(KeyValuePair_RCT_s) : sizeof(KeyValuePair_LocalDB_s) ;
+
+ state = itzam_btree_open( & pLldbHandler->btree, dbPathname, &itzam_comparator_string, &ErrorHandler, 0/*recover*/, 0/*read_only*/);
+ if( state != ITZAM_OKAY )
+ {
+ if(bForceCreationIfNotPresent)
+ {
+ state = itzam_btree_create( & pLldbHandler->btree, dbPathname, ITZAM_BTREE_ORDER_DEFAULT, (itzam_int)treeEntrySize, &itzam_comparator_string, &ErrorHandler );
+ if(ITZAM_OKAY != state)
+ {
+ bCanContinue = false ;
+ returnValue = PERS_COM_FAILURE ;
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ returnValue = PERS_COM_ERR_NOT_FOUND ;
+ }
+ }
+
+ if(bCanContinue)
+ {
+ lldb_handles_InitHandle(pLldbHandler, ePurpose, dbPathname) ;
+ returnValue = pLldbHandler->dbHandler;
+ }
+ else
+ {
+ /* clean up */
+ returnValue = PERS_COM_FAILURE ;
+ (void)lldb_handles_DeinitHandle(pLldbHandler->dbHandler) ;
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("<<"); DLT_STRING(dbPathname); DLT_STRING(">>, ");
+ ((PersLldbPurpose_RCT == ePurpose) ? DLT_STRING("RCT, ") : DLT_STRING("DB, "));
+ ((true == bForceCreationIfNotPresent) ? DLT_STRING("forced, ") : DLT_STRING("unforced, "));
+ DLT_STRING("retval=<"); DLT_INT(returnValue); DLT_STRING(">")) ;
+
+ return returnValue ;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/ /*DG C7MR2R-ISQP Metric 6-SSW_PersCommon_1005*/
+
+
+/**
+ * \brief write a key-value pair into database
+ * \note : DB type is identified from dbPathname (based on extension)
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ *
+ * \return 0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_close(sint_t handlerDB)
+{
+ sint_t returnValue = PERS_COM_SUCCESS ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("handlerDB="); DLT_INT(handlerDB); DLT_STRING("...")) ;
+
+ if(handlerDB >= 0)
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(handlerDB) ;
+ if(NIL == pLldbHandler)
+ {
+ returnValue = PERS_COM_FAILURE ;
+ }
+ else
+ {
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ returnValue = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == returnValue)
+ {
+ if(ITZAM_OKAY == itzam_btree_close( & pLldbHandler->btree))
+ {
+ if( ! lldb_handles_DeinitHandle(pLldbHandler->dbHandler))
+ {
+ returnValue = PERS_COM_FAILURE ;
+ }
+ }
+ else
+ {
+ returnValue = PERS_COM_FAILURE ;
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("handlerDB="); DLT_INT(handlerDB);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(returnValue); DLT_STRING(">")) ;
+
+ return returnValue ;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+/**
+ * \brief write a key-value pair into database
+ * \note : DB type is identified from dbPathname (based on extension)
+ * \note : DB is created if it does not exist
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ * \param key [in] key's name
+ * \param data [in] buffer with key's data
+ * \param dataSize [in] size of key's data
+ *
+ * \return 0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_write_key(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key, str_t const * data, sint_t dataSize)
+{
+ sint_t eErrorCode = PERS_COM_SUCCESS ;
+
+ switch(ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ {
+ eErrorCode = SetDataInItzamLocalDB(handlerDB, key, data, dataSize) ;
+ break ;
+ }
+ case PersLldbPurpose_RCT:
+ {
+ eErrorCode = SetDataInItzamRCT(handlerDB, key, (PersistenceConfigurationKey_s const *)data) ;
+ break ;
+ }
+ default:
+ {
+ eErrorCode = PERS_COM_ERR_INVALID_PARAM ;
+ break ;
+ }
+ }
+
+ return eErrorCode ;
+}
+
+
+/**
+ * \brief read a key's value from database
+ * \note : DB type is identified from dbPathname (based on extension)
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ * \param key [in] key's name
+ * \param dataBuffer_out [out]buffer where to return the read data
+ * \param bufSize [in] size of dataBuffer_out
+ *
+ * \return read size, or negative value in case of error (see pers_error_codes.h)
+ */
+sint_t pers_lldb_read_key(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key, pstr_t dataBuffer_out, sint_t bufSize)
+{
+ sint_t eErrorCode = PERS_COM_SUCCESS ;
+
+ switch(ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ {
+ eErrorCode = GetDataFromItzamLocalDB(handlerDB, key, dataBuffer_out, bufSize) ;
+ break ;
+ }
+ case PersLldbPurpose_RCT:
+ {
+ eErrorCode = GetDataFromItzamRCT(handlerDB, key, (PersistenceConfigurationKey_s*)dataBuffer_out) ;
+ break ;
+ }
+ default:
+ {
+ eErrorCode = PERS_COM_ERR_INVALID_PARAM ;
+ break ;
+ }
+ }
+
+ return eErrorCode ;
+}
+
+/**
+ * \brief read a key's value from database
+ * \note : DB type is identified from dbPathname (based on extension)
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ * \param key [in] key's name
+ * \return key's size, or negative value in case of error (see pers_error_codes.h)
+ */
+sint_t pers_lldb_get_key_size(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key)
+{
+ sint_t eErrorCode = PERS_COM_SUCCESS ;
+
+ switch(ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ {
+ eErrorCode = GetKeySizeFromItzamLocalDB(handlerDB, key) ;
+ break ;
+ }
+ default:
+ {
+ eErrorCode = PERS_COM_ERR_INVALID_PARAM ;
+ break ;
+ }
+ }
+
+ return eErrorCode ;
+}
+
+/**
+ * \brief delete key from database
+ * \note : DB type is identified from dbPathname (based on extension)
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ * \param key [in] key's name
+ *
+ * \return 0 for success, negative value otherway (see pers_error_codes.h)
+ */
+sint_t pers_lldb_delete_key(sint_t handlerDB, pers_lldb_purpose_e ePurpose, str_t const * key)
+{
+ sint_t eErrorCode = PERS_COM_SUCCESS ;
+
+ switch(ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ case PersLldbPurpose_RCT:
+ {
+ eErrorCode = DeleteDataFromItzamDB(handlerDB, key) ;
+ break ;
+ }
+ default:
+ {
+ eErrorCode = PERS_COM_ERR_INVALID_PARAM ;
+ break ;
+ }
+ }
+
+ return eErrorCode ;
+}
+
+
+/**
+ * \brief Find the buffer's size needed to accomodate the listing of keys' names in database
+ * \note : DB type is identified from dbPathname (based on extension)
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ *
+ * \return needed size, or negative value in case of error (see pers_error_codes.h)
+ */
+sint_t pers_lldb_get_size_keys_list(sint_t handlerDB, pers_lldb_purpose_e ePurpose)
+{
+ sint_t eErrorCode = PERS_COM_SUCCESS ;
+
+ switch(ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ {
+ eErrorCode = GetAllKeysFromItzamLocalDB(handlerDB, NIL, 0) ;
+ break ;
+ }
+ case PersLldbPurpose_RCT:
+ {
+ eErrorCode = GetAllKeysFromItzamRCT(handlerDB, NIL, 0) ;
+ break ;
+ }
+ default:
+ {
+ eErrorCode = PERS_COM_ERR_INVALID_PARAM ;
+ break ;
+ }
+ }
+
+ return eErrorCode ;
+}
+
+
+/**
+ * \brief List the keys' names in database
+ * \note : DB type is identified from dbPathname (based on extension)
+ * \note : keys are separated by '\0'
+ *
+ * \param handlerDB [in] handler obtained with pers_lldb_open
+ * \param ePurpose [in] see pers_lldb_purpose_e
+ * \param listingBuffer_out [out]buffer where to return the listing
+ * \param bufSize [in] size of listingBuffer_out
+ *
+ * \return listing size, or negative value in case of error (see pers_error_codes.h)
+ */
+ sint_t pers_lldb_get_keys_list(sint_t handlerDB, pers_lldb_purpose_e ePurpose, pstr_t listingBuffer_out, sint_t bufSize)
+ {
+ sint_t eErrorCode = PERS_COM_SUCCESS ;
+
+ switch(ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ {
+ eErrorCode = GetAllKeysFromItzamLocalDB(handlerDB, listingBuffer_out, bufSize) ;
+ break ;
+ }
+ case PersLldbPurpose_RCT:
+ {
+ eErrorCode = GetAllKeysFromItzamRCT(handlerDB, listingBuffer_out, bufSize) ;
+ break ;
+ }
+ default:
+ {
+ eErrorCode = PERS_COM_ERR_INVALID_PARAM ;
+ break ;
+ }
+ }
+
+ return eErrorCode ;
+}
+
+static sint_t DeleteDataFromItzamDB( sint_t dbHandler, pconststr_t key )
+{
+ bool_t bCanContinue = true ;
+ sint_t delete_size = PERS_COM_FAILURE ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("handlerDB="); DLT_INT(dbHandler);
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>...")) ;
+
+ if( (dbHandler >= 0) && (NIL != key))
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ }
+ else
+ {
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ }
+
+
+ if(bCanContinue)
+ {
+ switch(pLldbHandler->ePurpose)
+ {
+ case PersLldbPurpose_DB:
+ {
+ KeyValuePair_LocalDB_s search;
+ if( itzam_true == itzam_btree_find( &pLldbHandler->btree, key, & search ) )
+ {
+ if(ITZAM_OKAY == itzam_btree_remove( &pLldbHandler->btree, key ))
+ {
+ delete_size = search.m_dataSize ;
+ }
+ else
+ {
+ delete_size = PERS_COM_FAILURE ;
+ }
+ }
+ else
+ {
+ delete_size = PERS_COM_ERR_NOT_FOUND ;
+ }
+ break ;
+ }
+ case PersLldbPurpose_RCT:
+ {
+ KeyValuePair_RCT_s search;
+ if( itzam_true == itzam_btree_find( &pLldbHandler->btree, key, & search ) )
+ {
+ if(ITZAM_OKAY == itzam_btree_remove( &pLldbHandler->btree, key ))
+ {
+ delete_size = sizeof(PersistenceConfigurationKey_s) ;
+ }
+ else
+ {
+ delete_size = PERS_COM_FAILURE ;
+ }
+ }
+ else
+ {
+ delete_size = PERS_COM_ERR_NOT_FOUND ;
+ }
+ break ;
+ }
+ default:
+ {
+ break ;
+ }
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("handlerDB="); DLT_INT(dbHandler);
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(delete_size); DLT_STRING(">")) ;
+
+ return delete_size;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+static void ErrorHandler(pconststr_t function_name, itzam_error error )
+{
+ (void)fprintf( stderr, "pers_lldb:ErrorHandler:Itzam error in %s: %d\n", function_name, (sint_t)error );
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("ErrorHandler:Itzam error in "); DLT_STRING(function_name);
+ DLT_STRING("error=<"); DLT_INT((sint_t)error); DLT_STRING(">") ) ;
+}
+
+static sint_t GetAllKeysFromItzamLocalDB( sint_t dbHandler, pstr_t buffer, sint_t size )
+{
+ bool_t bCanContinue = true ;
+ itzam_btree_cursor cursor;
+ sint_t availableSize = size;
+ sint_t result = 0 ;
+ KeyValuePair_LocalDB_s crtKey;
+ bool_t bOnlySizeNeeded = (NIL == buffer) ;
+ itzam_state itzState ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("buffer="); DLT_UINT((uint_t)buffer);
+ DLT_STRING("size="); DLT_INT(size); DLT_STRING("...")) ;
+
+ if(dbHandler >= 0)
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ result = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_DB != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ result = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ result = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ if( ( buffer != NIL ) && ( size > 0 ) )
+ {
+ (void)memset( buffer, 0, (size_t)size );
+ }
+
+ itzState = itzam_btree_cursor_create( & cursor, & pLldbHandler->btree) ;
+ if(ITZAM_OKAY == itzState)
+ {
+ (void)memset( & crtKey, 0, sizeof( crtKey ) );
+ itzState = itzam_btree_cursor_read( & cursor, & crtKey ) ;
+ if(ITZAM_OKAY == itzState)
+ {
+ /* Add the length of the key separator to the count */
+ size_t keyLen = strnlen( crtKey.m_key, sizeof( crtKey.m_key ) ) ;
+ if(keyLen > 0)
+ {
+ if( (! bOnlySizeNeeded) && ( (sint_t)keyLen < availableSize ) )
+ {
+ (void)strncpy( buffer, crtKey.m_key, keyLen);
+ *(buffer+keyLen) = ListItemsSeparator; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ buffer += (keyLen + sizeof(ListItemsSeparator)) ; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ availableSize -= (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+ result += (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+
+ while ( itzam_btree_cursor_next( & cursor ) == itzam_true )
+ {
+ (void)memset( & crtKey, 0, sizeof( crtKey ) );
+ if( ITZAM_OKAY == itzam_btree_cursor_read( & cursor, & crtKey ) )
+ {
+ /* Add the length of the key separator to the count */
+ keyLen = strnlen( crtKey.m_key, sizeof( crtKey.m_key ) ) ; /* + sizeof( ListItemsSeparator ); */
+ if(keyLen > 0)
+ {
+ if( (! bOnlySizeNeeded) && ( (sint_t)keyLen < availableSize ) )
+ {
+ (void)strncpy( buffer, crtKey.m_key, keyLen);
+ *(buffer+keyLen) = ListItemsSeparator; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ buffer += (keyLen + sizeof(ListItemsSeparator)) ; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ availableSize -= (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+ result += (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+ }
+ }
+
+ (void)itzam_btree_cursor_free( & cursor );
+ }
+ }
+ else
+ {
+ if(ITZAM_FAILED == itzState)
+ {
+ /* no data found */
+ result = 0 ;
+ }
+ else
+ {
+ result = PERS_COM_FAILURE;
+ }
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(result); DLT_STRING(">")) ;
+
+ return result;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/ /*DG C7MR2R-ISQP Metric 11-SSW_PersCommon_1001*/ /*DG C7MR2R-ISQP Metric 1-SSW_PersCommon_1006*/ /*DG C7MR2R-ISQP Metric 6-SSW_PersCommon_1007*/
+
+static sint_t GetAllKeysFromItzamRCT( sint_t dbHandler, pstr_t buffer, sint_t size )
+{
+ bool_t bCanContinue = true ;
+ itzam_btree_cursor cursor;
+ sint_t availableSize = size;
+ sint_t result = 0 ;
+ KeyValuePair_RCT_s crtKey;
+ bool_t bOnlySizeNeeded = (NIL == buffer) ;
+ itzam_state itzState ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("buffer="); DLT_UINT((uint_t)buffer);
+ DLT_STRING("size="); DLT_INT(size); DLT_STRING("...")) ;
+
+ if(dbHandler >= 0)
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ result = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_RCT != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ result = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ result = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ if( ( buffer != NIL ) && ( size > 0 ) )
+ {
+ (void)memset( buffer, 0, (size_t)size );
+ }
+
+ itzState = itzam_btree_cursor_create( & cursor, & pLldbHandler->btree) ;
+ if(ITZAM_OKAY == itzState)
+ {
+ (void)memset( & crtKey, 0, sizeof( crtKey ) );
+ itzState = itzam_btree_cursor_read( & cursor, & crtKey ) ;
+ if(ITZAM_OKAY == itzState)
+ {
+ /* Add the length of the key separator to the count */
+ size_t keyLen = strnlen( crtKey.m_key, sizeof( crtKey.m_key ) ) ;
+ if(keyLen > 0)
+ {
+ if( (! bOnlySizeNeeded) && ( (sint_t)keyLen < availableSize ) )
+ {
+ (void)strncpy( buffer, crtKey.m_key, keyLen);
+ *(buffer+keyLen) = ListItemsSeparator; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ buffer += (sint_t)(keyLen + sizeof(ListItemsSeparator)) ; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ availableSize -= (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+ result += (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+
+ while ( itzam_btree_cursor_next( & cursor ) == itzam_true )
+ {
+ (void)memset( & crtKey, 0, sizeof( crtKey ) );
+ if( ITZAM_OKAY == itzam_btree_cursor_read( & cursor, & crtKey ) )
+ {
+ /* Add the length of the key separator to the count */
+ keyLen = strnlen( crtKey.m_key, sizeof( crtKey.m_key ) ) ; /* + sizeof( ListItemsSeparator ); */
+ if(keyLen > 0)
+ {
+ if( (! bOnlySizeNeeded) && ( (sint_t)keyLen < availableSize ) )
+ {
+ (void)strncpy( buffer, crtKey.m_key, keyLen);
+ *(buffer+keyLen) = ListItemsSeparator; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ buffer += (keyLen + sizeof(ListItemsSeparator)) ; /*DG C7MR2R-MISRA-C:2004 Rule 17.4-SSW_PersCommon_1004*/
+ availableSize -= (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+ result += (sint_t)(keyLen + sizeof(ListItemsSeparator));
+ }
+ }
+ }
+
+ (void)itzam_btree_cursor_free( & cursor );
+ }
+ }
+ else
+ {
+ if(ITZAM_FAILED == itzState)
+ {
+ /* no data found */
+ result = 0 ;
+ }
+ else
+ {
+ result = PERS_COM_FAILURE;
+ }
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(result); DLT_STRING(">")) ;
+
+ return result;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/ /*DG C7MR2R-ISQP Metric 11-SSW_PersCommon_0002*/ /*DG C7MR2R-ISQP Metric 1-SSW_PersCommon_1008*/ /*DG C7MR2R-ISQP Metric 6-SSW_PersCommon_1009*/
+
+
+/* return no of bytes written, or negative value in case of error */
+static sint_t SetDataInItzamLocalDB(sint_t dbHandler, pconststr_t key, pconststr_t data, sint_t dataSize)
+{
+ bool_t bCanContinue = true ;
+ sint_t size_written = PERS_COM_FAILURE;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("size<<"); DLT_INT(dataSize); DLT_STRING(">> ...")) ;
+
+ if(( dbHandler >= 0)
+ && (NIL != key)
+ && (NIL != data)
+ && (dataSize > 0) )
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ size_written = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_DB != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ size_written = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ size_written = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ KeyValuePair_LocalDB_s search_insert; /* use a single variable to reduce stack size */
+
+ if( itzam_true == itzam_btree_find( & pLldbHandler->btree, key, & search_insert ) )
+ {
+ if(ITZAM_OKAY != itzam_btree_remove( & pLldbHandler->btree, key ))
+ {
+ bCanContinue = false ;
+ }
+ }
+
+ if(bCanContinue)
+ {
+ (void)memset(search_insert.m_data, 0, sizeof(search_insert.m_data) );
+ (void)strncpy(search_insert.m_key, key, sizeof(search_insert.m_key)) ;
+ (void)memcpy(search_insert.m_data, data, (size_t)dataSize) ;
+ search_insert.m_dataSize = dataSize ;
+ if(ITZAM_OKAY == itzam_btree_insert( & pLldbHandler->btree, ( void * )( & search_insert ) ))
+ {
+ size_written = dataSize;
+ }
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("size<<"); DLT_INT(dataSize); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(size_written); DLT_STRING(">")) ;
+
+ return size_written;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+static sint_t SetDataInItzamRCT( sint_t dbHandler, pconststr_t key, PersistenceConfigurationKey_s const * pConfig)
+{
+ bool_t bCanContinue = true ;
+ sint_t size_written = PERS_COM_FAILURE;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>...")) ;
+
+ if( (dbHandler >= 0)
+ && (NIL != key)
+ && (NIL != pConfig) )
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ size_written = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_RCT != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ size_written = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ size_written = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ KeyValuePair_RCT_s search, insert;
+
+ (void)memset(insert.m_data, 0, sizeof(insert.m_data) );
+ (void)strncpy(insert.m_key, key, sizeof(insert.m_key)) ;
+ (void)memcpy(insert.m_data, pConfig, sizeof(PersistenceConfigurationKey_s)) ;
+
+ if( itzam_true == itzam_btree_find( & pLldbHandler->btree, key, & search ) )
+ {
+ if(ITZAM_OKAY == itzam_btree_remove( & pLldbHandler->btree, key ))
+ {
+ if(ITZAM_OKAY == itzam_btree_insert( & pLldbHandler->btree, ( void * )( & insert ) ))
+ {
+ size_written = (sint_t)sizeof(PersistenceConfigurationKey_s);
+ }
+ }
+ }
+ else
+ {
+ if(ITZAM_OKAY == itzam_btree_insert( & pLldbHandler->btree, ( void * )( & insert ) ))
+ {
+ size_written = (sint_t)sizeof(PersistenceConfigurationKey_s);
+ }
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(size_written); DLT_STRING(">")) ;
+
+ return size_written;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+/* return size of key, or negative value in case of error */
+static sint_t GetKeySizeFromItzamLocalDB(sint_t dbHandler, pconststr_t key)
+{
+ bool_t bCanContinue = true ;
+ sint_t size_read = PERS_COM_FAILURE ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">> ...")) ;
+
+ if((dbHandler >= 0) && (NIL != key))
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ size_read = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_DB != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ size_read = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ size_read = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ KeyValuePair_LocalDB_s search;
+
+ if( itzam_btree_find( & pLldbHandler->btree, key, & search ) == itzam_true )
+ {
+ size_read = search.m_dataSize ;
+ }
+ else
+ {
+ size_read = PERS_COM_ERR_NOT_FOUND ;
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(size_read); DLT_STRING(">")) ;
+
+ return size_read;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+/* return no of bytes read, or negative value in case of error */
+static sint_t GetDataFromItzamLocalDB(sint_t dbHandler, pconststr_t key, pstr_t buffer_out, sint_t bufSize)
+{
+ bool_t bCanContinue = true ;
+ sint_t size_read = PERS_COM_FAILURE ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);;
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("bufsize=<<"); DLT_INT(bufSize); DLT_STRING(">> ... ")) ;
+
+ if( (dbHandler >= 0)
+ && (NIL != key)
+ && (NIL != buffer_out)
+ && (bufSize > 0) )
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ size_read = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_DB != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ size_read = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ size_read = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ KeyValuePair_LocalDB_s search;
+
+ if( itzam_btree_find( & pLldbHandler->btree, key, & search ) == itzam_true )
+ {
+ if( bufSize >= search.m_dataSize)
+ {
+ size_read = search.m_dataSize ;
+ (void)memcpy(buffer_out, search.m_data, (size_t)size_read) ;
+ }
+ else
+ {
+ size_read = PERS_COM_ERR_BUFFER_TOO_SMALL ;
+ }
+ }
+ else
+ {
+ size_read = PERS_COM_ERR_NOT_FOUND ;
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("bufsize=<<"); DLT_INT(bufSize); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(size_read); DLT_STRING(">")) ;
+
+ return size_read;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+static sint_t GetDataFromItzamRCT( sint_t dbHandler, pconststr_t key, PersistenceConfigurationKey_s* pConfig)
+{
+ bool_t bCanContinue = true ;
+ sint_t size_read = PERS_COM_FAILURE ;
+ lldb_handler_s* pLldbHandler = NIL ;
+ bool_t bLocked = false ;
+ str_t dbPathnameTemp[PERS_ORG_MAX_LENGTH_PATH_FILENAME] = "invalid path" ;
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">> ...")) ;
+
+ if( (dbHandler >= 0)
+ && (NIL != key)
+ && (NIL != pConfig) )
+ {
+ if(lldb_handles_Lock())
+ {
+ bLocked = true ;
+ pLldbHandler = lldb_handles_FindInUseHandle(dbHandler) ;
+ if(NIL == pLldbHandler)
+ {
+ bCanContinue = false ;
+ size_read = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(PersLldbPurpose_RCT != pLldbHandler->ePurpose)
+ {/* this would be very bad */
+ bCanContinue = false ;
+ size_read = PERS_COM_FAILURE ;
+ }
+ /* to not use DLT while mutex locked */
+ (void)strncpy(dbPathnameTemp, pLldbHandler->dbPathname, sizeof(dbPathnameTemp)) ;
+ }
+ }
+ }
+ else
+ {
+ bCanContinue = false ;
+ size_read = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(bCanContinue)
+ {
+ KeyValuePair_RCT_s search;
+
+ if(itzam_true == itzam_btree_find( & pLldbHandler->btree, key, & search ) )
+ {
+ (void)memcpy(pConfig, &(search.m_data), sizeof(PersistenceConfigurationKey_s) );
+ size_read = sizeof(PersistenceConfigurationKey_s);
+ }
+ else
+ {
+ size_read = PERS_COM_ERR_NOT_FOUND ;
+ }
+ }
+
+ if(bLocked)
+ {
+ (void)lldb_handles_Unlock() ;
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler="); DLT_INT(dbHandler);
+ DLT_STRING("<<"); DLT_STRING(dbPathnameTemp); DLT_STRING(">>, ");
+ DLT_STRING("key=<<"); DLT_STRING(key); DLT_STRING(">>, ");
+ DLT_STRING("retval=<"); DLT_INT(size_read); DLT_STRING(">")) ;
+
+ return size_read;
+}/*DG C7MR2R-ISQP Metric 10-SSW_PersCommon_0001*/
+
+static bool_t lldb_handles_Lock(void)
+{
+ bool_t bEverythingOK = true ;
+ sint_t siErr = pthread_mutex_lock(&g_mutexLldb) ;
+ if(0 != siErr)
+ {
+ bEverythingOK = false ;
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("pthread_mutex_lock failed with error=<"); DLT_INT(siErr); DLT_STRING(">")) ;
+ }
+
+ return bEverythingOK ;
+}
+
+static bool_t lldb_handles_Unlock(void)
+{
+ bool_t bEverythingOK = true ;
+ sint_t siErr = pthread_mutex_unlock (&g_mutexLldb) ;
+ if(0 != siErr)
+ {
+ bEverythingOK = false ;
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("pthread_mutex_unlock failed with error=<"); DLT_INT(siErr); DLT_STRING(">")) ;
+ }
+
+ return bEverythingOK ;
+}
+
+/* it is assumed dbHandler is checked by the caller */
+static lldb_handler_s* lldb_handles_FindInUseHandle(sint_t dbHandler)
+{
+ lldb_handler_s* pHandler = NIL ;
+
+ if(dbHandler <= PERS_LLDB_MAX_STATIC_HANDLES)
+ {
+ if(g_sHandlers.asStaticHandles[dbHandler].bIsAssigned)
+ {
+ pHandler = &g_sHandlers.asStaticHandles[dbHandler] ;
+ }
+ }
+ else
+ {
+ lldb_handles_list_el_s* pListElemCurrent = g_sHandlers.pListHead ;
+ while(NIL != pListElemCurrent)
+ {
+ if(dbHandler == pListElemCurrent->sHandle.dbHandler)
+ {
+ pHandler = &pListElemCurrent->sHandle;
+ break ;
+ }
+ pListElemCurrent = pListElemCurrent->pNext ;
+ }
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING((NIL!=pHandler) ? "Found handler <" : "ERROR can't find handler <"); DLT_INT(dbHandler); DLT_STRING(">");
+ DLT_STRING((NIL!=pHandler) ? (dbHandler <= PERS_LLDB_MAX_STATIC_HANDLES ? "in static area" : "in dynamic list") : "")) ;
+
+ return pHandler ;
+}
+
+static lldb_handler_s* lldb_handles_FindAvailableHandle(void)
+{
+ bool_t bCanContinue = true ;
+ lldb_handler_s* pHandler = NIL ;
+ lldb_handles_list_el_s* psListElemNew = NIL ;
+
+ /* first try to find an available handle in the static area */
+ sint_t siIndex = 0 ;
+ for(siIndex = 0 ; siIndex <= PERS_LLDB_MAX_STATIC_HANDLES ; siIndex++)
+ {
+ if( ! g_sHandlers.asStaticHandles[siIndex].bIsAssigned)
+ {
+ /* index setting should be done only once at the initialization of the static array
+ * Anyway, doing it here is more consistent */
+ g_sHandlers.asStaticHandles[siIndex].dbHandler = siIndex ;
+ pHandler = &g_sHandlers.asStaticHandles[siIndex] ;
+ break ;
+ }
+ }
+
+ if(NIL == pHandler)
+ {
+ /* no position available in the static array => we have to use the list
+ * allocate memory for the new element and process the situation when the list is headless */
+
+ psListElemNew = (lldb_handles_list_el_s*)malloc(sizeof(lldb_handles_list_el_s)) ; /*DG C7MR2R-MISRA-C:2004 Rule 20.4-SSW_PersCommon_1010*/
+ if(NIL == psListElemNew)
+ {
+ bCanContinue = false ;
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("malloc failed")) ;
+ }
+ else
+ {
+ if(NIL == g_sHandlers.pListHead)
+ {
+ /* the list not yet used/created, so use the new created element as the head */
+ g_sHandlers.pListHead = psListElemNew ;
+ g_sHandlers.pListHead->pNext = NIL ;
+ g_sHandlers.pListHead->sHandle.dbHandler = PERS_LLDB_MAX_STATIC_HANDLES + 1 ;
+ /* the rest of the members will be set by lldb_handles_InitHandle */
+ pHandler = &psListElemNew->sHandle;
+ }
+ }
+ }
+
+ if((NIL == pHandler) && bCanContinue)
+ {
+ /* no position available in the static array => we have to use the list
+ * the memory for psListElemNew has been allocated and the list has a head
+ * The new element has to get the smallest index
+ * Now lets consider the situation when the head of the list has an index higher than (PERS_LLDB_MAX_STATIC_HANDLES + 1)
+ * => the list will have a new head !!! */
+ if(g_sHandlers.pListHead->sHandle.dbHandler > (PERS_LLDB_MAX_STATIC_HANDLES + 1))
+ {
+ psListElemNew->pNext = g_sHandlers.pListHead ;
+ psListElemNew->sHandle.dbHandler = PERS_LLDB_MAX_STATIC_HANDLES + 1 ;
+ /* the rest of the members will be set by lldb_handles_InitHandle */
+ g_sHandlers.pListHead = psListElemNew ;
+ pHandler = &psListElemNew->sHandle;
+ }
+ }
+
+ if((NIL == pHandler) && bCanContinue)
+ {
+ /* no position available in the static array => we have to use the list
+ * the memory for psListElemNew has been allocated and the list has a head (with the smallest index)
+ * The new element has to get the smallest available index
+ * So will search for the first gap between two consecutive elements of the list and will introduce the new element between */
+ lldb_handles_list_el_s* pListElemCurrent1 = g_sHandlers.pListHead ;
+ lldb_handles_list_el_s* pListElemCurrent2 = pListElemCurrent1->pNext;
+ while(NIL != pListElemCurrent2)
+ {
+ if(pListElemCurrent2->sHandle.dbHandler - pListElemCurrent1->sHandle.dbHandler > 1)
+ {
+ /* found a gap => insert the element between and use the index next to pListElemCurrent1's */
+ psListElemNew->pNext = pListElemCurrent2 ;
+ psListElemNew->sHandle.dbHandler = pListElemCurrent1->sHandle.dbHandler + 1 ;
+ pListElemCurrent1->pNext = psListElemNew ;
+ pHandler = &psListElemNew->sHandle;
+ break ;
+ }
+ else
+ {
+ pListElemCurrent1 = pListElemCurrent2 ;
+ pListElemCurrent2 = pListElemCurrent2->pNext ;
+ }
+ }
+ if(NIL == pListElemCurrent2)
+ {
+ /* reached the end of the list => the list will have a new end */
+ psListElemNew->pNext = NIL ;
+ psListElemNew->sHandle.dbHandler = pListElemCurrent1->sHandle.dbHandler + 1 ;
+ pListElemCurrent1->pNext = psListElemNew ;
+ pHandler = &psListElemNew->sHandle;
+ }
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING((NIL!=pHandler) ? "Found availble handler <" : "ERROR can't find available handler <");
+ DLT_INT((NIL!=pHandler) ? pHandler->dbHandler : (-1)); DLT_STRING(">");
+ DLT_STRING((NIL!=pHandler) ? (pHandler->dbHandler <= PERS_LLDB_MAX_STATIC_HANDLES ? "in static area" : "in dynamic list") : "") ) ;
+
+ return pHandler ;
+}/*DG C7MR2R-ISQP Metric 6-SSW_PersCommon_1011*/
+
+static void lldb_handles_InitHandle(lldb_handler_s* psHandle_inout, pers_lldb_purpose_e ePurpose, str_t const * dbPathname)
+{
+ psHandle_inout->bIsAssigned = true ;
+ psHandle_inout->ePurpose = ePurpose ;
+ (void)strncpy(psHandle_inout->dbPathname, dbPathname, sizeof(psHandle_inout->dbPathname)) ;
+}
+
+static bool_t lldb_handles_DeinitHandle(sint_t dbHandler)
+{
+ bool_t bEverythingOK = true ;
+ bool_t bHandlerFound = false ;
+
+
+ if(dbHandler <= PERS_LLDB_MAX_STATIC_HANDLES)
+ {
+ bHandlerFound = true ;
+ g_sHandlers.asStaticHandles[dbHandler].bIsAssigned = false ;
+ }
+ else
+ {
+ /* consider the situation when the handle is the head of the list */
+ if(NIL != g_sHandlers.pListHead)
+ {
+ if(dbHandler == g_sHandlers.pListHead->sHandle.dbHandler)
+ {
+ lldb_handles_list_el_s* pListElemTemp = NIL ;
+
+ bHandlerFound = true ;
+ pListElemTemp = g_sHandlers.pListHead ;
+ g_sHandlers.pListHead = g_sHandlers.pListHead->pNext ;
+ free(pListElemTemp) ; /*DG C7MR2R-MISRA-C:2004 Rule 20.4-SSW_PersCommon_1012*/
+ }
+ }
+ else
+ {
+ bEverythingOK = false ;
+ }
+ }
+
+ if(bEverythingOK && ( ! bHandlerFound))
+ {
+ /* consider the situation when the handle is in the list (but not the head) */
+ lldb_handles_list_el_s* pListElemCurrent1 = g_sHandlers.pListHead ;
+ lldb_handles_list_el_s* pListElemCurrent2 = pListElemCurrent1->pNext;
+ while(NIL != pListElemCurrent2)
+ {
+ if(dbHandler == pListElemCurrent2->sHandle.dbHandler)
+ {
+ /* found the handle */
+ bHandlerFound = true ;
+ pListElemCurrent1->pNext = pListElemCurrent2->pNext ;
+ free(pListElemCurrent2) ; /*DG C7MR2R-MISRA-C:2004 Rule 20.4-SSW_PersCommon_1013*/
+ break ;
+ }
+ else
+ {
+ pListElemCurrent1 = pListElemCurrent2 ;
+ pListElemCurrent2 = pListElemCurrent2->pNext ;
+ }
+ }
+ if(NIL == pListElemCurrent2)
+ {
+ /* reached the end of the list without finding the handle */
+ bEverythingOK = false ;
+ }
+ }
+
+ DLT_LOG(persComLldbDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); DLT_STRING(__FUNCTION__); DLT_STRING(":");
+ DLT_STRING("dbHandler=<"); DLT_INT(dbHandler); DLT_STRING("> ");
+ DLT_STRING(bEverythingOK ? (dbHandler <= PERS_LLDB_MAX_STATIC_HANDLES ? "deinit handler in static area" : "deinit handler in dynamic list") : "ERROR - handler not found") ) ;
+
+ return bEverythingOK ;
+}
diff --git a/src/pers_resource_config_table.c b/src/pers_resource_config_table.c
new file mode 100644
index 0000000..5f5cc65
--- /dev/null
+++ b/src/pers_resource_config_table.c
@@ -0,0 +1,247 @@
+/**********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Implementation of persComRct.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.02.05 uidl9757 CSP_WZ#2220: Adaptation for open source
+* 2012.12.10 uidl9757 CSP_WZ#2060: Created
+*
+**********************************************************************************************************************/
+
+#include "persComTypes.h"
+#include "string.h"
+
+#include "persComErrors.h"
+#include "persComDataOrg.h"
+#include "pers_low_level_db_access_if.h"
+#include "persComRct.h"
+
+/**
+ * \brief Obtain a handler to RCT indicated by rctPathname
+ * \note : RCT is created if it does not exist and (bForceCreationIfNotPresent != 0)
+ *
+ * \param rctPathname [in] absolute path to RCT (length limited to \ref PERS_ORG_MAX_LENGTH_PATH_FILENAME)
+ * \param bForceCreationIfNotPresent [in] if !=0x0, the RCT is created if it does not exist
+ *
+ * \return >= 0 for valid handler, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctOpen(char const * rctPathname, unsigned char bForceCreationIfNotPresent)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if(NIL != rctPathname)
+ {
+ if(strlen(rctPathname) >= PERS_ORG_MAX_LENGTH_PATH_FILENAME)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+ else
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_open(rctPathname, PersLldbPurpose_RCT, bForceCreationIfNotPresent);
+ }
+
+ return iErrCode ;
+}
+
+/**
+ * \brief Close handler to RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctClose(signed int handlerRCT)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if(handlerRCT < 0)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_close(handlerRCT) ;
+ }
+
+ return iErrCode ;
+}
+
+/**
+ * \brief write a resourceID-value pair into RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param resourceID [in] resource's identifier (length limited to \ref PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ * \param psConfig [in] configuration for resourceID
+ *
+ * \return 0 for success, negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctWrite(signed int handlerRCT, char const * resourceID, PersistenceConfigurationKey_s const * psConfig)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerRCT < 0)
+ || (NIL == resourceID)
+ || (NIL == psConfig)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(resourceID) >= PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_write_key(handlerRCT, PersLldbPurpose_RCT, resourceID, (pstr_t)psConfig, sizeof(PersistenceConfigurationKey_s)) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief read a resourceID's configuration from RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param resourceID [in] resource's identifier (length limited to \ref PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ * \param psConfig_out [out]where to return the configuration for resourceID
+ *
+ * \return read size [byte], or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctRead(signed int handlerRCT, char const * resourceID, PersistenceConfigurationKey_s const * psConfig_out)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerRCT < 0)
+ || (NIL == resourceID)
+ || (NIL == psConfig_out)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(resourceID) >= PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_read_key(handlerRCT, PersLldbPurpose_RCT, resourceID, (pstr_t)psConfig_out, sizeof(PersistenceConfigurationKey_s)) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief delete a resourceID's configuration from RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param resourceID [in] resource's identifier (length limited to \ref PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ *
+ * \return 0 for success, or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctDelete(signed int handlerRCT, char const * resourceID)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerRCT < 0)
+ || (NIL == resourceID)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ else
+ {
+ if(strlen(resourceID) >= PERS_RCT_MAX_LENGTH_RESOURCE_ID)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_delete_key(handlerRCT, PersLldbPurpose_RCT, resourceID) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief Find the buffer's size needed to accomodate the listing of resourceIDs in RCT
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ *
+ * \return needed size [byte], or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctGetSizeResourcesList(signed int handlerRCT)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if(handlerRCT < 0)
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_get_size_keys_list(handlerRCT, PersLldbPurpose_RCT) ;
+ }
+
+ return iErrCode ;
+}
+
+
+/**
+ * \brief Get the list of the resourceIDs in RCT
+ * \note : resourceIDs in the list are separated by '\0'
+ *
+ * \param handlerRCT [in] handler obtained with persComRctOpen
+ * \param listBuffer_out [out]buffer where to return the list of resourceIDs
+ * \param listBufferSize [in] size of listBuffer_out
+ *
+ * \return list size [byte], or negative value for error (\ref PERS_COM_ERROR_CODES_DEFINES)
+ */
+signed int persComRctGetResourcesList(signed int handlerRCT, char* listBuffer_out, signed int listBufferSize)
+{
+ sint_t iErrCode = PERS_COM_SUCCESS ;
+
+ if( (handlerRCT < 0)
+ || (NIL == listBuffer_out)
+ || (listBufferSize <= 0)
+ )
+ {
+ iErrCode = PERS_COM_ERR_INVALID_PARAM ;
+ }
+
+ if(PERS_COM_SUCCESS == iErrCode)
+ {
+ iErrCode = pers_lldb_get_keys_list(handlerRCT, PersLldbPurpose_RCT, (pstr_t)listBuffer_out, listBufferSize) ;
+ }
+
+ return iErrCode ;
+}
+