libamxd  6.4.1
Data Model Manager
amxd_object_mib.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 
66 #include <amxd/amxd_types.h>
67 #include <amxd/amxd_object.h>
68 #include <amxd/amxd_dm.h>
69 #include <amxd/amxd_dm_functions.h>
70 #include <amxd/amxd_mib.h>
71 #include <amxd/amxd_object_event.h>
72 
73 #include "amxd_priv.h"
74 #include "amxd_dm_priv.h"
75 #include "amxd_object_priv.h"
76 #include "amxd_assert.h"
77 
78 static void amxd_object_remove_mib_params(amxd_object_t* const object,
79  amxd_object_t* const mib) {
80  amxc_llist_for_each(it, (&mib->parameters)) {
81  amxd_param_t* mib_param = amxc_llist_it_get_data(it, amxd_param_t, it);
82  const char* param_name = amxd_param_get_name(mib_param);
83  amxd_param_t* obj_param = amxd_object_get_param_def(object, param_name);
84  if(obj_param == NULL) {
85  continue;
86  }
87  amxd_param_free(&obj_param);
88  }
89 }
90 
92  amxd_object_t* const mib) {
93  amxc_llist_for_each(it, (&mib->functions)) {
94  amxd_function_t* mib_func = amxc_llist_it_get_data(it, amxd_function_t, it);
95  const char* func_name = amxd_function_get_name(mib_func);
96  amxd_function_t* obj_func = amxd_object_get_function(object, func_name);
97  if(obj_func == NULL) {
98  continue;
99  }
100  amxd_function_delete(&obj_func);
101  }
102 }
103 
105  amxd_object_t* const mib) {
106  amxc_llist_for_each(it, (&mib->objects)) {
107  amxd_object_t* mib_obj = amxc_llist_it_get_data(it, amxd_object_t, it);
108  const char* obj_name = amxd_object_get_name(mib_obj, AMXD_OBJECT_NAMED);
109  amxd_object_t* obj_child = amxd_object_get_child(object, obj_name);
110  if(obj_child == NULL) {
111  continue;
112  }
113  amxd_object_free(&obj_child);
114  }
115 }
116 
118  amxd_object_t* const mib) {
119  amxc_var_for_each(data, (&mib->events)) {
120  const char* name = amxc_var_key(data);
121  amxc_var_t* event = amxc_var_get_key(&object->events, name, AMXC_VAR_FLAG_DEFAULT);
122  amxc_var_delete(&event);
123  }
124 }
125 
126 static void amxd_object_clear_mib(amxd_object_t* const object,
127  const char* mib_name) {
128  amxc_array_it_t* ait = amxc_array_get_first(&object->mib_names);
129  while(ait != NULL) {
130  const char* name = (const char*) amxc_array_it_get_data(ait);
131  if(name != NULL) {
132  if(strcmp(name, mib_name) == 0) {
133  amxc_array_it_take_data(ait);
134  break;
135  }
136  }
137  ait = amxc_array_it_get_next(ait);
138  }
139 }
140 
141 static bool amxd_object_can_add_mib(amxd_object_t* const object,
142  amxd_object_t* const mib) {
143  bool retval = false;
144  amxc_llist_for_each(it, (&mib->objects)) {
145  amxd_object_t* mib_obj = amxc_llist_it_get_data(it, amxd_object_t, it);
146  const char* obj_name = amxd_object_get_name(mib_obj, AMXD_OBJECT_NAMED);
147  amxd_object_t* obj_child = amxd_object_get_child(object, obj_name);
148  when_true(obj_child != NULL, exit);
149  }
150 
151  amxc_llist_for_each(it, (&mib->parameters)) {
152  amxd_param_t* mib_param = amxc_llist_it_get_data(it, amxd_param_t, it);
153  const char* param_name = amxd_param_get_name(mib_param);
154  amxd_param_t* obj_param = amxd_object_get_param_def(object, param_name);
155  when_true(obj_param != NULL, exit);
156  }
157 
158  amxc_llist_for_each(it, (&mib->functions)) {
159  amxd_function_t* mib_func = amxc_llist_it_get_data(it, amxd_function_t, it);
160  const char* func_name = amxd_function_get_name(mib_func);
161  amxd_function_t* obj_func = amxd_object_get_self_func(object, func_name);
162  when_true(obj_func != NULL, exit);
163  }
164 
165  retval = true;
166 exit:
167  return retval;
168 }
169 
171  amxd_object_t* mib) {
172  amxc_llist_for_each(it, (&mib->objects)) {
173  amxd_object_t* base = amxc_llist_it_get_data(it, amxd_object_t, it);
174  const char* name = amxd_object_get_name(base, AMXD_OBJECT_NAMED);
175  amxd_object_t* child = amxd_object_get(object, name);
176  amxd_dm_event("dm:object-added", child, NULL, false);
177  amxd_object_send_add_objects(child, base);
178  }
179 }
180 
182  amxd_object_t* mib) {
183  amxc_llist_for_each(it, (&mib->objects)) {
184  amxd_object_t* base = amxc_llist_it_get_data(it, amxd_object_t, it);
185  const char* name = amxd_object_get_name(base, AMXD_OBJECT_NAMED);
186  amxd_object_t* child = amxd_object_get(object, name);
187  amxd_object_send_del_object(child, false);
188  }
189 }
190 
192  const char* mib_name,
193  bool added) {
194  amxc_var_t data;
195 
196  amxc_var_init(&data);
197  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
198  amxc_var_add_key(cstring_t, &data, "mib", mib_name);
199 
200  amxd_dm_event(added ? "dm:mib-added" : "dm:mib-removed", object, &data, false);
201 
202  amxc_var_clean(&data);
203 }
204 
206  char* mibs = NULL;
207  amxc_array_it_t* ait = NULL;
208  amxc_string_t str;
209 
210  amxc_string_init(&str, 0);
211  when_null(object, exit);
212 
213  ait = amxc_array_get_first(&object->mib_names);
214  while(ait != NULL) {
215  const char* name = (const char*) amxc_array_it_get_data(ait);
216  if(name != NULL) {
217  amxc_string_appendf(&str, "%s ", name);
218  }
219  ait = amxc_array_it_get_next(ait);
220  }
221 
222  amxc_string_trim(&str, NULL);
223  mibs = amxc_string_take_buffer(&str);
224 
225 exit:
226  amxc_string_clean(&str);
227  return mibs;
228 }
229 
231  const char* mib_name) {
232  bool retval = false;
233  amxc_array_it_t* ait = NULL;
234 
235  when_null(object, exit);
236  when_str_empty(mib_name, exit);
237 
238  ait = amxc_array_get_first(&object->mib_names);
239  while(ait != NULL) {
240  const char* name = (const char*) amxc_array_it_get_data(ait);
241  if(name != NULL) {
242  if(strcmp(name, mib_name) == 0) {
243  retval = true;
244  break;
245  }
246  }
247  ait = amxc_array_it_get_next(ait);
248  }
249 
250 exit:
251  return retval;
252 }
253 
255  const char* mib_name) {
257  amxd_dm_t* dm = amxd_object_get_dm(object);
258  amxd_object_t* mib = amxd_dm_get_mib(dm, mib_name);
259  amxc_array_it_t* ait = NULL;
260 
261  when_null(dm, exit);
262  when_null_status(mib, exit, status = amxd_status_object_not_found);
263  if(amxd_object_has_mib(object, mib_name) ||
264  !amxd_object_can_add_mib(object, mib)) {
266  goto exit;
267  }
268 
269  amxd_object_copy_children(object, mib);
270  amxd_object_send_add_objects(object, mib);
271  amxd_object_copy_params(object, mib);
272  amxd_object_copy_funcs(object, mib);
273  amxd_object_copy_events(object, mib);
274 
275  mib_name = amxd_object_get_name(mib, AMXD_OBJECT_NAMED);
276  amxd_object_send_mib(object, mib_name, true);
277  ait = amxc_array_get_first_free(&object->mib_names);
278  if(ait == NULL) {
279  amxc_array_append_data(&object->mib_names, (void*) mib_name);
280  } else {
281  amxc_array_it_set_data(ait, (void*) mib_name);
282  }
283 
285 
286 exit:
287  return status;
288 }
289 
291  const char* mib_name) {
293  amxd_dm_t* dm = amxd_object_get_dm(object);
294  amxd_object_t* mib = amxd_dm_get_mib(dm, mib_name);
295 
296  when_null(dm, exit);
297  when_null_status(mib, exit, status = amxd_status_object_not_found);
298  when_false_status(amxd_object_has_mib(object, mib_name), exit, status = amxd_status_ok);
299 
300  mib_name = amxd_object_get_name(mib, AMXD_OBJECT_NAMED);
301  amxd_object_send_mib(object, mib_name, false);
302  amxd_object_remove_mib_params(object, mib);
304  amxd_object_send_del_objects(object, mib);
305  amxd_object_remove_mib_objects(object, mib);
306  amxd_object_remove_mib_events(object, mib);
307  amxd_object_clear_mib(object, mib_name);
308 
310 exit:
311  return status;
312 }
313 
315  when_null(mib, exit);
316  when_null(*mib, exit);
317 
318  when_true(amxd_object_get_type(*mib) != amxd_object_mib, exit);
319 
320  amxd_object_free(mib);
321 
322 exit:
323  return;
324 }
Ambiorix Data Model API header file.
amxd_object_t * amxd_dm_get_mib(amxd_dm_t *const dm, const char *name)
Definition: amxd_dm.c:397
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.
Ambiorix Data Model API header file.
void amxd_object_send_del_object(amxd_object_t *object, bool trigger)
void amxd_mib_delete(amxd_object_t **mib)
static void amxd_object_remove_mib_functions(amxd_object_t *const object, amxd_object_t *const mib)
static bool amxd_object_can_add_mib(amxd_object_t *const object, amxd_object_t *const mib)
static void amxd_object_send_del_objects(amxd_object_t *object, amxd_object_t *mib)
static void amxd_object_remove_mib_params(amxd_object_t *const object, amxd_object_t *const mib)
static void amxd_object_send_mib(amxd_object_t *object, const char *mib_name, bool added)
static void amxd_object_clear_mib(amxd_object_t *const object, const char *mib_name)
static void amxd_object_remove_mib_objects(amxd_object_t *const object, amxd_object_t *const mib)
static void amxd_object_send_add_objects(amxd_object_t *object, amxd_object_t *mib)
static void amxd_object_remove_mib_events(amxd_object_t *const object, amxd_object_t *const mib)
PRIVATE amxd_status_t amxd_object_copy_funcs(amxd_object_t *const dst, const amxd_object_t *const src)
PRIVATE amxd_function_t * amxd_object_get_self_func(const amxd_object_t *const object, const char *name)
PRIVATE amxd_status_t amxd_object_copy_events(amxd_object_t *const dst, const amxd_object_t *const src)
PRIVATE amxd_status_t amxd_object_copy_params(amxd_object_t *const dst, const amxd_object_t *const src)
PRIVATE amxd_status_t amxd_object_copy_children(amxd_object_t *const dst, const amxd_object_t *const src)
const char * amxd_param_get_name(const amxd_param_t *const param)
void PRIVATE amxd_param_free(amxd_param_t **param)
enum _amxd_status amxd_status_t
@ 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_duplicate
Definition: amxd_types.h:91
#define AMXD_OBJECT_NAMED
Name and path format flag - default behavior, use name for instance objects.
Definition: amxd_object.h:164
@ amxd_object_mib
Definition: amxd_types.h:188
amxd_object_t * amxd_object_get_child(const amxd_object_t *object, const char *name)
Get a child of the object.
amxd_dm_t * amxd_object_get_dm(const amxd_object_t *const object)
Get the data model.
amxd_object_t * amxd_object_get(const amxd_object_t *object, const char *name)
Get an instance or child of an object.
bool amxd_object_has_mib(amxd_object_t *object, const char *mib_name)
Checks if a mib has been added to a data model object.
char * amxd_object_get_mibs(amxd_object_t *object)
Get the names of all mibs attached to this object.
amxd_status_t amxd_object_add_mib(amxd_object_t *const object, const char *mib_name)
Adds a mib to an object.
amxd_status_t amxd_object_remove_mib(amxd_object_t *const object, const char *mib_name)
Removes a mib from 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.
amxd_function_t * amxd_object_get_function(const amxd_object_t *const object, const char *name)
Get the definition of a RPC method 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
void amxd_object_free(amxd_object_t **object)
Data model object destructor function.
Definition: amxd_object.c:153
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
const char * amxd_function_get_name(const amxd_function_t *const func)
Get the name of a method.
void amxd_function_delete(amxd_function_t **func)
Data model RPC method destructor function.
RPC method structure.
Definition: amxd_types.h:341
amxc_llist_t functions
Definition: amxd_types.h:245
amxc_llist_t objects
Definition: amxd_types.h:243
amxc_array_t mib_names
Definition: amxd_types.h:254
amxc_var_t events
Definition: amxd_types.h:256
amxc_llist_t parameters
Definition: amxd_types.h:246
static amxd_dm_t dm
static amxd_status_t status