TR181-XPON  1.4.0
TR-181 PON manager.
module_mgmt.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2022 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or
8 ** without modification, are permitted provided that the following
9 ** conditions are met:
10 **
11 ** 1. Redistributions of source code must retain the above copyright
12 ** notice, this list of conditions and the following disclaimer.
13 **
14 ** 2. Redistributions in binary form must reproduce the above
15 ** copyright notice, this list of conditions and the following
16 ** disclaimer in the documentation and/or other materials provided
17 ** with the distribution.
18 **
19 ** Subject to the terms and conditions of this license, each
20 ** copyright holder and contributor hereby grants to those receiving
21 ** rights under this license a perpetual, worldwide, non-exclusive,
22 ** no-charge, royalty-free, irrevocable (except for failure to
23 ** satisfy the conditions of this license) patent license to make,
24 ** have made, use, offer to sell, sell, import, and otherwise
25 ** transfer this software, where such license applies only to those
26 ** patent claims, already acquired or hereafter acquired, licensable
27 ** by such copyright holder or contributor that are necessarily
28 ** infringed by:
29 **
30 ** (a) their Contribution(s) (the licensed copyrights of copyright
31 ** holders and non-copyrightable additions of contributors, in
32 ** source or binary form) alone; or
33 **
34 ** (b) combination of their Contribution(s) with the work of
35 ** authorship to which such Contribution(s) was added by such
36 ** copyright holder or contributor, if, at the time the Contribution
37 ** is added, such addition causes such combination to be necessarily
38 ** infringed. The patent license shall not apply to any other
39 ** combinations which include the Contribution.
40 **
41 ** Except as expressly stated above, no rights or licenses from any
42 ** copyright holder or contributor is granted under this license,
43 ** whether expressly, by implication, estoppel or otherwise.
44 **
45 ** DISCLAIMER
46 **
47 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
48 ** CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
49 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
50 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
52 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
54 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
55 ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
56 ** AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
58 ** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 ** POSSIBILITY OF SUCH DAMAGE.
60 **
61 ****************************************************************************/
62 
63 /* Related header */
64 #include "module_mgmt.h"
65 
66 /* System headers */
67 #include <dlfcn.h> /* dlerror() */
68 #include <stdlib.h> /* free() */
69 #include <unistd.h> /* access() */
70 
71 /* Other libraries' headers */
72 #include <amxc/amxc_macros.h>
73 #include <amxc/amxc.h>
74 #include <amxm/amxm.h>
75 #include <amxp/amxp_dir.h> /* amxp_dir_scan() */
76 
77 /* Own headers */
78 #include "data_model.h" /* dm_get_vendor_module() */
79 #include "pon_stat.h" /* dm_instance_added() */
80 #include "pon_cfg.h" /* pon_cfg_get_param_value() */
81 #include "xpon_trace.h"
82 
83 #define MOD_PON_STAT "pon_stat"
84 #define MOD_PON_CFG "pon_cfg"
85 
86 static const char* const MODULES_PATH = "/usr/lib/amx/tr181-xpon/modules/";
87 
88 static amxm_module_t* s_pon_stat_module = NULL;
89 static amxm_module_t* s_pon_cfg_module = NULL;
90 static amxc_string_t s_module_name; /* name of vendor module */
91 static amxm_shared_object_t* s_module_so = NULL; /* vendor module loaded */
92 
93 typedef struct _pon_stat_function {
94  const char* name;
95  amxm_callback_t impl;
97 
99 
100  { .name = "dm_instance_added", .impl = dm_instance_added },
101  { .name = "dm_instance_removed", .impl = dm_instance_removed },
102  { .name = "dm_object_changed", .impl = dm_object_changed },
103  { .name = "dm_add_or_change_instance", .impl = dm_add_or_change_instance },
104  { .name = "omci_reset_mib", .impl = omci_reset_mib },
105  { .name = "watch_file_descriptor_start", .impl = watch_file_descriptor_start },
106  { .name = "watch_file_descriptor_stop", .impl = watch_file_descriptor_stop },
107  { .name = "dm_set_xpon_parameter", .impl = dm_set_xpon_parameter },
108  { .name = NULL, .impl = NULL } /* sentinel */
109 };
110 
112 
113  { .name = "pon_cfg_get_param_value", .impl = pon_cfg_get_param_value },
114  { .name = NULL, .impl = NULL } /* sentinel */
115 };
116 
117 static bool register_pon_stat_module(void) {
118 
119  bool rv = false;
120  amxm_shared_object_t* so = amxm_get_so("self");
121  if(!so) {
122  SAH_TRACEZ_ERROR(ME, "Failed to get amxm_shared_object_t for self");
123  goto exit;
124  }
125 
126  if(amxm_module_register(&s_pon_stat_module, so, MOD_PON_STAT)) {
127  SAH_TRACEZ_ERROR(ME, "Failed to register %s module namespace", MOD_PON_STAT);
128  goto exit;
129  }
130 
131  int i;
132  for(i = 0; PON_STAT_FUNCTIONS[i].name != NULL; ++i) {
133  if(amxm_module_add_function(s_pon_stat_module, PON_STAT_FUNCTIONS[i].name,
134  PON_STAT_FUNCTIONS[i].impl)) {
135  SAH_TRACEZ_ERROR(ME, "Failed to register self.%s.%s()", MOD_PON_STAT,
136  PON_STAT_FUNCTIONS[i].name);
137  }
138  }
139  rv = true;
140 
141 exit:
142  return rv;
143 }
144 
145 static bool register_pon_cfg_module(void) {
146 
147  bool rv = false;
148  amxm_shared_object_t* so = amxm_get_so("self");
149  if(!so) {
150  SAH_TRACEZ_ERROR(ME, "Failed to get amxm_shared_object_t for self");
151  goto exit;
152  }
153 
154  if(amxm_module_register(&s_pon_cfg_module, so, MOD_PON_CFG)) {
155  SAH_TRACEZ_ERROR(ME, "Failed to register %s module namespace", MOD_PON_CFG);
156  goto exit;
157  }
158 
159  int i;
160  for(i = 0; PON_CFG_FUNCTIONS[i].name != NULL; ++i) {
161  if(amxm_module_add_function(s_pon_cfg_module, PON_CFG_FUNCTIONS[i].name,
162  PON_CFG_FUNCTIONS[i].impl)) {
163  SAH_TRACEZ_ERROR(ME, "Failed to register self.%s.%s()", MOD_PON_CFG,
164  PON_CFG_FUNCTIONS[i].name);
165  }
166  }
167  rv = true;
168 
169 exit:
170  return rv;
171 }
172 
173 
183 static int handle_vendor_module_match(const char* name, void* priv UNUSED) {
184  SAH_TRACEZ_DEBUG(ME, "match: '%s'", name);
185 
186  int rc = 0; /* keep scanning */
187 
188  amxc_string_t module;
189  amxc_string_init(&module, 0);
190  amxc_string_setf(&module, "%s", name);
191  amxc_string_replace(&module, MODULES_PATH, "", /*max= */ 1);
192  amxc_string_replace(&module, ".so", "", /*max= */ 1);
193  const char* const module_cstr = amxc_string_get(&module, 0);
194 
195  if(amxc_string_is_empty(&s_module_name)) {
196  amxc_string_copy(&s_module_name, &module);
197  SAH_TRACEZ_DEBUG(ME, "Found vendor module: '%s.so'", module_cstr);
198  dm_set_vendor_module(module_cstr);
199  } else {
200  SAH_TRACEZ_ERROR(ME, "Found more than one vendor module");
201  SAH_TRACEZ_ERROR(ME, " modules found: %s.so, %s.so",
202  amxc_string_get(&s_module_name, 0), module_cstr);
203  rc = 1; /* error, stop scanning */
204  }
205 
206  amxc_string_clean(&module);
207  return rc;
208 }
209 
213 static bool find_vendor_module(void) {
214 
215  const char* const filter = "d_type == DT_REG && d_name matches 'mod-xpon-.*\\.so'";
216 
217  if(amxp_dir_scan(MODULES_PATH, filter, false, handle_vendor_module_match, NULL) != 0) {
218  /* handle_vendor_module_match() already logged error */
219  return false;
220  }
221 
222  if(amxc_string_is_empty(&s_module_name)) {
223  SAH_TRACEZ_ERROR(ME, "Failed to find vendor module");
224  return false;
225  }
226  return true;
227 }
228 
246 static bool load_vendor_module(void) {
247 
248  bool rv = false;
249 
250  amxc_string_t mod_path;
251  amxc_string_init(&mod_path, 0);
252 
253  if(!find_vendor_module()) {
254  goto exit;
255  }
256  const char* const module = amxc_string_get(&s_module_name, 0);
257  amxc_string_setf(&mod_path, "%s%s.so", MODULES_PATH, module);
258 
259  const char* const path_to_so = amxc_string_get(&mod_path, /*offset=*/ 0);
260 
261  if(access(path_to_so, F_OK) != 0) {
262  SAH_TRACEZ_ERROR(ME, "%s does not exist", path_to_so);
263  goto exit;
264  }
265 
266  if(amxm_so_open(&s_module_so, module, path_to_so)) {
267  const char* error = dlerror();
268  SAH_TRACEZ_ERROR(ME, "Failed to load %s module", module);
269  SAH_TRACEZ_ERROR(ME, "dlerror(): '%s'", error ? error : "No error");
270  goto exit;
271  }
272 
273  rv = true;
274 
275 exit:
276  if(!rv) {
278  }
279  amxc_string_clean(&mod_path);
280  return rv;
281 }
282 
299 bool mod_module_mgmt_init(bool* module_error) {
300 
301  amxc_string_init(&s_module_name, 0);
302 
303  if(!register_pon_stat_module()) {
304  return false;
305  }
306 
307  if(!register_pon_cfg_module()) {
308  return false;
309  }
310 
311  if(!load_vendor_module()) {
312  if(module_error) {
313  *module_error = true;
314  }
315  return false;
316  }
317  return true;
318 }
319 
326 const char* mod_get_vendor_module_loaded(void) {
327 
328  return s_module_so ? amxc_string_get(&s_module_name, 0) : NULL;
329 }
330 
341 
342  if(s_module_so) {
343  if(amxm_so_close(&s_module_so)) {
344  SAH_TRACEZ_ERROR(ME, "Failed to close module");
345  }
346  }
347 
348  if(s_pon_stat_module) {
349  amxm_module_deregister(&s_pon_stat_module);
350  }
351  if(s_pon_cfg_module) {
352  amxm_module_deregister(&s_pon_cfg_module);
353  }
354  amxc_string_clean(&s_module_name);
355 }
void dm_set_module_error(void)
Definition: data_model.c:192
void dm_set_vendor_module(const char *name)
Definition: data_model.c:178
const char * mod_get_vendor_module_loaded(void)
Definition: module_mgmt.c:326
#define MOD_PON_STAT
Definition: module_mgmt.c:83
static bool load_vendor_module(void)
Definition: module_mgmt.c:246
static const pon_stat_function_t PON_CFG_FUNCTIONS[]
Definition: module_mgmt.c:111
struct _pon_stat_function pon_stat_function_t
#define MOD_PON_CFG
Definition: module_mgmt.c:84
static amxc_string_t s_module_name
Definition: module_mgmt.c:90
static bool register_pon_cfg_module(void)
Definition: module_mgmt.c:145
static const pon_stat_function_t PON_STAT_FUNCTIONS[]
Definition: module_mgmt.c:98
static amxm_module_t * s_pon_cfg_module
Definition: module_mgmt.c:89
void mod_module_mgmt_cleanup(void)
Definition: module_mgmt.c:340
static amxm_shared_object_t * s_module_so
Definition: module_mgmt.c:91
static amxm_module_t * s_pon_stat_module
Definition: module_mgmt.c:88
bool mod_module_mgmt_init(bool *module_error)
Definition: module_mgmt.c:299
static const char *const MODULES_PATH
Definition: module_mgmt.c:86
static int handle_vendor_module_match(const char *name, void *priv UNUSED)
Definition: module_mgmt.c:183
static bool find_vendor_module(void)
Definition: module_mgmt.c:213
static bool register_pon_stat_module(void)
Definition: module_mgmt.c:117
int pon_cfg_get_param_value(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
Definition: pon_cfg.c:85
int dm_instance_added(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int watch_file_descriptor_start(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int dm_object_changed(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int dm_instance_removed(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int dm_add_or_change_instance(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int watch_file_descriptor_stop(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int dm_set_xpon_parameter(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
int omci_reset_mib(const char *function_name, amxc_var_t *args, amxc_var_t *ret)
const char * name
Definition: module_mgmt.c:94
amxm_callback_t impl
Definition: module_mgmt.c:95
#define SAH_TRACEZ_DEBUG(zone, format,...)
Definition: xpon_trace.h:115
#define ME
Definition: xpon_trace.h:78