diff options
author | Guy Sagnes <guy.sagnes@continental-corporation.com> | 2014-02-25 10:32:29 +0100 |
---|---|---|
committer | Ralf Anton Beier <ralf.anton.beier@continental-corporation.com> | 2014-02-25 11:33:41 +0100 |
commit | 880e7ffe185e5b410ee6183c4ce355a8a204ab28 (patch) | |
tree | 9c18d6aecfaf69a6753b4c2f251583cfe9f3722e | |
parent | 94b07e2221c3333a5a54f689eca4249667892f74 (diff) | |
download | persistence-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>
28 files changed, 6654 insertions, 0 deletions
@@ -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> @@ -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 @@ -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 @@ -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 ;
+}
+
|