1 /** @copyright
2   * Copyright (c) 2015, Intel Corporation
3   * All rights reserved.
4   *
5   * Redistribution and use in source and binary forms, with or without modification,
6   * are permitted provided that the following conditions are met:
7   *
8   * 1. Redistributions of source code must retain the above copyright notice, this
9   * list of conditions and the following disclaimer.
10   *
11   * 2. Redistributions in binary form must reproduce the above copyright notice,
12   * this list of conditions and the following disclaimer in the documentation and/or
13   * other materials provided with the distribution.
14   *
15   * 3. Neither the name of the copyright holder nor the names of its contributors
16   * may be used to endorse or promote products derived from this software without
17   * specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30 
31 /** @file Simplified parameter framework C API.
32   *       This API does not target a perfect one/one mapping with the c++ one,
33   *       but rather aim ease of use and type safety (as far as possible in c).
34   *       All function are reentrant and function call on a pfw (PfwHandle)
35   *       does not impact any other pfw.
36   *       Ie. There is no shared resources between pfw instances.
37   */
38 
39 #pragma once
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 #include <stdbool.h>
46 #include <stdint.h>
47 #include <stddef.h>
48 
49 /** Lots of function in this API require non null pointer parameter.
50   * Such arguments are marked NONNULL.
51   */
52 #define NONNULL  __attribute__((nonnull))
53 #define NONNULL_(...)  __attribute__((nonnull (__VA_ARGS__)))
54 #define USERESULT __attribute__((warn_unused_result))
55 
56 /** Private handle to a parameter framework.
57   * A PfwHandler* is valid if:
58   *  - it was created by pfwCreate
59   *  - it has not been destroyed by pfwDestroyParameter
60   *  - is not NULL
61   * A valid handle MUST be provided to all pfw related method.
62   * A valid handler MUST be destroyed with pfwDestroy before programme
63   * termination.
64   * @note Forward declaration to break header dependency.
65  */
66 struct PfwHandler_;
67 /** Typedef for use ease. @see PfwHandler_. */
68 typedef struct PfwHandler_ PfwHandler;
69 
70 ///////////////////////////////
71 ///////////// Log /////////////
72 ///////////////////////////////
73 /** Pfw log level for the callback. */
74 typedef enum {
75     pfwLogInfo = 55, //< Random value to avoid unfortunate mismatch.
76     pfwLogWarning
77 } PfwLogLevel;
78 
79 /** Type of the parameter framework log callback.
80   * @param userCtx[in] Arbitrary context provided during callback registration.
81   * @param level[in] Log level of the log line.
82   * @param logLine[in] Log line (without end line control character like '\n')
83   *                    to be logged. The pointer is invalidate after function
84   *                    return or if any pfw function is called.
85   */
86 typedef void PfwLogCb(void *userCtx, PfwLogLevel level, const char *logLine);
87 
88 /** Logger containing a callback method and its context. */
89 typedef struct {
90     /** User defined arbitrary value that will be provided to all logCb call. */
91     void *userCtx;
92     /** Callback that will be called.
93       * If NULL nothing will be logged.
94       */
95     PfwLogCb *logCb;
96 } PfwLogger;
97 
98 ///////////////////////////////
99 ///////////// Core ////////////
100 ///////////////////////////////
101 
102 /** Structure of a parameter framework criterion. */
103 typedef struct {
104     /** Name of the criterion in the pfw configuration rules. */
105     const char *name; //< Must not be null.
106     bool inclusive; //< True if the criterion is inclusive, false if exclusive.
107     /** Null terminated list of criterion value names.
108       * @example { "Red", "Green", "Blue", NULL }
109       *
110       * For an exclusive criterion, the list must not contain more elements then
111       *                             INT_MAX.
112       * For an inclusive criterion, the list must not contain more elements then
113       *                             sizeof(int) * BIT_CHAR - 1.
114       *                             Ie: (int)1 << n must *not* overflow (UB),
115       *                                 were n is the number of element in the
116       *                                 list. @see pfwSetCriterion
117       */
118     const char **values; //< Must not be null.
119 } PfwCriterion;
120 
121 
122 /** Create a parameter framework instance.
123   * Can not fail except for memory allocation.
124   */
125 PfwHandler *pfwCreate() USERESULT;
126 
127 /** Destroy a parameter framework. Can not fail. */
128 void pfwDestroy(PfwHandler *handle) NONNULL;
129 
130 /** Start a parameter framework.
131   * @param handle[in] @see PfwHandler
132   * @param configPath[in] Path to the file containing the pfw configuration.
133   * @param criteria[in] An array of PfwCriterion.
134   * @param criterionNb[in] The number of PfwCriterion in criteria.
135   * @param logger[in] the logger to use for all operation.
136   *                   If NULL, log infos to standard output and
137   *                                errors to standard error.
138   * @return true on success, false on failure.
139   */
140 bool pfwStart(PfwHandler *handle, const char *configPath,
141               const PfwCriterion criteria[], size_t criterionNb,
142               const PfwLogger *loggger) NONNULL_(1, 2, 3) USERESULT;
143 
144 /** @return a string describing the last call result.
145   * If the last pfw function call succeeded, return an empty string.
146   * If the last pfw function call failed, return a message explaining the error cause.
147   * The return pointer is invalidated if any pfw method is called on the SAME
148   * PfwHandle.
149   *
150   * Each PfwHandle own it's last error message. It is not static nor TLS.
151   * As a result, calling a pfw function with a NULL PfwHandler will result in a
152   * failure WITHOUT updating the last error.
153   */
154 const char *pfwGetLastError(const PfwHandler *handle) NONNULL;
155 
156 /** Set a criterion value given its name and value.
157   * @param handle[in] @see PfwHandler
158   * @param name[in] The name of the criterion that need to be changed.
159   * @param value If the criterion is exclusive, the index of the new value.
160   *              If the criterion is inclusive, a bit field where each bit
161   *              correspond to the value index.
162   * For an inclusive criterion defined as such: { "Red", "Green", "Blue", NULL }
163   * to set the value Green and Blue, value has to be 1<<1 | 1<<2 = 0b110 = 6.
164   * For an exclusive criterion defined as such: { "Car", "Boat", "Plane", NULL }
165   * to set the value Plane, value has to be 2.
166   *
167   * Criterion change do not have impact on the parameters value
168   * (no configuration applied) until the changes are committed using pfwApplyConfigurations.
169   *
170   * @return true on success and false on failure.
171   */
172 bool pfwSetCriterion(PfwHandler *handle, const char name[], int value) NONNULL USERESULT;
173 /** Get a criterion value given its name.
174   * Same usage as pfwSetCriterion except that value is an out param.
175   * Get criterion will return the last value setted with pfwSetCriterion independantly of pfwCommitCritenio.
176   */
177 bool pfwGetCriterion(const PfwHandler *handle, const char name[], int *value) NONNULL USERESULT;
178 
179 /** Commit criteria change and change parameters according to the configurations.
180   * Criterion do not have impact on the parameters value when changed,
181   * instead they are staged and only feed to the rule engine
182   * (who then impact parameter values according to the configuration) when
183   * committed with this function.
184   *
185   * @param handle[in] @see PfwHandler
186   * @return true on success and false on failure.
187   */
188 bool pfwApplyConfigurations(const PfwHandler *handle) NONNULL USERESULT;
189 
190 ///////////////////////////////
191 /////// Parameter access //////
192 ///////////////////////////////
193 
194 /** Handler to a pfw parameter.
195   * A PfwParameterHandler* is valid if:
196   *  - it was created by pfwBindParameter
197   *  - it has not been destroyed by pfwDestroyParameter
198   *  - is not NULL
199   *  - the pfwHandle used to created is still valid (ie. it must not outlive
200   *    its parent pfw)
201   * A valid handle MUST be provided to all pfw parameter related method.
202   * Any created handle MUST be destroyed (with pfwDestroyParameter) before
203   * the PfwHandler that was used for its creation.
204   * @note Forward declaration to break header dependency.
205   */
206 struct PfwParameterHandler_;
207 typedef struct PfwParameterHandler_ PfwParameterHandler;
208 
209 /** Construct the handle to a parameter given its path.
210   * The PfwHandle MUST stay valid until PfwParameterHandler destruction.
211   * @return a PfwParameterHandler on success, NULL on error.
212   *         @see pfwGetLastError for error detail.
213   */
214 PfwParameterHandler *pfwBindParameter(PfwHandler *handle, const char path[]) NONNULL;
215 /** Destroy a parameter handle. Can not fail. */
216 void pfwUnbindParameter(PfwParameterHandler *handle) NONNULL;
217 
218 /** Access the value of a previously bind int parameter.
219   * @param handle[in] Handler to a valid parameter.
220   * @param value[in] Non null pointer to an integer that will
221   *        hold the parameter value on success, undefined otherwise.
222   * return true of success, false on failure.
223   */
224 bool pfwGetIntParameter(const PfwParameterHandler *handle, int32_t *value ) NONNULL USERESULT;
225 
226 /** Set the value of a previously bind int parameter.
227   * @param handle[in] Handler to a valid parameter.
228   * @param value[in] The parameter value to set.
229   * return true of success, false on failure.
230   */
231 bool pfwSetIntParameter(PfwParameterHandler *handle, int32_t value) NONNULL USERESULT;
232 
233 /** Access the value of a previously bind string parameter.
234   * @param handle[in] Handler to a valid parameter.
235   * @param value[out] Non null pointer on a string.
236   *                   Will point on the parameter value string on success,
237   *                   NULL on failure.
238   *                   The callee MUST free the returned string using pfwFree after use.
239   * @return true on success, false on failure.
240   */
241 bool pfwGetStringParameter(const PfwParameterHandler *handle, const char *value[]) NONNULL;
242 
243 /** Set the value of a previously bind string parameter.
244   * @param handle[in] Handler to a valid parameter
245   * @param value[in] Non null pointer to a null terminated string to set.
246   */
247 bool pfwSetStringParameter(PfwParameterHandler *handle, const char value[]) NONNULL USERESULT;
248 
249 /** Frees the memory space pointed to by ptr,
250   *  which must have been returned by a previous call to the pfw.
251   *
252   * @param ptr[in] pointer to the memory to free.
253   * @see man 3 free for usage.
254   * @note Wrapper around the standard free to avoid problems
255   *       in case of a different pfw and client allocator.
256   */
257 void pfwFree(void *ptr);
258 
259 #undef NONNULL
260 #undef NONNULL_
261 #undef USERESULT
262 
263 #ifdef __cplusplus
264 }
265 #endif
266