62 #include <amxc/amxc.h>
64 #include <amxp/amxp.h>
66 #include <amxd/amxd_object.h>
67 #include <amxd/amxd_path.h>
68 #include <amxd/amxd_transaction.h>
69 #include <amxd/amxd_dm.h>
80 amxc_var_t* opposite_list = NULL;
81 amxc_var_t* opposite = NULL;
84 when_null(entry, exit);
86 when_str_empty(path, exit);
90 opposite = GET_ARG(opposite_list, path);
92 if(opposite != NULL) {
93 amxc_var_delete(&opposite);
104 const char* opposite_path) {
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;
112 amxd_path_init(&check_path, opposite_path);
114 when_null(entry, exit);
115 when_null(ctx, exit);
116 when_str_empty(path, exit);
117 when_str_empty(opposite_path, exit);
122 opposite = GET_ARG(opposite_list, path);
124 when_true(amxd_path_is_instance_path(&check_path), exit);
126 if(opposite != NULL) {
127 amxc_var_delete(&opposite);
130 amxc_var_add_key(
bool, current_list, opposite_path,
true);
134 amxd_path_clean(&check_path);
142 when_null(list, exit);
143 when_null(value, exit);
145 amxc_var_for_each(var, list) {
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);
172 const char* opposite_path) {
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;
182 amxc_string_init(&str, 0);
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);
196 opposite_list = GET_ARG(opposite_table, amxc_string_get(&str, 0));
197 if(opposite_list != NULL) {
200 when_true(ret, exit);
204 current_list = GET_ARG(current_table, amxc_string_get(&str, 0));
205 if(current_list == NULL) {
207 current_list = amxc_var_add_key(amxc_llist_t, current_table, amxc_string_get(&str, 0), NULL);
211 value_storage = amxc_var_add_new(current_list);
212 amxc_var_copy(value_storage, value);
215 amxc_string_clean(&str);
222 when_null(entry, exit);
254 when_null(entry, exit);
266 const char* name = NULL;
267 when_null(entry, exit);
277 const char* opposite = NULL;
278 when_null(entry, exit);
288 when_null(entry, exit);
289 when_false(amxc_llist_it_is_in_list(&entry->
it), exit);
300 when_null(entry, exit);
318 amxp_signal_mngr_t* sig_mngr = NULL;
322 when_null(ctx, exit);
333 amxb_bus_ctx_t*
bus_ctx = NULL;
334 when_null(ctx, exit);
345 amxb_bus_ctx_t*
bus_ctx = NULL;
346 when_null(ctx, exit);
357 amxd_dm_t* dm = NULL;
358 when_null(ctx, exit);
369 amxd_dm_t* dm = NULL;
370 when_null(ctx, exit);
381 unsigned int index) {
383 when_null(entry, exit);
394 amxc_string_t* path_str) {
395 char* last = amxd_path_get_last(path,
true);
397 unsigned int index = strtoul(last, &ptr, 0);
402 amxc_string_init(&str, 0);
404 if(strcmp(name, last) == 0) {
406 }
else if(strstr(name, last) != NULL) {
407 amxc_string_set(&str, 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);
415 }
else if(last != ptr) {
417 amxc_string_prependf(path_str,
"%u.", index);
425 amxc_string_clean(&str);
431 const char*
const old_path) {
432 char* new_path = NULL;
433 amxc_string_t path_str;
437 when_null(entry, exit);
438 when_str_empty(old_path, exit);
440 amxd_path_init(&path, old_path);
441 amxc_string_init(&path_str, 0);
443 while(amxd_path_get_depth(&path) != 0 && tmp != NULL) {
448 new_path = amxc_string_take_buffer(&path_str);
451 amxd_path_clean(&path);
452 amxc_string_clean(&path_str);
458 const char*
const old_path) {
459 char* new_path = NULL;
461 when_null(parent, exit);
471 char* path_str = NULL;
475 when_null(entry, exit);
476 amxc_string_init(&str, 0);
477 amxc_string_set(&str,
"$");
482 when_str_empty(name, exit);
483 amxd_path_init(&path, name);
486 amxc_string_prependf(&str,
"%s([0-9]+\\.)?", name);
488 amxc_string_prependf(&str,
"%s", name);
490 amxd_path_clean(&path);
493 amxc_string_prependf(&str,
"%s",
"^");
495 path_str = amxc_string_take_buffer(&str);
498 amxc_string_clean(&str);
506 when_null(parent, exit);
519 when_null(entry, exit);
520 when_null(params, exit);
523 amxc_llist_iterate(it, &entry->
entries) {
544 const amxc_var_t* input,
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");
553 char* opposite_path = NULL;
556 when_null(params, exit);
557 when_str_empty(path, exit);
558 when_str_empty(entry_name, exit);
559 when_str_empty(notification, exit);
562 when_str_empty(opposite_path, exit);
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);
569 if((strcmp(notification,
"dm:object-added") == 0) ||
570 (strcmp(notification,
"sync:init-param") == 0)) {
580 if(strcmp(notification,
"dm:object-removed") == 0) {
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;
591 if((strcmp(notification,
"sync:init-param") == 0) ||
592 (strcmp(notification,
"dm:object-added") == 0)) {
595 value = GET_ARG(param,
"to");
599 if(strcmp(notification,
"dm:object-added") != 0) {
606 amxc_var_copy(new_param, value);
619 const amxc_var_t* input,
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");
628 char* opposite_path = NULL;
630 when_null(params, exit);
631 when_str_empty(path, exit);
632 when_str_empty(entry_name, exit);
633 when_str_empty(notification, exit);
636 when_str_empty(opposite_path, exit);
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);
642 if((strcmp(notification,
"dm:object-added") == 0) ||
643 (strcmp(notification,
"sync:init-batch-param") == 0)) {
651 if(strcmp(notification,
"dm:object-removed") == 0) {
658 amxc_llist_iterate(it, &entry->
entries) {
660 amxc_var_t* param = NULL;
661 amxc_var_t* new_param = NULL;
662 amxc_var_t* value = NULL;
673 if((strcmp(notification,
"sync:init-batch-param") == 0) ||
674 (strcmp(notification,
"dm:object-added") == 0)) {
677 value = GET_ARG(param,
"to");
681 if(strcmp(notification,
"dm:object-added") != 0) {
688 amxc_var_copy(new_param, value);
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;
707 amxd_dm_t* dm = NULL;
711 when_null(path, exit);
712 when_null(params, exit);
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);
725 if(amxd_trans_apply(&trans, dm) == 0) {
728 amxd_trans_clean(&trans);
732 if(amxb_set(
bus_ctx, path, params, &ret, 5) == 0) {
738 amxc_var_clean(&ret);
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;
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"));
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));
762 parameters = amxc_var_add_key(amxc_htable_t, &event_data,
"parameters", 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);
767 amxc_var_add_key(cstring_t, &event_data,
"path", amxc_string_get(&str_path, 0));
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);
778 const amxc_var_t* input,
782 const char* path = GET_CHAR(input,
"path");
783 char* opposite_path = NULL;
784 const char* notification = GET_CHAR(input,
"notification");
786 when_str_empty(path, exit);
787 when_str_empty(notification, exit);
789 when_str_empty(opposite_path, exit);
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",
795 amxc_var_add_key(cstring_t, output,
"notification", notification);
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);
804 amxc_llist_for_each(it, &entry->
entries) {
809 amxc_var_for_each(param, params) {
812 amxc_var_copy(new_param, param);
818 (GET_CHAR(input,
"object") != NULL) &&
819 (GET_CHAR(input,
"path") != NULL) &&
820 (strcmp(
"dm:instance-added", notification) == 0)) {
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;
846 when_null(path, exit);
847 when_null(notification, exit);
852 if((strcmp(notification,
"dm:instance-added") == 0) ||
853 (strcmp(notification,
"sync:init-object") == 0)) {
854 amxc_var_t* params = GET_ARG(data,
"parameters");
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) {
864 if(amxb_add(
bus_ctx, path, index, NULL, params, &ret, 5) == 0) {
868 amxc_string_clean(&str);
870 if(amxb_del(
bus_ctx, path, index, NULL, &ret, 5) == 0) {
876 amxc_var_clean(&ret);
Ambiorix Object Synchronization API header file.
@ amxs_status_unknown_error
@ amxs_status_invalid_type
@ amxs_status_invalid_arg
enum _amxs_sync_direction amxs_sync_direction_t
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)
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)
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_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)
char * amxs_sync_entry_get_regex_path(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
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)
static bool amxs_sync_entry_check_bidirectional_param(amxc_var_t *list, amxc_var_t *value)
amxb_bus_ctx_t * amxs_sync_ctx_get_opposite_bus_ctx(const amxs_sync_ctx_t *const ctx, amxs_sync_direction_t direction)
bool amxs_sync_entry_remove_bidrection_object(const amxs_sync_entry_t *entry, amxs_sync_direction_t direction, const char *path)
amxd_dm_t * amxs_sync_ctx_get_opposite_dm(const amxs_sync_ctx_t *ctx, amxs_sync_direction_t direction)
amxs_sync_ctx_t * amxs_sync_entry_get_ctx(const amxs_sync_entry_t *const entry)
char * amxs_sync_entry_get_opposite_path(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction, const char *const old_path)
bool amxs_sync_entry_is_batch_param(const amxs_sync_entry_t *const entry)
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)
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)
const char * amxs_sync_entry_get_name(const amxs_sync_entry_t *const entry, 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)
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)
bool amxs_sync_entry_direction_allowed(const amxs_sync_entry_t *const entry, amxs_sync_direction_t direction)
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)
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)
amxb_bus_ctx_t * amxs_sync_ctx_get_bus_ctx(const amxs_sync_ctx_t *const ctx, 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)
static void amxs_notify_instance_added(const amxc_var_t *input, amxs_sync_entry_t *entry, const amxs_sync_direction_t direction)
bool amxs_sync_entry_is_bidirectional(const amxs_sync_entry_t *entry)
amxp_signal_mngr_t * amxs_sync_entry_get_signal_manager(const amxs_sync_entry_t *const entry)
amxs_sync_entry_t * amxs_sync_entry_get_parent(const amxs_sync_entry_t *const entry)
amxd_dm_t * amxs_sync_ctx_get_dm(const amxs_sync_ctx_t *ctx, amxs_sync_direction_t direction)
#define AMXS_SYNC_ONLY_B_TO_A
Only synchronize from object B to object A.
#define AMXS_SYNC_ONLY_A_TO_B
Only synchronize from object A to object B.
#define AMXS_SYNC_PARAM_BATCH
Indicate that this parameter may be part of a batch copy operation.
amxs_sync_entry_type_t type
amxb_bus_ctx_t * bus_ctx_a
amxp_signal_mngr_t * sig_mngr
amxb_bus_ctx_t * bus_ctx_b
static amxb_bus_ctx_t * bus_ctx