From 880e7ffe185e5b410ee6183c4ce355a8a204ab28 Mon Sep 17 00:00:00 2001 From: Guy Sagnes Date: Tue, 25 Feb 2014 10:32:29 +0100 Subject: 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 --- AUTHORS | 3 + COPYING | 373 +++++ ChangeLog | 0 INSTALL | 370 +++++ Makefile.am | 19 + NEWS | 3 + autogen.sh | 19 + configure.ac | 118 ++ dbus_config/org.genivi.persistence.admin.conf | 16 + .../org.genivi.persistence.admin.xml | 46 + .../org.genivi.persistence.admin_generate.txt | 1 + generated/Makefile.am | 29 + inc/private/pers_ipc_dbus_if.h | 127 ++ inc/private/pers_low_level_db_access_if.h | 157 ++ inc/protected/persComDataOrg.h | 265 ++++ inc/protected/persComDbAccess.h | 154 ++ inc/protected/persComErrors.h | 69 + inc/protected/persComIpc.h | 309 ++++ inc/protected/persComRct.h | 226 +++ inc/protected/persComTypes.h | 213 +++ pkgconfig/libperscommon.pc.in | 11 + src/Makefile.am | 70 + src/pers_data_organization.c | 101 ++ src/pers_ipc.c | 316 ++++ src/pers_ipc_dbus.c | 1590 ++++++++++++++++++++ src/pers_local_shared_db_access.c | 287 ++++ src/pers_low_level_db_access.c | 1515 +++++++++++++++++++ src/pers_resource_config_table.c | 247 +++ 28 files changed, 6654 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 autogen.sh create mode 100644 configure.ac create mode 100644 dbus_config/org.genivi.persistence.admin.conf create mode 100644 dbus_specifications/org.genivi.persistence.admin.xml create mode 100644 dbus_specifications/org.genivi.persistence.admin_generate.txt create mode 100644 generated/Makefile.am create mode 100644 inc/private/pers_ipc_dbus_if.h create mode 100644 inc/private/pers_low_level_db_access_if.h create mode 100644 inc/protected/persComDataOrg.h create mode 100644 inc/protected/persComDbAccess.h create mode 100644 inc/protected/persComErrors.h create mode 100644 inc/protected/persComIpc.h create mode 100644 inc/protected/persComRct.h create mode 100644 inc/protected/persComTypes.h create mode 100644 pkgconfig/libperscommon.pc.in create mode 100644 src/Makefile.am create mode 100644 src/pers_data_organization.c create mode 100644 src/pers_ipc.c create mode 100644 src/pers_ipc_dbus.c create mode 100644 src/pers_local_shared_db_access.c create mode 100644 src/pers_low_level_db_access.c create mode 100644 src/pers_resource_config_table.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..a776944 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Ionut Ieremie +Guy Sagnes +Petrica Manoila diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..14e2f77 --- /dev/null +++ b/COPYING @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..a1e89e1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..b18571e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,19 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Ana.Chisca@continental-corporation.com +# +# Makefile template for the persistence common library +# +# Process this file with automake to produce a Makefile.in. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +####################################################################################################################### + +# Build trough subfolders. Make sure "generated" is called before "src". +ACLOCAL_AMFLAGS=-I m4 +SUBDIRS = generated src diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e7f671b --- /dev/null +++ b/NEWS @@ -0,0 +1,3 @@ +1.0.1 +===== +* Initial release of the persistence common interface diff --git a/autogen.sh b/autogen.sh new file mode 100644 index 0000000..daeaa51 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e +# +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Ana.Chisca@continental-corporation.com +# +# Script to create necessary files/folders from a fresh git check out. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +############################################################################### + +mkdir -p m4 + +autoreconf --verbose --install --force +./configure $@ \ No newline at end of file diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f9a62e8 --- /dev/null +++ b/configure.ac @@ -0,0 +1,118 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Ana.Chisca@continental-corporation.com +# +# Configure template for the persistence-common library +# +# Process this file with autoconf to produce a configure script. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +####################################################################################################################### + +dnl ************************************************************************** +dnl *** First, define all of the version numbers up front *** +dnl *** In particular, this allows the version macro to be used in AC_INIT *** +dnl ************************************************************************** +m4_define([LIBPERSOCOMMON_VERSION_S],[1.0.1]) +m4_define([LIBPERSOCOMMON_VERSION_N],[1000001]) + +dnl *************************** +dnl *** Initialize autoconf *** +dnl *************************** +AC_INIT([persistence-common],[LIBPERSOCOMMON_VERSION_S()]) +AC_COPYRIGHT([Copyright (c) 2012 Continental Automotive GmbH]) +AC_PREREQ([2.50]) + +dnl *************************** +dnl *** Initialize automake *** +dnl *************************** +AM_INIT_AUTOMAKE() +AC_USE_SYSTEM_EXTENSIONS() +AC_CONFIG_MACRO_DIR([m4]) +AC_SUBST([ACLOCAL_AMFLAGS], ["$ACLOCAL_FLAGS -I m4"]) + +dnl ********************************* +dnl *** Shared library versioning *** +dnl ********************************* +PERSCOMMON_MAJOR=$((((LIBPERSOCOMMON_VERSION_N() / 1000) / 1000) % 1000 )) +PERSCOMMON_MINOR=$(( (LIBPERSOCOMMON_VERSION_N() / 1000) % 1000 )) +PERSCOMMON_MICRO=$(( LIBPERSOCOMMON_VERSION_N() % 1000 )) +GENERIC_LIBRARY_VERSION=$PERSCOMMON_MAJOR:$PERSCOMMON_MINOR:$PERSCOMMON_MICRO +AC_SUBST(GENERIC_LIBRARY_VERSION) + +dnl ******************************** +dnl *** Check for basic programs *** +dnl ******************************** +AC_PROG_CC() +AM_PROG_CC_C_O() +AC_PROG_CXX() +AC_PROG_INSTALL() + +dnl *************************** +dnl *** Initialize lib tool *** +dnl *************************** +AC_DISABLE_STATIC() +AC_PROG_LIBTOOL() + +dnl *************************************** +dnl *** Check for standard header files *** +dnl *************************************** +AC_CHECK_HEADERS([string.h]) + +dnl *********************************** +dnl *** Check for library functions *** +dnl *********************************** +AC_FUNC_STRNLEN +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memcpy]) +AC_CHECK_FUNCS([memset]) + +dnl ******************************************************************** +dnl *** Check for typedefs, structures, and compiler characteristics *** +dnl ******************************************************************** +AC_HEADER_STDBOOL +AC_TYPE_SIZE_T +AC_TYPE_UINT8_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T + +dnl *********************************** +dnl *** Check for required packages *** +dnl *********************************** +PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.30.0]) +PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.30.0]) +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30.0]) +PKG_CHECK_MODULES([DLT], [automotive-dlt >= 2.2.0]) +PKG_CHECK_MODULES([ITZAM], [libitzam >= 6.0.4]) +ITZAM_LIBS="-litzam" + +dnl ************************************* +dnl *** Define extra paths *** +dnl ************************************* +AC_ARG_WITH([dbuspolicydir], + AS_HELP_STRING([--with-dbuspolicydirdir=DIR], [Directory for D-Bus system policy files]), + [], + [with_dbuspolicydir=$(pkg-config --silence-errors --variable=sysconfdir dbus-1)/dbus-1/system.d]) +AC_SUBST([dbuspolicydir], [$with_dbuspolicydir]) + +# Derive path for storing 'dbus' interface files (e. g. /usr/share/dbus-1/interfaces) +AC_ARG_WITH([dbusinterfacesdir], + AS_HELP_STRING([--with-dbusinterfacesdir=DIR], [Directory for D-Bus interface files]), + [], + [with_dbusinterfacesdir=$(pkg-config --silence-errors --variable=interfaces_dir dbus-1)]) +AC_SUBST([dbusinterfacesdir], [$with_dbusinterfacesdir]) + +dnl ******************************* +dnl *** Define configure output *** +dnl ******************************* +AC_CONFIG_FILES(Makefile src/Makefile generated/Makefile pkgconfig/libperscommon.pc) + +AC_OUTPUT + + diff --git a/dbus_config/org.genivi.persistence.admin.conf b/dbus_config/org.genivi.persistence.admin.conf new file mode 100644 index 0000000..fac05f9 --- /dev/null +++ b/dbus_config/org.genivi.persistence.admin.conf @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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/\/\ */ +#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/\/\ */ +#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/\/\ */ +#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/\/\ */ +#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/\/\ */ +#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/\/\ */ +#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/\ */ +#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/\ */ +#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 + +#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 /* 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// */ +const char* gLocalCachePath = PERS_ORG_LOCAL_CACHE_PATH_FORMAT ; + +/* path prefix for local write through database /Data/mnt-wt// */ +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// */ +const char* gSharedCachePath = PERS_ORG_SHARED_CACHE_PATH_FORMAT ; + +/* path prefix for shared cached database: /Data/mnt-c/shared/group// */ +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// */ +const char* gSharedWtPath = PERS_ORG_SHARED_WT_PATH_FORMAT ; + +/* path prefix for shared write through database: /Data/mnt-wt/shared/group// */ +const char* gSharedWtPathString = PERS_ORG_SHARED_WT_PATH_STRING_FORMAT ; + +/* path prefix for shared public cached database: /Data/mnt-c/shared/public/ */ +const char* gSharedPublicCachePath = PERS_ORG_SHARED_PUBLIC_CACHE_PATH_FORMAT ; + +/* path prefix for shared public write through database: /Data/mnt-wt/shared/public/ */ +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 +#include +#include +#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 +#include +#include +#include +#include + +#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 +#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 +#include /*DG C7MR2R-MISRA-C:2004 Rule 20.9-SSW_PersCommon_1003*/ +#include +#include +#include +#include +#include + +#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 ; +} + -- cgit v1.2.1