TR181-XPON  1.4.0
TR-181 PON manager.
data_model.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 "data_model.h"
65 
66 /* System headers */
67 #include <stdio.h> /* snprintf() */
68 #include <stdlib.h> /* free() */
69 #include <string.h> /* strncmp() */
70 
71 /* Other libraries' headers */
72 #include <amxc/amxc.h>
73 
79 #include <amxp/amxp.h>
80 #include <amxd/amxd_object.h>
81 #include <amxd/amxd_transaction.h>
82 
83 /* Own headers */
84 #include "ani.h" /* ani_append_tc_authentication() */
85 #include "dm_actions.h" /* dm_actions_set_ignore_param_reads() */
86 #include "dm_info.h"
87 #include "dm_xpon_mngr.h" /* xpon_mngr_get_dm() */
88 #include "onu_priv.h" /* onu_priv_attach_private_data() */
89 #include "persistency.h"
90 #include "password.h"
91 #include "restore_to_hal.h" /* rth_schedule_enable() */
92 #include "xpon_trace.h"
93 
94 #define ADD_INST_N_ARGS_REQUIRED 3
96  "path", "index", "keys"
97 };
98 
99 #define REMOVE_INST_N_ARGS_REQUIRED 2
101  "path", "index"
102 };
103 
104 #define CHANGE_OBJ_N_ARGS_REQUIRED 2
106  "path", "parameters"
107 };
108 
109 #define ADD_OR_CHANGE_INST_N_ARGS_REQUIRED 2
111  "path", "index"
112 };
113 
114 
133 typedef struct _dm_action_info {
134  const char* path;
135  uint32_t index;
137  amxc_var_t* key_value;
138  const amxc_var_t* params;
140 
141 static void init_dm_action_info(dm_action_info_t* const info) {
142 
143  info->path = NULL;
144  info->index = 0;
145  info->obj_id = obj_id_unknown;
146  info->key_value = NULL;
147  info->params = NULL;
148 }
149 
153 static amxd_object_t* dm_get_xpon_object(void) {
154 
155  amxd_dm_t* const dm = xpon_mngr_get_dm();
156  if(!dm) {
157  SAH_TRACEZ_ERROR(ME, "Failed to get DM");
158  return NULL;
159  }
160 
161 
162  amxd_object_t* xpon = amxd_dm_get_object(dm, "XPON");
163  if(!xpon) {
164  SAH_TRACEZ_ERROR(ME, "Failed to get XPON object");
165  return NULL;
166  }
167  return xpon;
168 }
169 
178 void dm_set_vendor_module(const char* name) {
179 
180  amxd_object_t* xpon = dm_get_xpon_object();
181  when_null(xpon, exit);
182  if(amxd_object_set_value(cstring_t, xpon, "ModuleName", name)) {
183  SAH_TRACEZ_ERROR(ME, "Failed to update XPON.ModuleName");
184  }
185 exit:
186  return;
187 }
188 
193 
194  amxd_object_t* xpon = dm_get_xpon_object();
195  when_null(xpon, exit);
196  if(amxd_object_set_value(bool, xpon, "ModuleError", true)) {
197  SAH_TRACEZ_ERROR(ME, "Failed to set XPON.ModuleError to true");
198  }
199 exit:
200  return;
201 }
202 
203 static bool get_ref_to_params(const amxc_var_t* const args,
204  const amxc_var_t** params) {
205  bool rv = false;
206 
207  const amxc_var_t* const params_var =
208  amxc_var_get_key(args, "parameters", AMXC_VAR_FLAG_DEFAULT);
209  when_null_trace(params_var, exit, ERROR, "Failed to get 'parameters' from 'args'");
210 
211  const uint32_t params_type = amxc_var_type_of(params_var);
212  when_false_trace(AMXC_VAR_ID_HTABLE == params_type, exit, ERROR,
213  "Type of 'parameters' = %d != htable", params_type);
214 
215  *params = params_var;
216 
217  rv = true;
218 exit:
219  return rv;
220 }
221 
244 static bool process_args_common(const amxc_var_t* const args,
245  dm_action_info_t* info,
246  const char** keys_required,
247  int n_keys_required) {
248  bool rv = false;
249  uint32_t index = 0;
250  const amxc_var_t* params = NULL;
251 
252  SAH_TRACEZ_DEBUG2(ME, "called");
253 
254  when_null_trace(args, exit, ERROR, "args is NULL");
255 
256 #ifdef _DEBUG_
257  printf("tr181-xpon: process_args_common(): dump(args):\n");
258  amxc_var_dump(args, STDOUT_FILENO);
259 #endif
260 
261  init_dm_action_info(info);
262 
263  const amxc_htable_t* const htable = amxc_var_constcast(amxc_htable_t, args);
264  when_null_trace(htable, exit, ERROR, "args is not an htable");
265 
266  int i;
267  for(i = 0; i < n_keys_required; ++i) {
268  if(!amxc_htable_contains(htable, keys_required[i])) {
269  SAH_TRACEZ_ERROR(ME, "args does not contain key '%s'", keys_required[i]);
270  goto exit;
271  }
272  if((index == 0) && (strncmp(keys_required[i], "index", 5) == 0)) {
273  index = GET_UINT32(args, "index");
274  if(0 == index) {
275  SAH_TRACEZ_ERROR(ME, "Failed to get valid index");
276  goto exit;
277  }
278  }
279  }
280 
281  const char* const path = GET_CHAR(args, "path");
282  when_null_trace(path, exit, ERROR, "Failed to get path");
283 
284  const object_id_t obj_id = dm_get_object_id(path);
285  when_false_trace(obj_id_unknown != obj_id, exit, ERROR,
286  "path='%s': failed to get ID", path);
287 
288  /* Get 'index' if it's in 'args' even it's not required */
289  if((index == 0) && amxc_htable_contains(htable, "index")) {
290  index = GET_UINT32(args, "index");
291  if(0 == index) {
292  SAH_TRACEZ_ERROR(ME, "Failed to get valid index");
293  }
294  }
295 
296  info->path = path;
297  info->index = index;
298  info->obj_id = obj_id;
299 
300  if(amxc_htable_contains(htable, "parameters")) {
301  if(get_ref_to_params(args, &params)) {
302  info->params = params;
303  }
304  }
305  rv = true;
306 exit:
307  return rv;
308 }
309 
326 static bool process_add_instance_args(const amxc_var_t* const args,
327  dm_action_info_t* info) {
328 
329  bool rv = false;
330  SAH_TRACEZ_DEBUG2(ME, "called");
331 
334  goto exit;
335  }
336 
337  const object_id_t obj_id = info->obj_id;
338  const object_info_t* const obj_info = dm_get_object_info(obj_id);
339  when_null_trace(obj_info, exit, ERROR, "obj_info is NULL for obj_id=%d", obj_id);
340 
341  const char* key_name = obj_info->key_name; /* alias */
342 
343  const amxc_var_t* const keys_var = amxc_var_get_key(args, "keys", AMXC_VAR_FLAG_DEFAULT);
344  when_null_trace(keys_var, exit, ERROR, "%s.%d: failed to get 'keys' from args",
345  info->path, info->index);
346 
347  if(amxc_var_type_of(keys_var) != AMXC_VAR_ID_HTABLE) {
348  SAH_TRACEZ_ERROR(ME, "%s.%d: variant 'keys' is not an htable",
349  info->path, info->index);
350  goto exit;
351  }
352  amxc_var_t* key_value =
353  amxc_var_get_key(keys_var, key_name, AMXC_VAR_FLAG_DEFAULT);
354  when_null_trace(key_value, exit, ERROR, "%s.%d: failed to get value for key='%s'",
355  info->path, info->index, key_name);
356 
357  /* If the key name is "Name", its value is of type string, else its value
358  * is of type uint32_t. */
359  const bool key_is_uint32 =
360  strncmp(key_name, NAME_PARAM, NAME_PARAM_LEN) != 0;
361 
362  if(key_is_uint32) {
363  const uint32_t key_uint32 = amxc_var_constcast(uint32_t, key_value);
364  if(key_uint32 > obj_info->key_max_value) {
365  SAH_TRACEZ_ERROR(ME, "%s.%d: key: %s: value=%d > max=%d",
366  info->path, info->index, key_name, key_uint32,
367  obj_info->key_max_value);
368  goto exit;
369  }
370  }
371 
372  info->key_value = key_value;
373 
374  rv = true;
375 exit:
376  return rv;
377 }
378 
389 static bool prepare_adding_instance(const char* const path, uint32_t index,
390  amxd_object_t** templ) {
391 
392  bool rv = false;
393  when_null(path, exit);
394  when_null(templ, exit);
395 
396  amxd_dm_t* const dm = xpon_mngr_get_dm();
397  when_null(dm, exit);
398 
399  amxd_object_t* templ_candidate = amxd_dm_findf(dm, "%s", path);
400  when_null_trace(templ_candidate, exit, ERROR, "%s does not exist", path);
401 
402  const amxd_object_type_t type = amxd_object_get_type(templ_candidate);
403  when_false_trace(amxd_object_template == type, exit, ERROR,
404  "%s is not a template object", path);
405 
406  if(amxd_object_get_instance(templ_candidate, NULL, index) != NULL) {
407  SAH_TRACEZ_ERROR(ME, "%s.%d already exists", path, index);
408  goto exit;
409  }
410 
411  *templ = templ_candidate;
412  rv = true;
413 
414 exit:
415  return rv;
416 }
417 
430 static bool add_params_to_transaction(amxd_trans_t* transaction,
431  const amxc_var_t* const params,
432  object_id_t id) {
433  bool rv = false;
434 
435  const amxc_htable_t* const params_table = amxc_var_constcast(amxc_htable_t, params);
436  when_null(params_table, exit);
437 
438  const object_info_t* const obj_info = dm_get_object_info(id);
439  when_null(obj_info, exit);
440 
441  const param_info_t* param_info;
442  const param_info_t* single_param;
443  uint32_t n_params;
444 
445  if(!dm_get_object_param_info(id, &param_info, &n_params)) {
446  SAH_TRACEZ_ERROR(ME, "%s: failed to get info about its params", obj_info->name);
447  goto exit;
448  }
449 
450  amxc_var_t* param_value = NULL;
451  uint32_t i;
452  const char* key;
453 
454  amxc_htable_for_each(it, params_table) {
455  single_param = NULL;
456  key = amxc_htable_it_get_key(it);
457  if(!key) {
458  continue;
459  }
460  for(i = 0; i < n_params; ++i) {
461  if((strncmp(key, param_info[i].name, strlen(key)) == 0) &&
462  (strlen(key) == strlen(param_info[i].name))) {
463  single_param = &param_info[i];
464  break; /* out of for loop */
465  }
466  }
467  if(NULL == single_param) {
468  SAH_TRACEZ_WARNING(ME, "%s: unknown param name: %s", obj_info->name, key);
469  continue;
470  }
471  param_value = GET_ARG(params, key);
472  if(NULL == param_value) {
473  SAH_TRACEZ_ERROR(ME, "%s: failed to get value for %s", obj_info->name, key);
474  continue;
475  }
476  if(amxc_var_type_of(param_value) != single_param->type) {
477  SAH_TRACEZ_ERROR(ME, "%s: type of parameter %s: %d != expected=%d",
478  obj_info->name, key, amxc_var_type_of(param_value),
479  single_param->type);
480  continue;
481  }
482  if(amxd_trans_set_param(transaction, key, param_value)) {
483  SAH_TRACEZ_ERROR(ME, "%s: failed to add value for %s to transaction",
484  obj_info->name, key);
485  } else {
486  SAH_TRACEZ_DEBUG(ME, "%s: added value for %s to transaction",
487  obj_info->name, key);
488  }
489  }
490  rv = true;
491 
492 exit:
493  return rv;
494 }
495 
505 static void update_enable(amxd_trans_t* transaction,
506  const char* const path, uint32_t index) {
507 
508  when_false_trace(index != 0, exit, ERROR, "index is 0");
509 
510  amxc_string_t full_path;
511  amxc_string_init(&full_path, 0);
512  amxc_string_set(&full_path, path);
513  amxc_string_appendf(&full_path, ".%d", index);
514 
515  const char* const full_path_cstr = amxc_string_get(&full_path, 0);
516 
517  if(persistency_is_enabled(full_path_cstr)) {
518  amxc_var_t enabled;
519  amxc_var_init(&enabled);
520  amxc_var_set(bool, &enabled, true);
521  amxd_trans_set_param(transaction, ENABLE_PARAM, &enabled);
522  amxc_var_clean(&enabled);
523 
524  rth_schedule_enable(full_path_cstr);
525  }
526  amxc_string_clean(&full_path);
527 
528 exit:
529  return;
530 }
531 
538 static void add_private_data_to_onu(const char* const path, uint32_t index) {
539 
540  SAH_TRACEZ_DEBUG(ME, "%s.%d", path, index);
541 
542  amxd_dm_t* const dm = xpon_mngr_get_dm();
543  when_null(dm, exit);
544 
545  amxd_object_t* templ = amxd_dm_findf(dm, "%s", path);
546  when_null_trace(templ, exit, ERROR, "Failed to find %s", path);
547 
548  amxd_object_t* const obj = amxd_object_get_instance(templ, NULL, index);
549  when_null_trace(obj, exit, ERROR, "Instance %s.%d does not exist", path, index);
550 
552 
553 exit:
554  return;
555 }
556 
589 static bool add_instance(const dm_action_info_t* const info) {
590 
591  bool rv = false;
592  amxd_object_t* templ = NULL;
593 
594  SAH_TRACEZ_INFO(ME, "Create %s.%d", info->path, info->index);
595 
596  const object_info_t* const obj_info = dm_get_object_info(info->obj_id);
597  when_null_trace(obj_info, exit_no_cleanup, ERROR,
598  "obj_info is NULL for obj_id=%d", info->obj_id);
599 
600  if(!prepare_adding_instance(info->path, info->index, &templ)) {
601  return false;
602  }
603 
604  amxd_dm_t* const dm = xpon_mngr_get_dm();
605  when_null(dm, exit_no_cleanup);
606 
607  amxd_trans_t transaction;
608  amxd_trans_init(&transaction);
609  amxd_trans_set_attr(&transaction, amxd_tattr_change_ro, true);
610 
611  const char* const key_name = obj_info->key_name; /* alias */
612 
613  amxd_status_t rc = amxd_trans_select_object(&transaction, templ);
614  when_failed_trace(rc, exit, ERROR, "Failed to select %s for transaction (rc=%d)",
615  info->path, rc);
616 
617  rc = amxd_trans_add_inst(&transaction, info->index, NULL);
618  when_failed_trace(rc, exit, ERROR,
619  "Failed to add creation of %s.%d to transaction (rc=%d)",
620  info->path, info->index, rc);
621 
622  rc = amxd_trans_set_param(&transaction, key_name, info->key_value);
623  when_failed_trace(rc, exit, ERROR,
624  "Failed to add value for key to transaction (rc=%d)", rc);
625 
626  if(info->params) {
627  add_params_to_transaction(&transaction, info->params, info->obj_id);
628  }
629 
630  if(obj_info->has_rw_enable) {
631  update_enable(&transaction, info->path, info->index);
632  }
633 
634  rc = amxd_trans_apply(&transaction, dm);
635  when_failed_trace(rc, exit, ERROR, "Failed to create %s.%d (rc=%d)",
636  info->path, info->index, rc);
637 
638  SAH_TRACEZ_DEBUG(ME, "Created %s.%d", info->path, info->index);
639 
640  if(obj_info->id == obj_id_onu) {
641  add_private_data_to_onu(info->path, info->index);
642  } else if(obj_info->id == obj_id_ani) {
643  amxc_string_t ani_instance;
644  amxc_string_init(&ani_instance, 0);
645  amxc_string_setf(&ani_instance, "%s.%d", info->path, info->index);
646  passwd_restore_password(amxc_string_get(&ani_instance, 0));
647  amxc_string_clean(&ani_instance);
648  }
649 
650  rv = true;
651 
652 exit:
653  amxd_trans_clean(&transaction);
654 
655 exit_no_cleanup:
656  return rv;
657 }
658 
669 static bool process_remove_instance_args(const amxc_var_t* const args,
670  dm_action_info_t* info) {
671 
672  bool rv = false;
673  SAH_TRACEZ_DEBUG2(ME, "called");
674 
677  goto exit;
678  }
679 
680  rv = true;
681 
682 exit:
683  return rv;
684 }
685 
695 static bool remove_instance(const dm_action_info_t* const info) {
696 
697  bool rv = false;
698  amxd_object_t* obj;
699 
700  SAH_TRACEZ_INFO(ME, "Delete %s.%d", info->path, info->index);
701 
702  amxd_dm_t* const dm = xpon_mngr_get_dm();
703  when_null(dm, exit_no_cleanup);
704 
705  amxd_object_t* templ = amxd_dm_findf(dm, "%s", info->path);
706  if(!templ) {
707  SAH_TRACEZ_WARNING(ME, "Failed to find %s", info->path);
708  return true;
709  }
710 
711  const amxd_object_type_t type = amxd_object_get_type(templ);
712  when_false_trace(amxd_object_template == type, exit_no_cleanup, ERROR,
713  "%s is not a template object", info->path);
714 
715  obj = amxd_object_get_instance(templ, NULL, info->index);
716  if(!obj) {
717  SAH_TRACEZ_WARNING(ME, "Instance %s.%d does not exist", info->path,
718  info->index);
719  return true;
720  }
721 
722  amxd_trans_t transaction;
723  amxd_trans_init(&transaction);
724  amxd_trans_set_attr(&transaction, amxd_tattr_change_ro, true);
725 
726  amxd_status_t rc = amxd_trans_select_object(&transaction, templ);
727  when_failed_trace(rc, exit, ERROR, "Failed to select %s for transaction (rc=%d)",
728  info->path, rc);
729 
730  rc = amxd_trans_del_inst(&transaction, info->index, NULL);
731  when_failed_trace(rc, exit, ERROR,
732  "Failed to add %s.%d for deletion to transaction (rc=%d)",
733  info->path, info->index, rc);
734 
736  rc = amxd_trans_apply(&transaction, dm);
737  when_failed_trace(rc, exit, ERROR, "Failed to delete %s.%d (rc=%d)",
738  info->path, info->index, rc);
739 
740  SAH_TRACEZ_DEBUG(ME, "Deleted %s.%d", info->path, info->index);
741 
742  rv = true;
743 
744 exit:
745  amxd_trans_clean(&transaction);
747 
748 exit_no_cleanup:
749  return rv;
750 }
751 
752 
762 int dm_add_instance(const amxc_var_t* const args) {
763 
764  int rc = -1;
765  dm_action_info_t info;
766 
767  SAH_TRACEZ_DEBUG2(ME, "called");
768 
769  if(!process_add_instance_args(args, &info)) {
770  goto exit;
771  }
772  if(!add_instance(&info)) {
773  goto exit;
774  }
775 
776  rc = 0;
777 exit:
778  return rc;
779 }
780 
788 int dm_remove_instance(const amxc_var_t* const args) {
789 
790  int rc = -1;
791  dm_action_info_t info;
792 
793  SAH_TRACEZ_DEBUG2(ME, "called");
794 
795  if(!process_remove_instance_args(args, &info)) {
796  goto exit;
797  }
798  if(!remove_instance(&info)) {
799  goto exit;
800  }
801 
802  rc = 0;
803 exit:
804  return rc;
805 }
806 
821 int dm_change_object(const amxc_var_t* const args) {
822 
823  int rc = -1;
824 
825  SAH_TRACEZ_DEBUG2(ME, "called");
826 
827  amxd_dm_t* const dm = xpon_mngr_get_dm();
828  when_null(dm, exit);
829 
830  dm_action_info_t info;
833  goto exit;
834  }
835 
836  amxc_string_t path;
837  amxc_string_init(&path, 0);
838  amxc_string_set(&path, info.path);
839 
840  SAH_TRACEZ_DEBUG(ME, "path='%s' index=%d", info.path, info.index);
841 
842  if(info.index) {
843  /* Assume caller wants to update 'path'.'index' */
844  amxc_string_appendf(&path, ".%d", info.index);
845  }
846  const char* const path_cstr = amxc_string_get(&path, 0);
847 
848  amxd_object_t* object = amxd_dm_findf(dm, "%s", path_cstr);
849  if(!object) {
850  SAH_TRACEZ_WARNING(ME, "%s does not exist: ignore object-changed", path_cstr);
851  amxc_string_clean(&path);
852  rc = 0;
853  goto exit;
854  }
855 
856  amxd_trans_t transaction;
857  amxd_trans_init(&transaction);
858  amxd_trans_set_attr(&transaction, amxd_tattr_change_ro, true);
859 
860  amxd_status_t status = amxd_trans_select_object(&transaction, object);
861  when_failed_trace(status, exit_cleanup, ERROR,
862  "Failed to select %s for transaction (status=%d)",
863  info.path, status);
864 
865  add_params_to_transaction(&transaction, info.params, info.obj_id);
866 
867  if(info.obj_id == obj_id_onu) {
868  if(object->priv == NULL) {
869  SAH_TRACEZ_DEBUG(ME, "%s has no private data", path_cstr);
871  update_enable(&transaction, info.path, info.index);
872  } else {
873  SAH_TRACEZ_DEBUG(ME, "%s already has private data", path_cstr);
874  }
875  }
876 
877  status = amxd_trans_apply(&transaction, dm);
878  when_failed_trace(status, exit_cleanup, ERROR, "Failed to update %s (status=%d)",
879  info.path, status);
880 
881  rc = 0;
882 
883 exit_cleanup:
884  amxc_string_clean(&path);
885  amxd_trans_clean(&transaction);
886 exit:
887  return rc;
888 }
889 
922 int dm_add_or_change_instance_impl(const amxc_var_t* const args) {
923 
924  int rc = -1;
925 
926  SAH_TRACEZ_DEBUG2(ME, "called");
927 
928  amxd_dm_t* const dm = xpon_mngr_get_dm();
929  when_null(dm, exit);
930 
931  dm_action_info_t info;
934  goto exit;
935  }
936 
937  if(dm_does_instance_exist(info.path, info.index)) {
938  SAH_TRACEZ_DEBUG(ME, "Change %s.%d", info.path, info.index);
939  return dm_change_object(args);
940  } else {
941  SAH_TRACEZ_DEBUG(ME, "Add %s.%d", info.path, info.index);
942  return dm_add_instance(args);
943  }
944 
945 exit:
946  return rc;
947 }
948 
958 static bool remove_all_instances(amxd_object_t* templ) {
959 
960  bool rv = false;
961 
962  when_null(templ, exit_no_cleanup);
963 
964  amxd_dm_t* const dm = xpon_mngr_get_dm();
965  when_null(dm, exit_no_cleanup);
966 
967  if(amxd_object_get_type(templ) != amxd_object_template) {
968  SAH_TRACEZ_ERROR(ME, "Parameter 'templ' is not a template");
969  goto exit_no_cleanup;
970  }
971 
972  const uint32_t nr_instances = amxd_object_get_instance_count(templ);
973  if(0 == nr_instances) {
974  SAH_TRACEZ_DEBUG(ME, "No instances");
975  rv = true;
976  goto exit_no_cleanup;
977  }
978 
979  amxd_trans_t transaction;
980  amxd_trans_init(&transaction);
981  amxd_trans_set_attr(&transaction, amxd_tattr_change_ro, true);
982 
983  int rc = amxd_trans_select_object(&transaction, templ);
984  when_failed_trace(rc, exit, ERROR, "Failed to select template object");
985 
986  uint32_t index;
987  amxd_object_t* obj_inst = NULL;
988 
989  amxd_object_iterate(instance, it, templ) {
990  obj_inst = amxc_container_of(it, amxd_object_t, it);
991  index = amxd_object_get_index(obj_inst);
992  rc = amxd_trans_del_inst(&transaction, index, NULL);
993  when_failed_trace(rc, exit, ERROR, "Failed to add deletion to transaction");
994  }
995 
996  rc = amxd_trans_apply(&transaction, dm);
997  when_failed_trace(rc, exit, ERROR, "Failed to apply transaction (rc=%d)", rc);
998 
999  rv = true;
1000 
1001 exit:
1002  amxd_trans_clean(&transaction);
1003 
1004 exit_no_cleanup:
1005  return rv;
1006 }
1007 
1011 static void set_ethernet_uni_status_to_down(const amxd_object_t* const onu_instance,
1012  const char* const path) {
1013 
1014  const amxd_object_t* ethernet_uni = amxd_object_get_child(onu_instance, "EthernetUNI");
1015  when_null_trace(ethernet_uni, exit, ERROR, "%s.EthernetUNI does not exist", path);
1016 
1017  char* current_status_cstr;
1018  amxd_object_iterate(instance, it, ethernet_uni) {
1019  amxd_object_t* const eth_uni_inst = amxc_container_of(it, amxd_object_t, it);
1020  if(NULL == eth_uni_inst) {
1021  SAH_TRACEZ_ERROR(ME, "Failed to get EthernetUNI object");
1022  continue;
1023  }
1024  current_status_cstr = amxd_object_get_value(cstring_t, eth_uni_inst, "Status", NULL);
1025  if(current_status_cstr) {
1026  if(strncmp(current_status_cstr, "Up", 2) == 0) {
1027  amxd_object_set_value(cstring_t, eth_uni_inst, "Status", "Down");
1028  }
1029  free(current_status_cstr);
1030  }
1031  }
1032 exit:
1033  return;
1034 }
1035 
1049 int dm_omci_reset_mib(const amxc_var_t* const args) {
1050 
1051  int rc = -1;
1052 
1053  SAH_TRACEZ_DEBUG2(ME, "called");
1054 
1055  when_null_trace(args, exit, ERROR, "args is NULL");
1056 
1057  amxd_dm_t* const dm = xpon_mngr_get_dm();
1058  when_null(dm, exit);
1059 
1060  const uint32_t index = GET_UINT32(args, "index");
1061  when_false_trace(index != 0, exit, ERROR, "Failed to extract valid index from args");
1062 
1063  char path[16];
1064  snprintf(path, 16, "XPON.ONU.%d", index);
1065  const amxd_object_t* onu_instance = amxd_dm_findf(dm, "%s", path);
1066  if(!onu_instance) {
1067  SAH_TRACEZ_WARNING(ME, "%s does not exist: ignore omci:reset-mib", path);
1068  rc = 0;
1069  goto exit;
1070  }
1071 
1072  set_ethernet_uni_status_to_down(onu_instance, path);
1073 
1074  /* Remove GEM ports */
1075  const amxd_object_t* ani = amxd_object_get_child(onu_instance, "ANI");
1076  if(ani) {
1077  amxd_object_iterate(instance, it, ani) {
1078  amxd_object_t* const ani_inst = amxc_container_of(it, amxd_object_t, it);
1079  amxd_object_t* const port_templ = amxd_object_findf(ani_inst, "TC.GEM.Port");
1080  if(!port_templ) {
1081  SAH_TRACEZ_ERROR(ME, "%s: failed to find TC.GEM.Port for ANI.%d",
1082  path, amxd_object_get_index(ani_inst));
1083  continue;
1084  }
1085  if(!remove_all_instances(port_templ)) {
1086  SAH_TRACEZ_ERROR(ME, "%s: failed to delete GEM ports for ANI.%d",
1087  path, amxd_object_get_index(ani_inst));
1088  }
1089  }
1090  } else {
1091  SAH_TRACEZ_ERROR(ME, "%s.ANI does not exist", path);
1092  }
1093 
1094  rc = 0;
1095 exit:
1096  return rc;
1097 }
1098 
1106 int dm_set_xpon_parameter_impl(const amxc_var_t* const args) {
1107  int rc = -1;
1108  amxd_object_t* const xpon = dm_get_xpon_object();
1109  when_null(xpon, exit);
1110 
1111  const amxc_htable_t* const htable = amxc_var_constcast(amxc_htable_t, args);
1112  when_null_trace(htable, exit, ERROR, "args is not an htable");
1113 
1114  const char* const name = GET_CHAR(args, "name");
1115  when_null_trace(name, exit, ERROR, "Failed to get name");
1116 
1117  if(strncmp(name, "FsmState", 8) != 0) {
1118  SAH_TRACEZ_WARNING(ME, "dm_set_xpon_parameter() only supports XPON.FsmState");
1119  goto exit;
1120  }
1121 
1122  amxc_var_t* const value = GET_ARG(args, "value");
1123  when_null_trace(value, exit, ERROR, "Failed to get value");
1124 
1125  const amxd_status_t status = amxd_object_set_param(xpon, name, value);
1126  when_true_trace(status != amxd_status_ok, exit, ERROR,
1127  "Failed to update %s: status=%d", name, status);
1128  rc = 0;
1129 exit:
1130  return rc;
1131 }
1132 
1141 bool dm_does_instance_exist(const char* const path, uint32_t index) {
1142 
1143  bool rv = false;
1144  amxd_dm_t* const dm = xpon_mngr_get_dm();
1145  when_null(dm, exit);
1146 
1147  const amxd_object_t* const templ = amxd_dm_findf(dm, "%s", path);
1148  if(!templ) {
1149  goto exit;
1150  }
1151 
1152  if(amxd_object_get_instance(templ, NULL, index)) {
1153  rv = true;
1154  }
1155 
1156 exit:
1157  return rv;
1158 }
1159 
1166 static uint32_t get_nr_of_instances(const char* const path) {
1167 
1168  uint32_t result = 0;
1169 
1170  amxd_dm_t* const dm = xpon_mngr_get_dm();
1171  when_null(dm, exit);
1172 
1173  const amxd_object_t* const object = amxd_dm_findf(dm, "%s", path);
1174  when_null_trace(object, exit, ERROR, "%s not found", path);
1175 
1176  result = amxd_object_get_instance_count(object);
1177 
1178 exit:
1179  return result;
1180 }
1181 
1187 uint32_t dm_get_nr_of_ethernet_uni_instances(const char* const onu_path) {
1188  char path[64];
1189  snprintf(path, 64, "%s.EthernetUNI", onu_path);
1190  return get_nr_of_instances(path);
1191 }
1192 
1198 uint32_t dm_get_nr_of_ani_instances(const char* const onu_path) {
1199  char path[64];
1200  snprintf(path, 64, "%s.ANI", onu_path);
1201  return get_nr_of_instances(path);
1202 }
1203 
1204 bool dm_get_param(const char* path, const char* name, amxc_var_t* resp) {
1205  SAH_TRACEZ_DEBUG(ME, "get value of dm parameter path=%s.%s", path, name);
1206 
1207  amxd_dm_t* const dm = xpon_mngr_get_dm();
1208  when_null(dm, exit);
1209 
1210  amxd_object_t* const param_object = amxd_dm_findf(dm, "%s", path);
1211  if(!param_object) {
1212  SAH_TRACEZ_WARNING(ME, "%s does not exist!", path);
1213  goto exit;
1214  }
1215 
1216  if(amxd_status_ok != amxd_object_get_param(param_object, name, resp)) {
1217  SAH_TRACEZ_WARNING(ME, "Failed to get param from object: %s.%s", path, name);
1218  goto exit;
1219  }
1220 
1221  return true;
1222 exit:
1223  return false;
1224 }
1225 
1236 bool dm_is_hex_password(const char* const ani_path, bool* is_hex) {
1237 
1238  bool rv = false;
1239  amxc_var_t is_hex_variant;
1240  amxc_string_t ani_auth_path;
1241  amxc_var_init(&is_hex_variant);
1242  amxc_string_init(&ani_auth_path, 0);
1243 
1244  amxd_dm_t* const dm = xpon_mngr_get_dm();
1245  when_null(dm, exit);
1246  when_null(is_hex, exit);
1247 
1248  ani_append_tc_authentication(ani_path, &ani_auth_path);
1249  const char* const ani_auth_path_cstr = amxc_string_get(&ani_auth_path, 0);
1250 
1251  amxd_object_t* const object = amxd_dm_findf(dm, "%s", ani_auth_path_cstr);
1252  when_null_trace(object, exit, WARNING, "%s does not exist",
1253  ani_auth_path_cstr);
1254 
1255  if(amxd_status_ok != amxd_object_get_param(object, "HexadecimalPassword",
1256  &is_hex_variant)) {
1257  SAH_TRACEZ_ERROR(ME, "Failed to get %s.HexadecimalPassword",
1258  ani_auth_path_cstr);
1259  goto exit;
1260  }
1261 
1262  *is_hex = amxc_var_constcast(bool, &is_hex_variant);
1263  rv = true;
1264 
1265 exit:
1266  amxc_var_clean(&is_hex_variant);
1267  amxc_string_clean(&ani_auth_path);
1268  return rv;
1269 }
1270 
1280 bool dm_get_ani_pon_mode(const char* const ani_path, pon_mode_t* pon_mode) {
1281 
1282  bool rv = false;
1283  amxc_var_t pon_mode_var;
1284  amxc_var_init(&pon_mode_var);
1285 
1286  amxd_dm_t* const dm = xpon_mngr_get_dm();
1287  when_null(dm, exit);
1288  when_null(pon_mode, exit);
1289 
1290  amxd_object_t* const object = amxd_dm_findf(dm, "%s", ani_path);
1291  when_null_trace(object, exit, WARNING, "%s does not exist", ani_path);
1292 
1293  if(amxd_status_ok != amxd_object_get_param(object, "PONMode",
1294  &pon_mode_var)) {
1295  SAH_TRACEZ_ERROR(ME, "Failed to get %s.PONMode", ani_path);
1296  goto exit;
1297  }
1298 
1299  const char* const pon_mode_cstr = amxc_var_constcast(cstring_t, &pon_mode_var);
1300  if(strncmp(pon_mode_cstr, "Unknown", 7) == 0) {
1301  *pon_mode = pon_mode_unknown;
1302  } else if(strncmp(pon_mode_cstr, "G-PON", 5) == 0) {
1303  *pon_mode = pon_mode_gpon;
1304  } else if(strncmp(pon_mode_cstr, "XG-PON", 6) == 0) {
1305  *pon_mode = pon_mode_xg_pon;
1306  } else if(strncmp(pon_mode_cstr, "NG-PON2", 7) == 0) {
1307  *pon_mode = pon_mode_ng_pon2;
1308  } else if(strncmp(pon_mode_cstr, "XGS-PON", 7) == 0) {
1309  *pon_mode = pon_mode_xgs_pon;
1310  } else {
1311  SAH_TRACEZ_ERROR(ME, "Invalid PON mode: %s", pon_mode_cstr);
1312  *pon_mode = pon_mode_unknown;
1313  goto exit;
1314  }
1315 
1316  rv = true;
1317 
1318 exit:
1319  amxc_var_clean(&pon_mode_var);
1320  return rv;
1321 }
1322 
1323 
void ani_append_tc_authentication(const char *const ani_path, amxc_string_t *const ani_auth_path)
Definition: ani.c:113
void dm_set_module_error(void)
Definition: data_model.c:192
static bool prepare_adding_instance(const char *const path, uint32_t index, amxd_object_t **templ)
Definition: data_model.c:389
bool dm_is_hex_password(const char *const ani_path, bool *is_hex)
Definition: data_model.c:1236
uint32_t dm_get_nr_of_ani_instances(const char *const onu_path)
Definition: data_model.c:1198
int dm_omci_reset_mib(const amxc_var_t *const args)
Definition: data_model.c:1049
static amxd_object_t * dm_get_xpon_object(void)
Definition: data_model.c:153
#define CHANGE_OBJ_N_ARGS_REQUIRED
Definition: data_model.c:104
#define ADD_OR_CHANGE_INST_N_ARGS_REQUIRED
Definition: data_model.c:109
static void update_enable(amxd_trans_t *transaction, const char *const path, uint32_t index)
Definition: data_model.c:505
int dm_change_object(const amxc_var_t *const args)
Definition: data_model.c:821
static bool process_add_instance_args(const amxc_var_t *const args, dm_action_info_t *info)
Definition: data_model.c:326
int dm_add_or_change_instance_impl(const amxc_var_t *const args)
Definition: data_model.c:922
static bool process_remove_instance_args(const amxc_var_t *const args, dm_action_info_t *info)
Definition: data_model.c:669
static const char * REMOVE_INST_ARGS_REQUIRED[2]
Definition: data_model.c:100
#define REMOVE_INST_N_ARGS_REQUIRED
Definition: data_model.c:99
static const char * ADD_OR_CHANGE_INST_ARGS_REQUIRED[2]
Definition: data_model.c:110
static void init_dm_action_info(dm_action_info_t *const info)
Definition: data_model.c:141
static bool remove_all_instances(amxd_object_t *templ)
Definition: data_model.c:958
static const char * CHANGE_OBJ_ARGS_REQUIRED[2]
Definition: data_model.c:105
static void set_ethernet_uni_status_to_down(const amxd_object_t *const onu_instance, const char *const path)
Definition: data_model.c:1011
int dm_remove_instance(const amxc_var_t *const args)
Definition: data_model.c:788
int dm_set_xpon_parameter_impl(const amxc_var_t *const args)
Definition: data_model.c:1106
int dm_add_instance(const amxc_var_t *const args)
Definition: data_model.c:762
static bool add_instance(const dm_action_info_t *const info)
Definition: data_model.c:589
uint32_t dm_get_nr_of_ethernet_uni_instances(const char *const onu_path)
Definition: data_model.c:1187
static bool get_ref_to_params(const amxc_var_t *const args, const amxc_var_t **params)
Definition: data_model.c:203
static uint32_t get_nr_of_instances(const char *const path)
Definition: data_model.c:1166
#define ADD_INST_N_ARGS_REQUIRED
Definition: data_model.c:94
static const char * ADD_INST_PARAMS_REQUIRED[3]
Definition: data_model.c:95
static bool add_params_to_transaction(amxd_trans_t *transaction, const amxc_var_t *const params, object_id_t id)
Definition: data_model.c:430
bool dm_does_instance_exist(const char *const path, uint32_t index)
Definition: data_model.c:1141
static void add_private_data_to_onu(const char *const path, uint32_t index)
Definition: data_model.c:538
static bool process_args_common(const amxc_var_t *const args, dm_action_info_t *info, const char **keys_required, int n_keys_required)
Definition: data_model.c:244
struct _dm_action_info dm_action_info_t
bool dm_get_ani_pon_mode(const char *const ani_path, pon_mode_t *pon_mode)
Definition: data_model.c:1280
static bool remove_instance(const dm_action_info_t *const info)
Definition: data_model.c:695
bool dm_get_param(const char *path, const char *name, amxc_var_t *resp)
Definition: data_model.c:1204
void dm_set_vendor_module(const char *name)
Definition: data_model.c:178
void dm_actions_set_ignore_param_reads(bool ignore)
Definition: dm_actions.c:124
#define ENABLE_PARAM
Definition: dm_info.h:74
bool dm_get_object_param_info(object_id_t id, const param_info_t **param_info, uint32_t *size)
Definition: dm_info.c:429
object_id_t dm_get_object_id(const char *path)
Definition: dm_info.c:380
enum _xpon_object_id object_id_t
#define NAME_PARAM
Definition: dm_info.h:76
@ obj_id_ani
Definition: dm_info.h:83
@ obj_id_onu
Definition: dm_info.h:80
@ obj_id_unknown
Definition: dm_info.h:91
#define NAME_PARAM_LEN
Definition: dm_info.h:77
const object_info_t * dm_get_object_info(object_id_t id)
Definition: dm_info.c:410
amxd_dm_t *PRIVATE xpon_mngr_get_dm(void)
void onu_priv_attach_private_data(amxd_object_t *const object)
Definition: onu_priv.c:77
void passwd_restore_password(const char *const ani_path)
Definition: password.c:237
bool persistency_is_enabled(const char *const object)
Definition: persistency.c:280
enum _pon_mode pon_mode_t
@ pon_mode_ng_pon2
Definition: pon_mode.h:70
@ pon_mode_unknown
Definition: pon_mode.h:67
@ pon_mode_gpon
Definition: pon_mode.h:68
@ pon_mode_xgs_pon
Definition: pon_mode.h:71
@ pon_mode_xg_pon
Definition: pon_mode.h:69
void rth_schedule_enable(const char *const object)
object_id_t obj_id
Definition: data_model.c:136
const char * path
Definition: data_model.c:134
uint32_t index
Definition: data_model.c:135
const amxc_var_t * params
Definition: data_model.c:138
amxc_var_t * key_value
Definition: data_model.c:137
const char * name
Definition: dm_info.h:124
object_id_t id
Definition: dm_info.h:123
bool has_rw_enable
Definition: dm_info.h:132
uint32_t key_max_value
Definition: dm_info.h:127
const char * key_name
Definition: dm_info.h:126
uint32_t type
Definition: dm_info.h:96
on event dm
#define SAH_TRACEZ_DEBUG(zone, format,...)
Definition: xpon_trace.h:115
#define SAH_TRACEZ_DEBUG2(zone, format,...)
Definition: xpon_trace.h:127
#define ME
Definition: xpon_trace.h:78