libamxs  0.6.0
Data Model Synchronization C API
amxs_util.c File Reference
#include <stdlib.h>
#include <string.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_path.h>
#include <amxd/amxd_transaction.h>
#include <amxd/amxd_dm.h>
#include <amxs/amxs_types.h>
#include <amxs/amxs_util.h>
#include "amxs_priv.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

bool amxs_sync_entry_remove_bidrection_object (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const char *path)
 
bool amxs_sync_entry_check_bidrection_object (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const char *path, const char *opposite_path)
 
static bool amxs_sync_entry_check_bidirectional_param (amxc_var_t *list, amxc_var_t *value)
 
bool amxs_sync_entry_check_bidirectional_loop (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, amxc_var_t *value, const char *path, const char *opposite_path)
 
bool amxs_sync_entry_is_bidirectional (const amxs_sync_entry_t *entry)
 
bool amxs_sync_entry_direction_allowed (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
 
bool amxs_sync_entry_is_batch_param (const amxs_sync_entry_t *const entry)
 
const char * amxs_sync_entry_get_name (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
 
const char * amxs_sync_entry_get_opposite_name (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
 
amxs_sync_entry_tamxs_sync_entry_get_parent (const amxs_sync_entry_t *const entry)
 
amxs_sync_ctx_tamxs_sync_entry_get_ctx (const amxs_sync_entry_t *const entry)
 
amxp_signal_mngr_t * amxs_sync_entry_get_signal_manager (const amxs_sync_entry_t *const entry)
 
amxb_bus_ctx_t * amxs_sync_ctx_get_opposite_bus_ctx (const amxs_sync_ctx_t *const ctx, amxs_sync_direction_t direction)
 
amxb_bus_ctx_t * amxs_sync_ctx_get_bus_ctx (const amxs_sync_ctx_t *const ctx, amxs_sync_direction_t direction)
 
amxd_dm_t * amxs_sync_ctx_get_opposite_dm (const amxs_sync_ctx_t *ctx, amxs_sync_direction_t direction)
 
amxd_dm_t * amxs_sync_ctx_get_dm (const amxs_sync_ctx_t *ctx, amxs_sync_direction_t direction)
 
unsigned int amxs_sync_entry_get_opposite_index (const amxs_sync_entry_t *const entry, UNUSED amxs_sync_direction_t direction, unsigned int index)
 
static int amxs_sync_entry_build_opposite_path_entry (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, amxd_path_t *path, amxc_string_t *path_str)
 
char * amxs_sync_entry_get_opposite_path (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, const char *const old_path)
 
char * amxs_sync_entry_get_opposite_parent_path (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, const char *const old_path)
 
char * amxs_sync_entry_get_regex_path (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
 
char * amxs_sync_entry_get_regex_parent_path (const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
 
amxs_status_t amxs_sync_entry_get_batch_params (const amxs_sync_entry_t *const entry, amxc_var_t *params, amxs_sync_direction_t direction)
 
amxs_status_t amxs_sync_param_copy_trans_cb (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const amxc_var_t *input, amxc_var_t *output, UNUSED void *priv)
 
amxs_status_t amxs_sync_batch_param_copy_trans_cb (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const amxc_var_t *input, amxc_var_t *output, UNUSED void *priv)
 
amxs_status_t amxs_sync_param_copy_action_cb (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, amxc_var_t *data, UNUSED void *priv)
 
static void amxs_notify_instance_added (const amxc_var_t *input, amxs_sync_entry_t *entry, const amxs_sync_direction_t direction)
 
amxs_status_t amxs_sync_object_copy_trans_cb (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const amxc_var_t *input, amxc_var_t *output, UNUSED void *priv)
 
amxs_status_t amxs_sync_object_copy_action_cb (const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, amxc_var_t *data, UNUSED void *priv)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxs_util.c.

Function Documentation

◆ amxs_notify_instance_added()

static void amxs_notify_instance_added ( const amxc_var_t *  input,
amxs_sync_entry_t entry,
const amxs_sync_direction_t  direction 
)
static

Definition at line 742 of file amxs_util.c.

742  {
743  amxc_var_t* parameters = NULL;
744  amxc_var_t* changed_value = NULL;
745  amxc_var_t event_data;
746  amxc_string_t str_object;
747  amxc_string_t str_path;
748  amxc_string_t str_new_value;
749 
750  amxc_var_init(&event_data);
751  amxc_var_set_type(&event_data, AMXC_VAR_ID_HTABLE);
752  amxc_string_init(&str_object, 0);
753  amxc_string_init(&str_path, 0);
754  amxc_string_init(&str_new_value, 0);
755  amxc_string_setf(&str_object, "%s%d.", GET_CHAR(input, "object"), GET_UINT32(input, "index"));
756  amxc_string_setf(&str_path, "%s%d.", GET_CHAR(input, "path"), GET_UINT32(input, "index"));
757  amxc_string_setf(&str_new_value, "parameters.%s", amxs_sync_entry_get_name(entry, direction));
758 
759  amxc_var_add_key(cstring_t, &event_data, "notification", "dm:object-changed");
760  amxc_var_add_key(cstring_t, &event_data, "object", amxc_string_get(&str_object, 0));
761 
762  parameters = amxc_var_add_key(amxc_htable_t, &event_data, "parameters", NULL);
763  changed_value = amxc_var_add_key(amxc_htable_t, parameters, amxs_sync_entry_get_name(entry, direction), NULL);
764  amxc_var_set_key(changed_value, "from", NULL, AMXC_VAR_FLAG_DEFAULT);
765  amxc_var_set_key(changed_value, "to", GETP_ARG(input, amxc_string_get(&str_new_value, 0)), AMXC_VAR_FLAG_DEFAULT);
766 
767  amxc_var_add_key(cstring_t, &event_data, "path", amxc_string_get(&str_path, 0));
768  amxp_sigmngr_emit_signal(amxs_sync_entry_get_signal_manager(entry), "sync:instance-added", &event_data);
769 
770  amxc_var_clean(&event_data);
771  amxc_string_clean(&str_new_value);
772  amxc_string_clean(&str_path);
773  amxc_string_clean(&str_object);
774 }
const char * amxs_sync_entry_get_name(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
Definition: amxs_util.c:264
amxp_signal_mngr_t * amxs_sync_entry_get_signal_manager(const amxs_sync_entry_t *const entry)
Definition: amxs_util.c:317

◆ amxs_sync_batch_param_copy_trans_cb()

amxs_status_t amxs_sync_batch_param_copy_trans_cb ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
const amxc_var_t *  input,
amxc_var_t *  output,
UNUSED void *  priv 
)

Definition at line 617 of file amxs_util.c.

621  {
623  amxc_var_t* params = GET_ARG(input, "parameters");
624  amxc_var_t* output_params = NULL;
625  const char* path = GET_CHAR(input, "path");
626  const char* notification = GET_CHAR(input, "notification");
627  const char* entry_name = amxs_sync_entry_get_name(entry, direction);
628  char* opposite_path = NULL;
629 
630  when_null(params, exit);
631  when_str_empty(path, exit);
632  when_str_empty(entry_name, exit);
633  when_str_empty(notification, exit);
634 
635  opposite_path = amxs_sync_entry_get_opposite_path(entry, direction, path);
636  when_str_empty(opposite_path, exit);
637 
638  amxc_var_set_type(output, AMXC_VAR_ID_HTABLE);
639  output_params = amxc_var_add_key(amxc_htable_t, output, "parameters", NULL);
640  amxc_var_add_key(cstring_t, output, "path", opposite_path);
641 
642  if((strcmp(notification, "dm:object-added") == 0) ||
643  (strcmp(notification, "sync:init-batch-param") == 0)) {
644  // Handle loop prevention, returns true if this object-added is to be ignored
645  if(amxs_sync_entry_check_bidrection_object(entry, direction, path, opposite_path)) {
646  status = amxs_status_ok;
647  goto exit;
648  }
649  } else {
650  amxs_sync_entry_remove_bidrection_object(entry, direction, path);
651  if(strcmp(notification, "dm:object-removed") == 0) {
652  status = amxs_status_ok;
653  goto exit;
654  }
655  }
656 
657 
658  amxc_llist_iterate(it, &entry->entries) {
659  amxs_sync_entry_t* child = amxc_llist_it_get_data(it, amxs_sync_entry_t, it);
660  amxc_var_t* param = NULL;
661  amxc_var_t* new_param = NULL;
662  amxc_var_t* value = NULL;
663 
664  if(!amxs_sync_entry_is_batch_param(child)) {
665  continue;
666  }
667 
668  param = GETP_ARG(params, amxs_sync_entry_get_name(child, direction));
669  if(param == NULL) {
670  continue;
671  }
672 
673  if((strcmp(notification, "sync:init-batch-param") == 0) ||
674  (strcmp(notification, "dm:object-added") == 0)) {
675  value = param;
676  } else {
677  value = GET_ARG(param, "to");
678  }
679 
680  // Handle loop prevention, returns true if this parameter is to be ignored
681  if(strcmp(notification, "dm:object-added") != 0) {
682  if(amxs_sync_entry_check_bidirectional_loop(child, direction, value, path, opposite_path)) {
683  continue;
684  }
685  }
686 
687  new_param = amxc_var_add_new_key(output_params, amxs_sync_entry_get_opposite_name(child, direction));
688  amxc_var_copy(new_param, value);
689  }
690 
691  status = amxs_status_ok;
692 
693 exit:
694  free(opposite_path);
695  return status;
696 }
@ amxs_status_ok
Definition: amxs_types.h:86
@ amxs_status_unknown_error
Definition: amxs_types.h:90
enum _amxs_status amxs_status_t
const char * amxs_sync_entry_get_opposite_name(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
Definition: amxs_util.c:275
bool amxs_sync_entry_check_bidirectional_loop(const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, amxc_var_t *value, const char *path, const char *opposite_path)
Definition: amxs_util.c:168
bool amxs_sync_entry_remove_bidrection_object(const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const char *path)
Definition: amxs_util.c:76
char * amxs_sync_entry_get_opposite_path(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, const char *const old_path)
Definition: amxs_util.c:429
bool amxs_sync_entry_is_batch_param(const amxs_sync_entry_t *const entry)
Definition: amxs_util.c:251
bool amxs_sync_entry_check_bidrection_object(const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const char *path, const char *opposite_path)
Definition: amxs_util.c:101
Definition: amxs_types.h:161
amxc_llist_t entries
Definition: amxs_types.h:169

◆ amxs_sync_ctx_get_bus_ctx()

amxb_bus_ctx_t* amxs_sync_ctx_get_bus_ctx ( const amxs_sync_ctx_t *const  ctx,
amxs_sync_direction_t  direction 
)

Definition at line 343 of file amxs_util.c.

344  {
345  amxb_bus_ctx_t* bus_ctx = NULL;
346  when_null(ctx, exit);
347  when_false(ctx->type == amxs_sync_type_ctx, exit);
348 
349  bus_ctx = direction == amxs_sync_a_to_b ? ctx->bus_ctx_a : ctx->bus_ctx_b;
350 
351 exit:
352  return bus_ctx;
353 }
@ amxs_sync_a_to_b
Definition: amxs_types.h:80
@ amxs_sync_type_ctx
Definition: amxs_types.h:100
amxs_sync_entry_type_t type
Definition: amxs_types.h:170
amxb_bus_ctx_t * bus_ctx_a
Definition: amxs_types.h:171
amxb_bus_ctx_t * bus_ctx_b
Definition: amxs_types.h:172
static amxb_bus_ctx_t * bus_ctx

◆ amxs_sync_ctx_get_dm()

amxd_dm_t* amxs_sync_ctx_get_dm ( const amxs_sync_ctx_t ctx,
amxs_sync_direction_t  direction 
)

Definition at line 367 of file amxs_util.c.

368  {
369  amxd_dm_t* dm = NULL;
370  when_null(ctx, exit);
371  when_false(ctx->type == amxs_sync_type_ctx, exit);
372 
373  dm = direction == amxs_sync_a_to_b ? ctx->local_dm_a : ctx->local_dm_b;
374 
375 exit:
376  return dm;
377 }
amxd_dm_t * local_dm_b
Definition: amxs_types.h:178
amxd_dm_t * local_dm_a
Definition: amxs_types.h:177

◆ amxs_sync_ctx_get_opposite_bus_ctx()

amxb_bus_ctx_t* amxs_sync_ctx_get_opposite_bus_ctx ( const amxs_sync_ctx_t *const  ctx,
amxs_sync_direction_t  direction 
)

Definition at line 331 of file amxs_util.c.

332  {
333  amxb_bus_ctx_t* bus_ctx = NULL;
334  when_null(ctx, exit);
335  when_false(ctx->type == amxs_sync_type_ctx, exit);
336 
337  bus_ctx = direction == amxs_sync_a_to_b ? ctx->bus_ctx_b : ctx->bus_ctx_a;
338 
339 exit:
340  return bus_ctx;
341 }

◆ amxs_sync_ctx_get_opposite_dm()

amxd_dm_t* amxs_sync_ctx_get_opposite_dm ( const amxs_sync_ctx_t ctx,
amxs_sync_direction_t  direction 
)

Definition at line 355 of file amxs_util.c.

356  {
357  amxd_dm_t* dm = NULL;
358  when_null(ctx, exit);
359  when_false(ctx->type == amxs_sync_type_ctx, exit);
360 
361  dm = direction == amxs_sync_a_to_b ? ctx->local_dm_b : ctx->local_dm_a;
362 
363 exit:
364  return dm;
365 }

◆ amxs_sync_entry_build_opposite_path_entry()

static int amxs_sync_entry_build_opposite_path_entry ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction,
amxd_path_t *  path,
amxc_string_t *  path_str 
)
static

Definition at line 391 of file amxs_util.c.

394  {
395  char* last = amxd_path_get_last(path, true);
396  char* ptr = NULL;
397  unsigned int index = strtoul(last, &ptr, 0);
398  int ret = -1;
399  const char* name = amxs_sync_entry_get_name(entry, direction);
400  amxc_string_t str;
401 
402  amxc_string_init(&str, 0);
403 
404  if(strcmp(name, last) == 0) {
405  amxc_string_prependf(path_str, "%s", amxs_sync_entry_get_opposite_name(entry, direction));
406  } else if(strstr(name, last) != NULL) {
407  amxc_string_set(&str, last);
408  do {
409  free(last);
410  last = amxd_path_get_last(path, true);
411  when_null(last, exit);
412  amxc_string_prependf(&str, "%s", last);
413  } while(strcmp(amxc_string_get(&str, 0), name) != 0);
414  amxc_string_prependf(path_str, "%s", amxs_sync_entry_get_opposite_name(entry, direction));
415  } else if(last != ptr) {
416  index = amxs_sync_entry_get_opposite_index(entry, direction, index);
417  amxc_string_prependf(path_str, "%u.", index);
418  amxs_sync_entry_build_opposite_path_entry(entry, direction, path, path_str);
419  }
420 
421  ret = 0;
422 
423 exit:
424  free(last);
425  amxc_string_clean(&str);
426  return ret;
427 }
static int amxs_sync_entry_build_opposite_path_entry(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, amxd_path_t *path, amxc_string_t *path_str)
Definition: amxs_util.c:391
unsigned int amxs_sync_entry_get_opposite_index(const amxs_sync_entry_t *const entry, UNUSED amxs_sync_direction_t direction, unsigned int index)
Definition: amxs_util.c:379

◆ amxs_sync_entry_check_bidirectional_loop()

bool amxs_sync_entry_check_bidirectional_loop ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
amxc_var_t *  value,
const char *  path,
const char *  opposite_path 
)

Definition at line 168 of file amxs_util.c.

172  {
173  bool ret = false;
174  amxc_string_t str;
175  amxc_var_t* current_list = NULL;
176  amxc_var_t* opposite_list = NULL;
177  amxc_var_t* current_table = NULL;
178  amxc_var_t* opposite_table = NULL;
179  amxc_var_t* value_storage = NULL;
181 
182  amxc_string_init(&str, 0);
183 
184  when_null(entry, exit);
185  when_null(ctx, exit);
186  when_null(value, exit);
187  when_str_empty(path, exit);
188  when_str_empty(opposite_path, exit);
189  when_false(amxs_sync_entry_is_bidirectional(entry), exit);
190 
191  opposite_table = direction == amxs_sync_a_to_b ? &ctx->b_to_a : &ctx->a_to_b;
192  current_table = direction == amxs_sync_a_to_b ? &ctx->a_to_b : &ctx->b_to_a;
193 
194  // Find current path in opposite table
195  amxc_string_setf(&str, "%s%s", path, amxs_sync_entry_get_name(entry, direction));
196  opposite_list = GET_ARG(opposite_table, amxc_string_get(&str, 0));
197  if(opposite_list != NULL) {
198  // Entry found, do the regular loop detection for parameters
199  ret = amxs_sync_entry_check_bidirectional_param(opposite_list, value);
200  when_true(ret, exit);
201  }
202 
203  amxc_string_setf(&str, "%s%s", opposite_path, amxs_sync_entry_get_opposite_name(entry, direction));
204  current_list = GET_ARG(current_table, amxc_string_get(&str, 0));
205  if(current_list == NULL) {
206  // Add the opposite path to the current ctx htable
207  current_list = amxc_var_add_key(amxc_llist_t, current_table, amxc_string_get(&str, 0), NULL);
208  }
209 
210  // Add the current value to the current list
211  value_storage = amxc_var_add_new(current_list);
212  amxc_var_copy(value_storage, value);
213 
214 exit:
215  amxc_string_clean(&str);
216  return ret;
217 }
static bool amxs_sync_entry_check_bidirectional_param(amxc_var_t *list, amxc_var_t *value)
Definition: amxs_util.c:138
amxs_sync_ctx_t * amxs_sync_entry_get_ctx(const amxs_sync_entry_t *const entry)
Definition: amxs_util.c:297
bool amxs_sync_entry_is_bidirectional(const amxs_sync_entry_t *entry)
Definition: amxs_util.c:219
amxc_var_t b_to_a
Definition: amxs_types.h:176
amxc_var_t a_to_b
Definition: amxs_types.h:175

◆ amxs_sync_entry_check_bidirectional_param()

static bool amxs_sync_entry_check_bidirectional_param ( amxc_var_t *  list,
amxc_var_t *  value 
)
static

Definition at line 138 of file amxs_util.c.

139  {
140  bool ret = false;
141 
142  when_null(list, exit);
143  when_null(value, exit);
144 
145  amxc_var_for_each(var, list) {
146  int count = 1;
147  int result = 0;
148 
149  if((amxc_var_compare(value, var, &result) == 0) && (result == 0)) {
150  amxc_var_for_each(var_rm, list) {
151  amxc_var_take_it(var_rm);
152  amxc_var_delete(&var_rm);
153  count--;
154  if(count == 0) {
155  break;
156  }
157  }
158  ret = true;
159  goto exit;
160  }
161  count++;
162  }
163 
164 exit:
165  return ret;
166 }

◆ amxs_sync_entry_check_bidrection_object()

bool amxs_sync_entry_check_bidrection_object ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
const char *  path,
const char *  opposite_path 
)

Definition at line 101 of file amxs_util.c.

104  {
105  bool ret = false;
106  amxd_path_t check_path;
107  amxc_var_t* opposite_list = NULL;
108  amxc_var_t* current_list = NULL;
109  amxc_var_t* opposite = NULL;
111 
112  amxd_path_init(&check_path, opposite_path);
113 
114  when_null(entry, exit);
115  when_null(ctx, exit);
116  when_str_empty(path, exit);
117  when_str_empty(opposite_path, exit);
118  when_false(amxs_sync_entry_is_bidirectional(entry), exit);
119 
120  opposite_list = direction == amxs_sync_a_to_b ? &ctx->b_to_a : &ctx->a_to_b;
121  current_list = direction == amxs_sync_a_to_b ? &ctx->a_to_b : &ctx->b_to_a;
122  opposite = GET_ARG(opposite_list, path);
123 
124  when_true(amxd_path_is_instance_path(&check_path), exit);
125 
126  if(opposite != NULL) {
127  amxc_var_delete(&opposite);
128  ret = true;
129  } else {
130  amxc_var_add_key(bool, current_list, opposite_path, true);
131  }
132 
133 exit:
134  amxd_path_clean(&check_path);
135  return ret;
136 }

◆ amxs_sync_entry_direction_allowed()

bool amxs_sync_entry_direction_allowed ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction 
)

Definition at line 231 of file amxs_util.c.

232  {
233  bool ret = true;
234 
235  if((direction == amxs_sync_a_to_b) &&
236  ((entry->attributes & AMXS_SYNC_ONLY_B_TO_A) != 0)) {
237  ret = false;
238  goto exit;
239  }
240 
241  if((direction == amxs_sync_b_to_a) &&
242  ((entry->attributes & AMXS_SYNC_ONLY_A_TO_B) != 0)) {
243  ret = false;
244  goto exit;
245  }
246 
247 exit:
248  return ret;
249 }
@ amxs_sync_b_to_a
Definition: amxs_types.h:81
#define AMXS_SYNC_ONLY_B_TO_A
Only synchronize from object B to object A.
Definition: amxs_types.h:195
#define AMXS_SYNC_ONLY_A_TO_B
Only synchronize from object A to object B.
Definition: amxs_types.h:200
int attributes
Definition: amxs_types.h:165

◆ amxs_sync_entry_get_batch_params()

amxs_status_t amxs_sync_entry_get_batch_params ( const amxs_sync_entry_t *const  entry,
amxc_var_t *  params,
amxs_sync_direction_t  direction 
)

Definition at line 514 of file amxs_util.c.

516  {
518 
519  when_null(entry, exit);
520  when_null(params, exit);
521  when_true_status(entry->type == amxs_sync_type_param, exit, status = amxs_status_invalid_type);
522 
523  amxc_llist_iterate(it, &entry->entries) {
524  amxs_sync_entry_t* child = amxc_llist_it_get_data(it, amxs_sync_entry_t, it);
525  if(!amxs_sync_entry_is_batch_param(child)) {
526  continue;
527  }
528 
529  if(!amxs_sync_entry_direction_allowed(child, direction)) {
530  continue;
531  }
532 
533  amxc_var_add(cstring_t, params, direction == amxs_sync_a_to_b ? child->a : child->b);
534  }
535 
536  status = amxs_status_ok;
537 
538 exit:
539  return status;
540 }
@ amxs_status_invalid_type
Definition: amxs_types.h:92
@ amxs_status_invalid_arg
Definition: amxs_types.h:89
@ amxs_sync_type_param
Definition: amxs_types.h:102
bool amxs_sync_entry_direction_allowed(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
Definition: amxs_util.c:231
char * a
Definition: amxs_types.h:163
char * b
Definition: amxs_types.h:164

◆ amxs_sync_entry_get_ctx()

amxs_sync_ctx_t* amxs_sync_entry_get_ctx ( const amxs_sync_entry_t *const  entry)

Definition at line 297 of file amxs_util.c.

297  {
298  amxs_sync_ctx_t* ctx = NULL;
299  amxs_sync_entry_t* tmp = NULL;
300  when_null(entry, exit);
301 
302  when_true_status(entry->type == amxs_sync_type_ctx, exit, ctx = (amxs_sync_ctx_t*) entry);
303 
304  tmp = amxs_sync_entry_get_parent(entry);
305  while(tmp != NULL && tmp->type != amxs_sync_type_ctx) {
306  tmp = amxs_sync_entry_get_parent(tmp);
307  }
308 
309  if((tmp != NULL) && (tmp->type == amxs_sync_type_ctx)) {
310  ctx = tmp;
311  }
312 
313 exit:
314  return ctx;
315 }
amxs_sync_entry_t * amxs_sync_entry_get_parent(const amxs_sync_entry_t *const entry)
Definition: amxs_util.c:286

◆ amxs_sync_entry_get_name()

const char* amxs_sync_entry_get_name ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction 
)

Definition at line 264 of file amxs_util.c.

265  {
266  const char* name = NULL;
267  when_null(entry, exit);
268 
269  name = direction == amxs_sync_a_to_b ? entry->a : entry->b;
270 
271 exit:
272  return name;
273 }

◆ amxs_sync_entry_get_opposite_index()

unsigned int amxs_sync_entry_get_opposite_index ( const amxs_sync_entry_t *const  entry,
UNUSED amxs_sync_direction_t  direction,
unsigned int  index 
)

Definition at line 379 of file amxs_util.c.

381  {
382  int new_index = 0;
383  when_null(entry, exit);
384 
385  new_index = index;
386 
387 exit:
388  return new_index;
389 }

◆ amxs_sync_entry_get_opposite_name()

const char* amxs_sync_entry_get_opposite_name ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction 
)

Definition at line 275 of file amxs_util.c.

276  {
277  const char* opposite = NULL;
278  when_null(entry, exit);
279 
280  opposite = direction == amxs_sync_a_to_b ? entry->b : entry->a;
281 
282 exit:
283  return opposite;
284 }

◆ amxs_sync_entry_get_opposite_parent_path()

char* amxs_sync_entry_get_opposite_parent_path ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction,
const char *const  old_path 
)

Definition at line 456 of file amxs_util.c.

458  {
459  char* new_path = NULL;
461  when_null(parent, exit);
462 
463  new_path = amxs_sync_entry_get_opposite_path(parent, direction, old_path);
464 
465 exit:
466  return new_path;
467 }

◆ amxs_sync_entry_get_opposite_path()

char* amxs_sync_entry_get_opposite_path ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction,
const char *const  old_path 
)

Definition at line 429 of file amxs_util.c.

431  {
432  char* new_path = NULL;
433  amxc_string_t path_str;
434  amxd_path_t path;
435  const amxs_sync_entry_t* tmp = entry;
436 
437  when_null(entry, exit);
438  when_str_empty(old_path, exit);
439 
440  amxd_path_init(&path, old_path);
441  amxc_string_init(&path_str, 0);
442 
443  while(amxd_path_get_depth(&path) != 0 && tmp != NULL) {
444  when_false(amxs_sync_entry_build_opposite_path_entry(tmp, direction, &path, &path_str) == 0, exit);
445  tmp = amxs_sync_entry_get_parent(tmp);
446  }
447 
448  new_path = amxc_string_take_buffer(&path_str);
449 
450 exit:
451  amxd_path_clean(&path);
452  amxc_string_clean(&path_str);
453  return new_path;
454 }

◆ amxs_sync_entry_get_parent()

amxs_sync_entry_t* amxs_sync_entry_get_parent ( const amxs_sync_entry_t *const  entry)

Definition at line 286 of file amxs_util.c.

286  {
287  amxs_sync_entry_t* parent = NULL;
288  when_null(entry, exit);
289  when_false(amxc_llist_it_is_in_list(&entry->it), exit);
290 
291  parent = amxc_container_of(entry->it.llist, amxs_sync_entry_t, entries);
292 
293 exit:
294  return parent;
295 }
amxc_llist_it_t it
Definition: amxs_types.h:162

◆ amxs_sync_entry_get_regex_parent_path()

char* amxs_sync_entry_get_regex_parent_path ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction 
)

Definition at line 502 of file amxs_util.c.

503  {
504  char* path = NULL;
506  when_null(parent, exit);
507 
508  path = amxs_sync_entry_get_regex_path(parent, direction);
509 
510 exit:
511  return path;
512 }
char * amxs_sync_entry_get_regex_path(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
Definition: amxs_util.c:469

◆ amxs_sync_entry_get_regex_path()

char* amxs_sync_entry_get_regex_path ( const amxs_sync_entry_t *const  entry,
amxs_sync_direction_t  direction 
)

Definition at line 469 of file amxs_util.c.

470  {
471  char* path_str = NULL;
472  const amxs_sync_entry_t* tmp = entry;
473  amxc_string_t str;
474 
475  when_null(entry, exit);
476  amxc_string_init(&str, 0);
477  amxc_string_set(&str, "$");
478 
479  while(tmp != NULL) {
480  amxd_path_t path;
481  const char* name = amxs_sync_entry_get_name(tmp, direction);
482  when_str_empty(name, exit);
483  amxd_path_init(&path, name);
484 
485  if((entry->type == amxs_sync_type_object) && (amxd_path_is_instance_path(&path) == false)) {
486  amxc_string_prependf(&str, "%s([0-9]+\\.)?", name);
487  } else {
488  amxc_string_prependf(&str, "%s", name);
489  }
490  amxd_path_clean(&path);
491  tmp = amxs_sync_entry_get_parent(tmp);
492  }
493  amxc_string_prependf(&str, "%s", "^");
494 
495  path_str = amxc_string_take_buffer(&str);
496 
497 exit:
498  amxc_string_clean(&str);
499  return path_str;
500 }
@ amxs_sync_type_object
Definition: amxs_types.h:101

◆ amxs_sync_entry_get_signal_manager()

amxp_signal_mngr_t* amxs_sync_entry_get_signal_manager ( const amxs_sync_entry_t *const  entry)

Definition at line 317 of file amxs_util.c.

317  {
318  amxp_signal_mngr_t* sig_mngr = NULL;
319  amxs_sync_ctx_t* ctx = NULL;
320 
321  ctx = amxs_sync_entry_get_ctx(entry);
322  when_null(ctx, exit);
323 
324  sig_mngr = ctx->sig_mngr;
325 
326 exit:
327  return sig_mngr;
328 }
amxp_signal_mngr_t * sig_mngr
Definition: amxs_types.h:174

◆ amxs_sync_entry_is_batch_param()

bool amxs_sync_entry_is_batch_param ( const amxs_sync_entry_t *const  entry)

Definition at line 251 of file amxs_util.c.

251  {
252  bool ret = false;
253 
254  when_null(entry, exit);
255  when_false(entry->type == amxs_sync_type_param, exit);
256  when_true((entry->attributes & AMXS_SYNC_PARAM_BATCH) == 0, exit);
257 
258  ret = true;
259 
260 exit:
261  return ret;
262 }
#define AMXS_SYNC_PARAM_BATCH
Indicate that this parameter may be part of a batch copy operation.
Definition: amxs_types.h:210

◆ amxs_sync_entry_is_bidirectional()

bool amxs_sync_entry_is_bidirectional ( const amxs_sync_entry_t entry)

Definition at line 219 of file amxs_util.c.

219  {
220  bool ret = true;
221 
222  when_null(entry, exit);
223  if((entry->attributes & (AMXS_SYNC_ONLY_B_TO_A | AMXS_SYNC_ONLY_A_TO_B)) != 0) {
224  ret = false;
225  }
226 
227 exit:
228  return ret;
229 }

◆ amxs_sync_entry_remove_bidrection_object()

bool amxs_sync_entry_remove_bidrection_object ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
const char *  path 
)

Definition at line 76 of file amxs_util.c.

78  {
79  bool ret = false;
80  amxc_var_t* opposite_list = NULL;
81  amxc_var_t* opposite = NULL;
83 
84  when_null(entry, exit);
85  when_null(ctx, exit);
86  when_str_empty(path, exit);
87  when_false(amxs_sync_entry_is_bidirectional(entry), exit);
88 
89  opposite_list = direction == amxs_sync_a_to_b ? &ctx->b_to_a : &ctx->a_to_b;
90  opposite = GET_ARG(opposite_list, path);
91 
92  if(opposite != NULL) {
93  amxc_var_delete(&opposite);
94  ret = true;
95  }
96 
97 exit:
98  return ret;
99 }

◆ amxs_sync_object_copy_action_cb()

amxs_status_t amxs_sync_object_copy_action_cb ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
amxc_var_t *  data,
UNUSED void *  priv 
)

Definition at line 833 of file amxs_util.c.

836  {
838  const char* path = GET_CHAR(data, "path");
839  const char* notification = GET_CHAR(data, "notification");
840  uint32_t index = GET_UINT32(data, "index");
841  amxb_bus_ctx_t* bus_ctx = NULL;
842  amxc_var_t ret;
843 
844  amxc_var_init(&ret);
845 
846  when_null(path, exit);
847  when_null(notification, exit);
848 
850  when_null(bus_ctx, exit);
851 
852  if((strcmp(notification, "dm:instance-added") == 0) ||
853  (strcmp(notification, "sync:init-object") == 0)) {
854  amxc_var_t* params = GET_ARG(data, "parameters");
855  amxc_string_t str;
856  amxc_string_init(&str, 0);
857  amxc_string_setf(&str, "%s%u.", path, index);
858  if((amxb_get(bus_ctx, amxc_string_get(&str, 0), 0, &ret, 5) == 0) &&
859  (GETP_ARG(&ret, "0.0") != NULL)) {
860  if(amxb_set(bus_ctx, amxc_string_get(&str, 0), params, &ret, 5) == 0) {
861  status = amxs_status_ok;
862  }
863  } else {
864  if(amxb_add(bus_ctx, path, index, NULL, params, &ret, 5) == 0) {
865  status = amxs_status_ok;
866  }
867  }
868  amxc_string_clean(&str);
869  } else {
870  if(amxb_del(bus_ctx, path, index, NULL, &ret, 5) == 0) {
871  status = amxs_status_ok;
872  }
873  }
874 
875 exit:
876  amxc_var_clean(&ret);
877  return status;
878 }
amxb_bus_ctx_t * amxs_sync_ctx_get_opposite_bus_ctx(const amxs_sync_ctx_t *const ctx, amxs_sync_direction_t direction)
Definition: amxs_util.c:331

◆ amxs_sync_object_copy_trans_cb()

amxs_status_t amxs_sync_object_copy_trans_cb ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
const amxc_var_t *  input,
amxc_var_t *  output,
UNUSED void *  priv 
)

Definition at line 776 of file amxs_util.c.

780  {
782  const char* path = GET_CHAR(input, "path");
783  char* opposite_path = NULL;
784  const char* notification = GET_CHAR(input, "notification");
785 
786  when_str_empty(path, exit);
787  when_str_empty(notification, exit);
788  opposite_path = amxs_sync_entry_get_opposite_path(entry, direction, path);
789  when_str_empty(opposite_path, exit);
790 
791  amxc_var_set_type(output, AMXC_VAR_ID_HTABLE);
792  amxc_var_add_key(cstring_t, output, "path", opposite_path);
793  amxc_var_add_key(uint32_t, output, "index",
794  amxs_sync_entry_get_opposite_index(entry, direction, GET_UINT32(input, "index")));
795  amxc_var_add_key(cstring_t, output, "notification", notification);
796 
797  if(((strcmp("dm:instance-added", notification) == 0) ||
798  (strcmp("sync:init-object", notification) == 0)) &&
799  (GET_ARG(input, "parameters") != NULL)) {
800  amxc_var_t* params = GET_ARG(input, "parameters");
801  amxc_var_t* output_params = amxc_var_add_new_key(output, "parameters");
802  amxc_var_set_type(output_params, AMXC_VAR_ID_HTABLE);
803 
804  amxc_llist_for_each(it, &entry->entries) {
805  amxs_sync_entry_t* child = amxc_container_of(it, amxs_sync_entry_t, it);
806  if(child->type != amxs_sync_type_param) {
807  continue;
808  }
809  amxc_var_for_each(param, params) {
810  if(strcmp(amxc_var_key(param), amxs_sync_entry_get_name(child, direction)) == 0) {
811  amxc_var_t* new_param = amxc_var_add_new_key(output_params, amxs_sync_entry_get_opposite_name(child, direction));
812  amxc_var_copy(new_param, param);
813  }
814  }
815 
816  /* Emit a sync:instance-added signal for each non batch parameter */
817  if((amxs_sync_entry_is_batch_param(child) == false) &&
818  (GET_CHAR(input, "object") != NULL) &&
819  (GET_CHAR(input, "path") != NULL) &&
820  (strcmp("dm:instance-added", notification) == 0)) {
821  amxs_notify_instance_added(input, child, direction);
822  }
823  }
824  }
825 
826  status = amxs_status_ok;
827 
828 exit:
829  free(opposite_path);
830  return status;
831 }
static void amxs_notify_instance_added(const amxc_var_t *input, amxs_sync_entry_t *entry, const amxs_sync_direction_t direction)
Definition: amxs_util.c:742

◆ amxs_sync_param_copy_action_cb()

amxs_status_t amxs_sync_param_copy_action_cb ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
amxc_var_t *  data,
UNUSED void *  priv 
)

Definition at line 698 of file amxs_util.c.

701  {
703  const char* path = GET_CHAR(data, "path");
704  amxc_var_t* params = GET_ARG(data, "parameters");
705  amxb_bus_ctx_t* bus_ctx = NULL;
706  amxc_var_t ret;
707  amxd_dm_t* dm = NULL;
708 
709  amxc_var_init(&ret);
710 
711  when_null(path, exit);
712  when_null(params, exit);
713 
715  if(dm != NULL) {
716  amxd_trans_t trans;
717 
718  amxd_trans_init(&trans);
719  amxd_trans_set_attr(&trans, amxd_tattr_change_ro, true);
720  amxd_trans_select_pathf(&trans, "%s", path);
721  amxc_var_for_each(var, params) {
722  amxd_trans_set_param(&trans, amxc_var_key(var), var);
723  }
724 
725  if(amxd_trans_apply(&trans, dm) == 0) {
726  status = amxs_status_ok;
727  }
728  amxd_trans_clean(&trans);
729  } else {
731  when_null(bus_ctx, exit);
732  if(amxb_set(bus_ctx, path, params, &ret, 5) == 0) {
733  status = amxs_status_ok;
734  }
735  }
736 
737 exit:
738  amxc_var_clean(&ret);
739  return status;
740 }
amxd_dm_t * amxs_sync_ctx_get_opposite_dm(const amxs_sync_ctx_t *ctx, amxs_sync_direction_t direction)
Definition: amxs_util.c:355

◆ amxs_sync_param_copy_trans_cb()

amxs_status_t amxs_sync_param_copy_trans_cb ( const amxs_sync_entry_t entry,
amxs_sync_direction_t  direction,
const amxc_var_t *  input,
amxc_var_t *  output,
UNUSED void *  priv 
)

Definition at line 542 of file amxs_util.c.

546  {
548  amxc_var_t* params = GET_ARG(input, "parameters");
549  amxc_var_t* output_params = NULL;
550  const char* path = GET_CHAR(input, "path");
551  const char* notification = GET_CHAR(input, "notification");
552  const char* entry_name = amxs_sync_entry_get_name(entry, direction);
553  char* opposite_path = NULL;
554  amxs_sync_entry_t* parent_entry = amxs_sync_entry_get_parent(entry);
555 
556  when_null(params, exit);
557  when_str_empty(path, exit);
558  when_str_empty(entry_name, exit);
559  when_str_empty(notification, exit);
560 
561  opposite_path = amxs_sync_entry_get_opposite_parent_path(entry, direction, path);
562  when_str_empty(opposite_path, exit);
563 
564  amxc_var_set_type(output, AMXC_VAR_ID_HTABLE);
565  output_params = amxc_var_add_key(amxc_htable_t, output, "parameters", NULL);
566  amxc_var_add_key(cstring_t, output, "path", opposite_path);
567 
568  // When doing initial sync, protect agains loop-back add-object events
569  if((strcmp(notification, "dm:object-added") == 0) ||
570  (strcmp(notification, "sync:init-param") == 0)) {
571  // This translation callback function is called on parameter entries
572  // Here the object entry is needed, take parent.
573  // Handle loop prevention, returns true if this object-added is to be ignored
574  if(amxs_sync_entry_check_bidrection_object(parent_entry, direction, path, opposite_path)) {
575  status = amxs_status_ok;
576  goto exit;
577  }
578  } else {
579  amxs_sync_entry_remove_bidrection_object(parent_entry, direction, path);
580  if(strcmp(notification, "dm:object-removed") == 0) {
581  status = amxs_status_ok;
582  goto exit;
583  }
584  }
585 
586  amxc_var_for_each(param, params) {
587  if(strcmp(amxc_var_key(param), entry_name) == 0) {
588  amxc_var_t* value = NULL;
589  amxc_var_t* new_param = NULL;
590 
591  if((strcmp(notification, "sync:init-param") == 0) ||
592  (strcmp(notification, "dm:object-added") == 0)) {
593  value = param;
594  } else {
595  value = GET_ARG(param, "to");
596  }
597 
598  // Handle loop prevention, returns true if this parameter is to be ignored
599  if(strcmp(notification, "dm:object-added") != 0) {
600  if(amxs_sync_entry_check_bidirectional_loop(entry, direction, value, path, opposite_path)) {
601  continue;
602  }
603  }
604 
605  new_param = amxc_var_add_new_key(output_params, amxs_sync_entry_get_opposite_name(entry, direction));
606  amxc_var_copy(new_param, value);
607  }
608  }
609 
610  status = amxs_status_ok;
611 
612 exit:
613  free(opposite_path);
614  return status;
615 }
char * amxs_sync_entry_get_opposite_parent_path(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, const char *const old_path)
Definition: amxs_util.c:456