libamxd  6.4.1
Data Model Manager
amxd_object_event.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 <amxc/amxc.h>
63 #include <amxp/amxp_signal.h>
64 #include <amxp/amxp_slot.h>
65 #include <amxp/amxp_timer.h>
66 
67 #include <amxd/amxd_types.h>
68 #include <amxd/amxd_object.h>
69 #include <amxd/amxd_object_event.h>
70 #include <amxd/amxd_dm.h>
71 #include <amxd/amxd_dm_functions.h>
72 
73 #include "amxd_priv.h"
74 #include "amxd_dm_priv.h"
75 #include "amxd_assert.h"
76 
78  UNUSED amxd_param_t* const p,
79  amxd_action_t reason,
80  UNUSED const amxc_var_t* const args,
81  amxc_var_t* const retval,
82  void* priv) {
84  amxp_timer_t* timer = (amxp_timer_t*) priv;
85 
86  when_null(object, exit);
87  when_null(timer, exit);
88 
89  when_true_status(reason != action_object_destroy,
90  exit,
92 
93 
94  amxp_timer_delete(&timer);
95 
96  amxc_var_clean(retval);
97 
98 exit:
99  return status;
100 }
101 
102 static void amxd_periodic_inform(UNUSED amxp_timer_t* timer, void* priv) {
103  amxd_object_t* object = (amxd_object_t*) priv;
104  amxc_var_t data;
105  amxc_var_t* parameters = NULL;
106 
107  amxc_var_init(&data);
108  when_null(object, exit);
109  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
110 
111  parameters = amxc_var_add_key(amxc_htable_t, &data, "parameters", NULL);
113  amxd_dm_event("dm:periodic-inform", object, &data, false);
114 
115 exit:
116  amxc_var_clean(&data);
117  return;
118 }
119 
121  amxc_var_t* data) {
122  amxc_var_t* params = NULL;
123 
124  amxc_var_add_key(uint32_t, data, "index", object->index);
125  amxc_var_add_key(cstring_t, data, "name", object->name);
126  params = amxc_var_add_key(amxc_htable_t, data, "parameters", NULL);
127  amxd_object_get_params_filtered(object, params, "attributes.volatile == false", amxd_dm_access_protected);
128  params = amxc_var_add_key(amxc_htable_t, data, "keys", NULL);
130 }
131 
132 static bool amxd_object_event_filter(amxd_object_t* const object,
133  UNUSED int32_t depth,
134  UNUSED void* priv) {
135  bool retval = true;
136  when_true(amxd_object_get_type(object) == amxd_object_root, exit);
137 
139  retval = false;
140  goto exit;
141  }
142 
143 exit:
144  return retval;
145 }
146 
147 static bool amxd_object_event_filter_add(amxd_object_t* const object,
148  int32_t depth,
149  void* priv) {
150  bool retval = amxd_object_event_filter(object, depth, priv);
151  when_false(retval, exit);
152 
154  retval = false;
155  goto exit;
156  }
157 
158 exit:
159  return retval;
160 }
161 
162 static void amxd_object_send_event_add(amxd_object_t* const object,
163  UNUSED int32_t depth,
164  void* priv) {
165  bool* trigger = (bool*) priv;
166  amxc_var_t data;
167 
168  amxc_var_init(&data);
169  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
170 
172  amxd_object_t* templ = amxd_object_get_parent(object);
173  amxd_object_instance_sig_data(object, &data);
174  amxd_dm_event("dm:instance-added", templ, &data, *trigger);
175  } else {
176  amxc_var_t* params = amxc_var_add_key(amxc_htable_t, &data, "parameters", NULL);
177  amxd_object_get_params_filtered(object, params, "attributes.volatile == false", amxd_dm_access_protected);
178  amxd_dm_event("dm:object-added", object, &data, *trigger);
179  }
180 
181  amxc_var_clean(&data);
182 }
183 
184 static void amxd_object_send_event_del(amxd_object_t* const object,
185  UNUSED int32_t depth,
186  void* priv) {
187  bool* trigger = (bool*) priv;
188  amxc_var_t data;
189 
190  amxc_var_init(&data);
191  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
192 
194  amxd_object_t* templ = amxd_object_get_parent(object);
195  amxd_object_instance_sig_data(object, &data);
196  amxd_dm_event("dm:instance-removed", templ, &data, *trigger);
197  } else {
198  amxc_var_t* params = amxc_var_add_key(amxc_htable_t, &data, "parameters", NULL);
199  amxd_object_get_params_filtered(object, params, "attributes.volatile == false", amxd_dm_access_protected);
200  amxd_dm_event("dm:object-removed", object, &data, *trigger);
201  }
202 
203  amxc_var_clean(&data);
204 }
205 
206 static void amxd_build_param_changed(const char* name,
207  amxc_var_t* values,
208  amxc_var_t* data,
209  amxc_var_t* ovalue) {
210  amxc_var_t* new_value = NULL;
211  amxc_var_t* data_param = NULL;
212  int result = 0;
213 
214  new_value = amxc_var_get_pathf(values,
215  AMXC_VAR_FLAG_DEFAULT,
216  "'%s'",
217  name);
218 
219  data_param = amxc_var_add_new_key(data, name);
220  amxc_var_set_type(data_param, AMXC_VAR_ID_HTABLE);
221  amxc_var_set_key(data_param, "from", ovalue, AMXC_VAR_FLAG_COPY);
222  amxc_var_set_key(data_param, "to", new_value, AMXC_VAR_FLAG_DEFAULT);
223  // when no change in value, remove from event data
224  amxc_var_compare(ovalue, new_value, &result);
225  if(result == 0) {
226  amxc_var_delete(&data_param);
227  }
228 }
229 
231  const char* name,
232  amxc_var_t* const data,
233  bool trigger) {
234 
235  when_null(object, exit);
236  when_str_empty(name, exit);
237 
238  amxd_dm_event(name, object, data, trigger);
239 exit:
240  return;
241 }
242 
243 void amxd_object_send_add_inst(amxd_object_t* instance, bool trigger) {
244  when_null(instance, exit);
245  when_true(amxd_object_get_type(instance) != amxd_object_instance, exit);
246 
247  amxd_object_send_event_add(instance, INT32_MAX, &trigger);
248  amxd_object_for_each(child, it, instance) {
249  amxd_object_t* object = amxc_container_of(it, amxd_object_t, it);
254  INT32_MAX,
255  &trigger);
256  }
257 
258 exit:
259  return;
260 }
261 
262 void amxd_object_send_del_object(amxd_object_t* object, bool trigger) {
263  when_null(object, exit);
264 
269  INT32_MAX,
270  &trigger);
271 
272 exit:
273  return;
274 }
275 
276 void amxd_object_send_del_inst(amxd_object_t* instance, bool trigger) {
277  amxd_object_send_del_object(instance, trigger);
278 }
279 
281  amxc_var_t* params,
282  bool trigger) {
283  const amxc_htable_t* tparams = NULL;
284  amxc_var_t data;
285  amxc_var_t values;
286  amxc_var_t* parameters = NULL;
287  amxc_var_init(&data);
288  amxc_var_init(&values);
289 
290  when_null(object, exit);
291  when_null(params, exit);
292  when_true(amxc_var_type_of(params) != AMXC_VAR_ID_HTABLE, exit);
293  amxc_var_set_type(&values, AMXC_VAR_ID_HTABLE);
294 
295  amxc_var_for_each(ovalue, params) {
296  amxd_param_t* param_def = amxd_object_get_param_def(object, amxc_var_key(ovalue));
297  if(param_def == NULL) {
298  amxc_var_set_type(&values, AMXC_VAR_ID_HTABLE);
300  &values,
301  "attributes.volatile==false",
303  break;
304  }
306  amxc_var_set_key(&values, amxc_var_key(ovalue), &param_def->value, AMXC_VAR_FLAG_COPY);
307  }
308  }
309 
310  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
311  parameters = amxc_var_add_key(amxc_htable_t, &data, "parameters", NULL);
312  amxc_var_for_each(ovalue, params) {
313  const char* name = amxc_var_key(ovalue);
314  amxd_build_param_changed(name, &values, parameters, ovalue);
315  }
316 
317  tparams = amxc_var_constcast(amxc_htable_t, parameters);
318 
319  if(!amxc_htable_is_empty(tparams)) {
320  amxd_dm_event("dm:object-changed", object, &data, trigger);
321  }
322 
323 exit:
324  amxc_var_clean(&values);
325  amxc_var_clean(&data);
326  return;
327 }
328 
330  uint32_t sec) {
332  amxp_timer_t* timer = NULL;
333 
334  when_null(object, exit);
335  when_true(sec == 0, exit);
336  when_true(object->type == amxd_object_root, exit);
337  when_true(amxd_object_has_action_cb(object,
339  amxd_object_delete_timer), exit);
340 
341  amxp_timer_new(&timer, amxd_periodic_inform, object);
342  when_null(timer, exit);
343 
344  amxp_timer_set_interval(timer, sec * 1000);
345  amxp_timer_start(timer, sec * 1000);
346 
350  timer);
351 exit:
352  return status;
353 }
354 
357  amxp_timer_t* timer = NULL;
358 
359  when_null(object, exit);
360  when_true(object->type == amxd_object_root, exit);
361 
362  timer = (amxp_timer_t*) amxd_object_get_action_cb_data(object,
365  when_null(timer, exit);
366  amxp_timer_delete(&timer);
370 
371 exit:
372  return status;
373 
374 }
375 
377  const char* event_name,
378  amxc_var_t* event_data) {
380  amxd_dm_t* dm = amxd_object_get_dm(object);
381 
382  when_null(dm, exit);
383 
384  if(event_data != NULL) {
385  when_failed(amxc_var_set_key(&object->events,
386  event_name,
387  event_data,
388  AMXC_VAR_FLAG_DEFAULT | AMXC_VAR_FLAG_UPDATE), exit);
389  } else {
390  amxc_var_t* event = amxc_var_get_key(&object->events,
391  event_name,
392  AMXC_VAR_FLAG_DEFAULT);
393  if(event == NULL) {
394  when_null(amxc_var_add_new_key(&object->events,
395  event_name), exit);
396  } else {
397  amxc_var_set_type(event, AMXC_VAR_ID_NULL);
398  }
399  }
400 
401  amxp_sigmngr_add_signal(&dm->sigmngr, event_name);
402  retval = amxd_status_ok;
403 
404 exit:
405  if(retval != amxd_status_ok) {
406  amxc_var_delete(&event_data);
407  }
408  return retval;
409 }
410 
412  const char* event_name) {
413  return amxd_object_add_event_ext(object, event_name, NULL);
414 }
415 
417  const char* event_name) {
418  amxc_var_t* event = amxc_var_get_key(&object->events,
419  event_name,
420  AMXC_VAR_FLAG_DEFAULT);
421  amxc_var_delete(&event);
422 }
423 
424 amxc_var_t* amxd_object_new_event_data(const amxd_object_t* object,
425  const char* event_name) {
426  amxc_var_t* data = NULL;
427 
428  when_null(object, exit);
429  when_str_empty(event_name, exit);
430 
431  data = amxc_var_get_key(&object->events, event_name, AMXC_VAR_FLAG_COPY);
432  when_not_null(data, exit);
433 
435  object = amxd_object_get_parent(object);
436  } else {
437  object = amxd_object_get_base(object);
438  }
439  while(object != NULL) {
440  data = amxc_var_get_key(&object->events, event_name, AMXC_VAR_FLAG_COPY);
441  if(data != NULL) {
442  break;
443  }
444  object = amxd_object_get_base(object);
445  }
446 
447 exit:
448  return data;
449 }
Ambiorix Data Model API header file.
void PRIVATE amxd_dm_event(const char *signal, const amxd_object_t *const object, amxc_var_t *const data, bool trigger)
Definition: amxd_dm_priv.c:550
Ambiorix Data Model API header file.
amxd_object_t * amxd_object_get_base(const amxd_object_t *const object)
Definition: amxd_object.c:389
bool amxd_object_has_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn)
amxd_status_t amxd_object_add_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn, void *priv)
void * amxd_object_get_action_cb_data(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn)
amxd_status_t amxd_object_remove_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn)
static void amxd_object_send_event_add(amxd_object_t *const object, UNUSED int32_t depth, void *priv)
static void amxd_periodic_inform(UNUSED amxp_timer_t *timer, void *priv)
void amxd_object_send_del_object(amxd_object_t *object, bool trigger)
static void amxd_object_send_event_del(amxd_object_t *const object, UNUSED int32_t depth, void *priv)
static bool amxd_object_event_filter_add(amxd_object_t *const object, int32_t depth, void *priv)
static bool amxd_object_event_filter(amxd_object_t *const object, UNUSED int32_t depth, UNUSED void *priv)
static void amxd_object_instance_sig_data(amxd_object_t *object, amxc_var_t *data)
static amxd_status_t amxd_object_delete_timer(amxd_object_t *object, UNUSED amxd_param_t *const p, amxd_action_t reason, UNUSED const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
static void amxd_build_param_changed(const char *name, amxc_var_t *values, amxc_var_t *data, amxc_var_t *ovalue)
Ambiorix Data Model API header file.
amxd_status_t amxd_object_get_params_filtered(amxd_object_t *const object, amxc_var_t *const params, const char *filter, amxd_dm_access_t access)
amxd_status_t amxd_object_get_key_params(amxd_object_t *const object, amxc_var_t *const params, amxd_dm_access_t access)
bool amxd_param_is_attr_set(const amxd_param_t *const param, const amxd_pattr_id_t attr)
amxd_object_t * amxd_param_get_owner(const amxd_param_t *const param)
@ amxd_pattr_variable
Definition: amxd_types.h:360
@ action_object_destroy
Definition: amxd_types.h:125
enum _amxd_action amxd_action_t
enum _amxd_status amxd_status_t
@ amxd_status_function_not_implemented
Definition: amxd_types.h:83
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_unknown_error
Definition: amxd_types.h:79
@ amxd_direction_down
Definition: amxd_types.h:216
@ amxd_direction_down_reverse
Definition: amxd_types.h:217
@ amxd_oattr_private
Definition: amxd_types.h:202
@ amxd_dm_access_protected
Definition: amxd_types.h:139
@ amxd_object_root
Definition: amxd_types.h:178
@ amxd_object_instance
Definition: amxd_types.h:186
void amxd_object_remove_event(amxd_object_t *const object, const char *event_name)
Removes an event definition to the object.
void amxd_object_send_add_inst(amxd_object_t *instance, bool trigger)
Send an add instance object event.
amxd_status_t amxd_object_add_event_ext(amxd_object_t *const object, const char *event_name, amxc_var_t *event_data)
Adds an event definition to the object.
amxd_status_t amxd_object_add_event(amxd_object_t *const object, const char *event_name)
Adds an event definition to the object.
void amxd_object_send_changed(amxd_object_t *object, amxc_var_t *params, bool trigger)
Send an object changed event.
amxc_var_t * amxd_object_new_event_data(const amxd_object_t *object, const char *event_name)
Allocates a variant that contains the predefined event data.
amxd_status_t amxd_object_new_pi(amxd_object_t *object, uint32_t sec)
Creates and starts a periodic inform event timer.
void amxd_object_send_del_inst(amxd_object_t *instance, bool trigger)
Send a delete instance object event.
amxd_status_t amxd_object_delete_pi(amxd_object_t *object)
Stops and deletes a periodic inform event timer.
void amxd_object_send_signal(amxd_object_t *const object, const char *name, amxc_var_t *const data, bool trigger)
Send an object signal/event.
amxd_object_t * amxd_object_get_parent(const amxd_object_t *const object)
Get the parent object.
void amxd_object_hierarchy_walk(amxd_object_t *const object, const amxd_direction_t direction, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
Iterates over all objects in the data model tree.
amxd_dm_t * amxd_object_get_dm(const amxd_object_t *const object)
Get the data model.
amxd_status_t amxd_object_get_params(amxd_object_t *const object, amxc_var_t *const params, amxd_dm_access_t access)
Gets all parameter values of an object.
amxd_param_t * amxd_object_get_param_def(const amxd_object_t *const object, const char *name)
Gets a parameter definition from an 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
#define amxd_object_for_each(type, it, object)
Helper macro for iterating object content.
Definition: amxd_object.h:113
amxp_signal_mngr_t sigmngr
Definition: amxd_types.h:261
amxd_object_type_t type
Definition: amxd_types.h:236
uint32_t index
Definition: amxd_types.h:240
char * name
Definition: amxd_types.h:238
amxc_var_t events
Definition: amxd_types.h:256
amxc_var_t value
Definition: amxd_types.h:390
static amxd_dm_t dm
static amxd_status_t status