libamxs  0.6.0
Data Model Synchronization C API
dummy_be.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 #include <stdlib.h>
55 #include <string.h>
56 
57 #include <amxc/amxc.h>
58 #include <amxp/amxp.h>
59 #include <amxd/amxd_dm.h>
60 #include <amxd/amxd_object.h>
61 #include <amxd/amxd_object_function.h>
62 #include <amxb/amxb_be.h>
63 #include <amxo/amxo.h>
64 
65 #include "dummy_be.h"
66 
67 #include <amxc/amxc_macros.h>
68 static amxd_dm_t remote_dm;
69 static amxo_parser_t parser;
70 static uint32_t caps = AMXB_BE_DISCOVER_DESCRIBE | AMXB_BE_DISCOVER_LIST | AMXB_BE_DISCOVER;
71 static amxp_signal_mngr_t* dummy_sigmngr = NULL;
72 static amxc_htable_t subscriptions;
73 
74 static void amxb_dummy_send_notification(const char* const sig_name,
75  const amxc_var_t* const data,
76  void* const priv) {
77  amxc_var_t notification;
78  amxc_htable_it_t* it = (amxc_htable_it_t*) priv;
79  amxc_var_init(&notification);
80  amxc_var_set_type(&notification, AMXC_VAR_ID_HTABLE);
81 
82  amxc_var_copy(&notification, data);
83  amxc_var_add_key(cstring_t, &notification, "notification", sig_name);
84 
85  amxp_sigmngr_emit_signal(dummy_sigmngr, amxc_htable_it_get_key(it), &notification);
86 
87  amxc_var_clean(&notification);
88 }
89 
90 static void amxb_dummy_free_subscription(UNUSED const char* key, amxc_htable_it_t* it) {
91  free(it);
92 }
93 
94 static void* amxb_dummy_connect(UNUSED const char* host,
95  UNUSED const char* port,
96  UNUSED const char* path,
97  UNUSED amxp_signal_mngr_t* sigmngr) {
98 
99  amxd_dm_init(&remote_dm);
100  amxo_parser_init(&parser);
101  dummy_sigmngr = sigmngr;
102  return &remote_dm;
103 }
104 
105 static int amxb_dummy_disconnect(UNUSED void* ctx) {
106  amxd_dm_clean(&remote_dm);
107  dummy_sigmngr = NULL;
108  return 0;
109 }
110 
111 static int amxb_dummy_invoke(UNUSED void* const ctx,
112  amxb_invoke_t* invoke_ctx,
113  amxc_var_t* args,
114  amxb_request_t* request,
115  UNUSED int timeout) {
116 
117  amxc_var_t empty_args;
118  amxc_var_t* return_value = NULL;
119  amxc_var_init(&empty_args);
120  amxc_var_set_type(&empty_args, AMXC_VAR_ID_HTABLE);
121  amxc_var_set_type(request->result, AMXC_VAR_ID_LIST);
122 
123  int rv = 0;
124 
125  if(args == NULL) {
126  args = &empty_args;
127  }
128 
129  return_value = amxc_var_add_new(request->result);
130  amxd_object_t* obj = amxd_dm_findf(&remote_dm, invoke_ctx->object);
131  if(obj == NULL) {
132  rv = amxd_status_invalid_path;
133  } else {
134  rv = amxd_object_invoke_function(obj, invoke_ctx->method, args, return_value);
135  }
136 
137  amxc_var_clean(&empty_args);
138  return rv;
139 }
140 
141 static void amxb_dummy_free(UNUSED void* ctx) {
142  amxo_parser_clean(&parser);
143  amxd_dm_clean(&remote_dm);
144 }
145 
146 static int amxb_dummy_register(UNUSED void* const ctx,
147  UNUSED amxd_dm_t* const dm) {
148  return 0;
149 }
150 
151 static bool amxb_dummy_has(UNUSED void* const ctx,
152  const char* object) {
153  amxd_object_t* obj = amxd_dm_findf(&remote_dm, "%s", object);
154 
155  return obj != NULL;
156 }
157 
158 static uint32_t amxb_dummy_capabilities(UNUSED void* const ctx) {
159  return caps;
160 }
161 
162 static int amxb_dummy_subscribe(UNUSED void* const ctx,
163  const char* object) {
164 
165  int retval = 0;
166  amxc_string_t expression;
167  amxc_htable_it_t* it = NULL;
168 
169  amxc_string_init(&expression, 0);
170 
171  when_failed(retval, exit);
172 
173  it = (amxc_htable_it_t*) calloc(1, sizeof(amxc_htable_it_t));
174  amxc_htable_insert(&subscriptions, object, it);
175  amxc_string_appendf(&expression, "path starts with \"%s.\"", object);
176  amxp_slot_connect_filtered(&remote_dm.sigmngr,
177  ".*",
178  amxc_string_get(&expression, 0),
180  it);
181 
182 exit:
183  amxc_string_clean(&expression);
184  return retval;
185 }
186 
187 static int amxb_dummy_unsubscribe(UNUSED void* const ctx,
188  const char* object) {
189  amxc_htable_it_t* it = amxc_htable_get(&subscriptions, object);
190  if(it != NULL) {
191  amxp_slot_disconnect_with_priv(&remote_dm.sigmngr, amxb_dummy_send_notification, it);
192  }
193  amxc_htable_it_clean(it, amxb_dummy_free_subscription);
194 
195  return 0;
196 }
197 
198 static amxb_be_funcs_t amxb_dummy_impl = {
199  .connect = amxb_dummy_connect,
200  .disconnect = amxb_dummy_disconnect,
201  .get_fd = NULL,
202  .read = NULL,
203  .invoke = amxb_dummy_invoke,
204  .async_invoke = NULL,
205  .wait_request = NULL,
206  .close_request = NULL,
207  .subscribe = amxb_dummy_subscribe,
208  .unsubscribe = amxb_dummy_unsubscribe,
209  .free = amxb_dummy_free,
210  .register_dm = amxb_dummy_register,
211  .has = amxb_dummy_has,
212  .capabilities = amxb_dummy_capabilities,
213  .name = "dummy",
214  .size = sizeof(amxb_be_funcs_t),
215 };
216 
217 static amxb_version_t sup_min_lib_version = {
218  .major = 2,
219  .minor = 0,
220  .build = -1
221 };
222 
223 static amxb_version_t sup_max_lib_version = {
224  .major = 2,
225  .minor = -1,
226  .build = -1
227 };
228 
229 static amxb_version_t dummy_be_version = {
230  .major = 0,
231  .minor = 0,
232  .build = 0,
233 };
234 
235 amxb_be_info_t amxb_dummy_be_info = {
236  .min_supported = &sup_min_lib_version,
237  .max_supported = &sup_max_lib_version,
238  .be_version = &dummy_be_version,
239  .name = "dummy",
240  .description = "AMXB Dummy Backend for testing",
241  .funcs = &amxb_dummy_impl,
242 };
243 
245  amxc_htable_init(&subscriptions, 5);
246  return amxb_be_register(&amxb_dummy_impl);
247 }
248 
250  amxc_htable_clean(&subscriptions, amxb_dummy_free_subscription);
251  return amxb_be_unregister(&amxb_dummy_impl);
252 }
253 
254 int test_load_dummy_remote(const char* odl) {
255  amxd_object_t* root_obj = amxd_dm_get_root(&remote_dm);
256 
257  return amxo_parser_parse_file(&parser, odl, root_obj);
258 }
259 
260 void test_set_dummy_caps(uint32_t dummy_caps) {
261  caps = dummy_caps;
262 }
263 
264 amxd_dm_t* test_get_dm(void) {
265  return &remote_dm;
266 }
267 
268 amxo_parser_t* test_get_parser(void) {
269  return &parser;
270 }
static amxd_dm_t remote_dm
Definition: dummy_be.c:68
static amxc_htable_t subscriptions
Definition: dummy_be.c:72
void test_set_dummy_caps(uint32_t dummy_caps)
Definition: dummy_be.c:260
static void amxb_dummy_send_notification(const char *const sig_name, const amxc_var_t *const data, void *const priv)
Definition: dummy_be.c:74
static amxp_signal_mngr_t * dummy_sigmngr
Definition: dummy_be.c:71
static void amxb_dummy_free(UNUSED void *ctx)
Definition: dummy_be.c:141
amxo_parser_t * test_get_parser(void)
Definition: dummy_be.c:268
static int amxb_dummy_subscribe(UNUSED void *const ctx, const char *object)
Definition: dummy_be.c:162
amxb_be_info_t amxb_dummy_be_info
Definition: dummy_be.c:235
static amxo_parser_t parser
Definition: dummy_be.c:69
static int amxb_dummy_disconnect(UNUSED void *ctx)
Definition: dummy_be.c:105
amxd_dm_t * test_get_dm(void)
Definition: dummy_be.c:264
static uint32_t caps
Definition: dummy_be.c:70
static uint32_t amxb_dummy_capabilities(UNUSED void *const ctx)
Definition: dummy_be.c:158
static amxb_be_funcs_t amxb_dummy_impl
Definition: dummy_be.c:198
static int amxb_dummy_register(UNUSED void *const ctx, UNUSED amxd_dm_t *const dm)
Definition: dummy_be.c:146
static int amxb_dummy_unsubscribe(UNUSED void *const ctx, const char *object)
Definition: dummy_be.c:187
int test_unregister_dummy_be(void)
Definition: dummy_be.c:249
static bool amxb_dummy_has(UNUSED void *const ctx, const char *object)
Definition: dummy_be.c:151
static amxb_version_t dummy_be_version
Definition: dummy_be.c:229
static int amxb_dummy_invoke(UNUSED void *const ctx, amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxb_request_t *request, UNUSED int timeout)
Definition: dummy_be.c:111
static void amxb_dummy_free_subscription(UNUSED const char *key, amxc_htable_it_t *it)
Definition: dummy_be.c:90
int test_load_dummy_remote(const char *odl)
Definition: dummy_be.c:254
int test_register_dummy_be(void)
Definition: dummy_be.c:244
static amxb_version_t sup_max_lib_version
Definition: dummy_be.c:223
static void * amxb_dummy_connect(UNUSED const char *host, UNUSED const char *port, UNUSED const char *path, UNUSED amxp_signal_mngr_t *sigmngr)
Definition: dummy_be.c:94
static amxb_version_t sup_min_lib_version
Definition: dummy_be.c:217