libamxd  6.4.1
Data Model Manager
amxd_action_object_add_inst.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 
55 #ifndef _GNU_SOURCE
56 #define _GNU_SOURCE
57 #endif
58 
59 #include <stdlib.h>
60 #include <string.h>
61 
62 #include "amxd_priv.h"
63 
64 #include <amxd/amxd_dm.h>
65 #include <amxd/amxd_action.h>
66 #include <amxd/amxd_object.h>
68 
69 #include "amxd_priv.h"
70 #include "amxd_object_priv.h"
71 #include "amxd_assert.h"
72 
74  amxc_var_t* retval) {
75  uint32_t index = amxd_object_get_index(instance);
76  const char* name = amxd_object_get_name(instance, AMXD_OBJECT_NAMED);
79  amxc_var_t* parameters = NULL;
80  const amxc_htable_t* ht_parameters = NULL;
81 
82  /* build the return value of the add instance action
83  the return value is a variant containing a htable
84  the variant contains this structure:
85  {
86  index : <the new index>,
87  name : <the new name>,
88  path : <the full absolute path with indeces>
89  object : <the full absolute path with names>,
90  parameters : <a hash table containig all key parameters and the values>
91  {
92  <KEY_PARAM1> : <KEY_PARAM1_VALUE>,
93  <KEY_PARAM2> : <KEY_PARAM2_VALUE>,
94  ...
95  <KEY_PARAMn> : <KEY_PARAMn_VALUE>
96  }
97  }
98  */
99  amxc_var_set_type(retval, AMXC_VAR_ID_HTABLE);
100  amxc_var_add_key(uint32_t, retval, "index", index);
101  amxc_var_add_key(cstring_t, retval, "name", name);
102  amxc_var_add_key(cstring_t, retval, "path", path);
103  amxc_var_add_key(cstring_t, retval, "object", object);
104  parameters = amxc_var_add_key(amxc_htable_t, retval, "parameters", NULL);
105 
106  /* Fetch the description of all parameters in the object and filter out
107  the key parameters.
108 
109  The parameters variant (which is an htable) will contain all parameters
110  after the call to amxd_object_describe_params.
111  Each element will have as the key the name of the parameter and the value
112  is a hash table containing all meta data of the parameter, including the
113  attributes.
114 
115  The returned description for each parameter has this format
116  <PARAM_NAME> :
117  {
118  attributes :
119  {
120  instance : <true or false>,
121  read-only : <true or false>,
122  volatile : <true or false>,
123  counter : <true or false>,
124  unique : <true or false>,
125  private : <true or false>,
126  template : <true or false>,
127  protected : <true or false>,
128  key : <true or false>,
129  persistent : <true or false>
130  },
131  value : <PARAM_VALUE>,
132  name : <PARAM_NAME>,
133  type_name : <PARAM_TYPE_NAME>,
134  type_id : <PARAM_TYPE_ID>
135  }
136  All parameters for which the "key" attribute is not set are deleted from
137  the parameters hash table (using amxc_var_delete)
138 
139  All parameters for which the "key" attribute is set are updated.
140  - the value of the parameter is taken from the description (field value)
141  - the value of the parameter is updated (this will remove the description)
142  */
144  ht_parameters = amxc_var_constcast(amxc_htable_t, parameters);
145  amxc_htable_for_each(it, ht_parameters) {
146  const char* param_name = amxc_htable_it_get_key(it);
147  amxc_var_t* param_description = amxc_var_from_htable_it(it);
148  bool is_key = GETP_BOOL(param_description, "attributes.key");
149  if(is_key) {
150  amxc_var_t* param_value = amxc_var_take_key(param_description, "value");
151  amxc_var_set_key(parameters, param_name, param_value, AMXC_VAR_FLAG_UPDATE);
152  } else {
153  amxc_var_delete(&param_description);
154  }
155  }
156  free(path);
157  free(object);
158 }
159 
162 
163  amxd_object_for_each(parameter, it, instance) {
164  amxd_param_t* param = amxc_container_of(it, amxd_param_t, it);
166  amxc_var_t value;
167  amxc_var_init(&value);
168  amxd_param_get_value(param, &value);
169  status = amxd_param_validate(param, &value);
170  amxc_var_clean(&value);
171  when_failed(status, exit);
172  }
173  }
174 
175 exit:
176  return status;
177 }
178 
180  const char* name,
181  uint32_t index,
182  amxc_var_t* params,
183  amxd_dm_access_t access,
184  bool set_ro,
185  amxc_var_t* retval) {
187  amxc_var_t templ_params;
188  amxd_object_t* instance = NULL;
189  amxp_expr_t* expr = NULL;
190 
191  amxc_var_init(&templ_params);
192  when_true_status(amxd_object_get_type(templ) != amxd_object_template,
193  exit,
195  when_true_status(amxd_object_is_attr_set(templ, amxd_oattr_private) &&
196  access != amxd_dm_access_private,
197  exit,
199  when_true_status(amxd_object_is_attr_set(templ, amxd_oattr_read_only) &&
200  !set_ro,
201  exit,
203 
204  status = amxd_object_new_instance(&instance, templ, name, index, params);
205  when_failed(status, exit);
206 
207  status = amxd_action_set_values(instance, access, true, params, retval, true);
208  if(status != amxd_status_ok) {
209  amxd_object_delete(&instance);
210  goto exit;
211  }
212 
214  if(status != amxd_status_ok) {
215  amxd_object_delete(&instance);
216  goto exit;
217  }
218 
219  amxd_action_add_inst_build_retval(instance, retval);
220 
221 exit:
222  amxc_var_clean(&templ_params);
223  amxp_expr_delete(&expr);
224  return status;
225 }
226 
228  amxc_var_t* data) {
229  bool retval = false;
230 
231  when_false(amxc_var_type_of(data) == AMXC_VAR_ID_HTABLE, exit);
232  when_null(GET_ARG(data, "index"), exit);
233  when_null(amxd_object_get_instance(object, NULL, GET_UINT32(data, "index")), exit);
234 
235  retval = true;
236 
237 exit:
238  return retval;
239 }
240 
242  UNUSED amxd_param_t* const p,
243  amxd_action_t reason,
244  const amxc_var_t* const args,
245  amxc_var_t* const retval,
246  void* priv) {
248  amxc_var_t* params = NULL;
249  amxc_var_t* max = (amxc_var_t*) priv;
250  uint32_t index = 0;
251  char* key = NULL;
253  bool set_ro = false;
254  bool is_created = false;
255 
256  when_null(object, exit);
257  when_null(retval, exit);
258  when_true_status(reason != action_object_add_inst,
259  exit,
261 
262  is_created = amxd_action_add_inst_is_created(object, retval);
263 
264  if(max != NULL) {
265  uint32_t instances = amxd_object_get_instance_count(object);
266  int64_t max_inst = 0;
267  instances = is_created ? instances - 1 : instances;
268  if(amxc_var_type_of(max) == AMXC_VAR_ID_CSTRING) {
269  amxc_var_t* ref_value = amxd_resolve_param_ref(object, max);
270  max = ref_value == NULL ? max : ref_value;
271  }
272  max_inst = amxc_var_dyncast(int64_t, max);
273  if((max_inst > 0) && ((int64_t) instances >= max_inst)) {
275  goto exit;
276  }
277  }
278 
279  if(is_created) {
281  goto exit;
282  }
283 
284  index = GET_UINT32(args, "index");
285  key = amxc_var_dyncast(cstring_t, GET_ARG(args, "name"));
286  params = GET_ARG(args, "parameters");
287  access = (amxd_dm_access_t) GET_UINT32(args, "access");
288  set_ro = GET_BOOL(args, "set_read_only");
289 
290  when_true_status(!amxd_action_verify_access(object, access),
291  exit,
293 
294  status = amxd_action_add_inst(object, key, index, params, access, set_ro, retval);
295 
296 exit:
297  free(key);
298  return status;
299 }
300 
302  amxd_object_t* templ,
303  const char* name,
304  uint32_t index,
305  amxc_var_t* values) {
307  amxc_var_t args;
308  amxc_var_t* var_index = NULL;
309  amxc_var_t retval;
310 
311  amxc_var_init(&args);
312  amxc_var_init(&retval);
313  when_null(templ, exit);
314 
315  if(instance != NULL) {
316  *instance = NULL;
317  }
318 
319  amxc_var_set_type(&args, AMXC_VAR_ID_HTABLE);
320  amxc_var_set_key(&args, "parameters", values, AMXC_VAR_FLAG_COPY);
321  amxc_var_add_key(uint32_t, &args, "access", amxd_dm_access_private);
322  amxc_var_add_key(bool, &args, "set_read_only", true);
323  amxc_var_add_key(uint32_t, &args, "index", index);
324  amxc_var_add_key(cstring_t, &args, "name", name);
325 
327  NULL,
329  &args,
330  &retval);
331  when_failed(status, exit);
332 
333  var_index = amxc_var_get_path(&retval, "index", AMXC_VAR_FLAG_DEFAULT);
334  index = amxc_var_dyncast(uint32_t, var_index);
335 
336  if(instance != NULL) {
337  *instance = amxd_object_get_instance(templ, NULL, index);
338  }
339 
340 exit:
341  amxc_var_clean(&args);
342  amxc_var_clean(&retval);
343  return status;
344 }
Ambiorix Data Model Default actions header file.
static amxd_status_t amxd_action_add_inst(amxd_object_t *const templ, const char *name, uint32_t index, amxc_var_t *params, amxd_dm_access_t access, bool set_ro, amxc_var_t *retval)
amxd_status_t amxd_action_object_add_inst(amxd_object_t *const object, UNUSED amxd_param_t *const p, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
static amxd_status_t amxd_instance_validate_keys(amxd_object_t *instance)
static bool amxd_action_add_inst_is_created(amxd_object_t *const object, amxc_var_t *data)
static void amxd_action_add_inst_build_retval(amxd_object_t *instance, amxc_var_t *retval)
#define IS_BIT_SET(b, f)
Definition: amxd_common.h:66
Ambiorix Data Model API header file.
amxd_status_t amxd_dm_invoke_action(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval)
Definition: amxd_dm.c:591
Ambiorix Data Model API header file.
bool amxd_action_verify_access(amxd_object_t *object, amxd_dm_access_t access)
static uint32_t amxd_object_get_instance_count(const amxd_object_t *object)
amxd_status_t amxd_object_describe_params(amxd_object_t *const object, amxc_var_t *const value, amxd_dm_access_t access)
amxd_status_t amxd_param_validate(amxd_param_t *const param, const amxc_var_t *const value)
uint32_t amxd_param_get_attrs(const amxd_param_t *const param)
amxd_status_t amxd_param_get_value(amxd_param_t *const param, amxc_var_t *const value)
amxc_var_t *PRIVATE amxd_resolve_param_ref(amxd_object_t *object, amxc_var_t *ref)
amxd_status_t PRIVATE amxd_action_set_values(amxd_object_t *const object, amxd_dm_access_t access, bool ro, const amxc_var_t *values, amxc_var_t *retval, bool required)
@ amxd_pattr_key
Definition: amxd_types.h:362
@ action_object_add_inst
Definition: amxd_types.h:123
enum _amxd_action amxd_action_t
enum _amxd_status amxd_status_t
@ amxd_status_function_not_implemented
Definition: amxd_types.h:83
@ amxd_status_invalid_type
Definition: amxd_types.h:90
@ amxd_status_object_not_found
Definition: amxd_types.h:80
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_unknown_error
Definition: amxd_types.h:79
@ amxd_status_invalid_value
Definition: amxd_types.h:88
@ amxd_status_invalid_action
Definition: amxd_types.h:89
#define AMXD_OBJECT_INDEXED
Name and path format flag - use index for instance objects.
Definition: amxd_object.h:176
#define AMXD_OBJECT_NAMED
Name and path format flag - default behavior, use name for instance objects.
Definition: amxd_object.h:164
enum _amxd_dm_access amxd_dm_access_t
Access level.
#define AMXD_OBJECT_TERMINATE
Path format flag - when set the object path is terminated with a dot.
Definition: amxd_object.h:214
@ amxd_oattr_read_only
Definition: amxd_types.h:199
@ amxd_oattr_private
Definition: amxd_types.h:202
@ amxd_dm_access_private
Definition: amxd_types.h:141
@ amxd_dm_access_public
Definition: amxd_types.h:136
@ amxd_object_template
Definition: amxd_types.h:183
amxd_object_t amxd_status_t amxd_status_t char * amxd_object_get_path(const amxd_object_t *object, const uint32_t flags)
Get the full path of the object.
amxd_object_t * amxd_object_get_instance(const amxd_object_t *object, const char *name, uint32_t index)
Get an instance of the template object.
uint32_t amxd_object_get_index(const amxd_object_t *const object)
Get the index of an instance object.
Definition: amxd_object.c:265
amxd_status_t amxd_object_new_instance(amxd_object_t **object, amxd_object_t *templ, const char *name, uint32_t index, amxc_var_t *values)
Data model object constructor function.
amxd_status_t amxd_object_add_instance(amxd_object_t **instance, amxd_object_t *templ, const char *name, uint32_t index, amxc_var_t *values)
Data model object constructor function.
void amxd_object_delete(amxd_object_t **object)
Invokes the destroy handler(s) of the object.
static amxd_object_type_t amxd_object_get_type(const amxd_object_t *const object)
Returns the object type.
Definition: amxd_object.h:586
bool amxd_object_is_attr_set(const amxd_object_t *const object, const amxd_oattr_id_t attr)
Checks if an attribute is set.
Definition: amxd_object.c:348
const char * amxd_object_get_name(const amxd_object_t *const object, const uint32_t flags)
Get the name of the object (or index as a string for instance objects)
Definition: amxd_object.c:239
#define amxd_object_for_each(type, it, object)
Helper macro for iterating object content.
Definition: amxd_object.h:113
static amxd_status_t status