TR181-XPON  1.4.0
TR-181 PON manager.
restore_to_hal.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 "restore_to_hal.h"
65 
66 /* System headers */
67 #include <stdlib.h> /* free() */
68 #include <string.h> /* strcmp() */
69 
70 /* Other libraries' headers */
71 #include <amxc/amxc_macros.h>
72 #include <amxc/amxc.h>
73 #include <amxp/amxp_timer.h>
74 
75 /* Own headers */
76 #include "data_model.h" /* dm_get_nr_of_ethernet_uni_instances() */
77 #include "dm_info.h" /* dm_get_object_id() */
78 #include "pon_ctrl.h" /* pon_ctrl_set_enable() */
79 #include "xpon_mgr_constants.h" /* SHORT_TIMEOUT_MS */
80 #include "xpon_trace.h"
81 
82 /* List of tasks of type rth_task_t */
83 static amxc_llist_t s_rth_tasks;
84 
85 /* Timer to process tasks in s_rth_tasks */
86 static amxp_timer_t* s_timer_handle_rth_tasks = NULL;
87 
88 static const uint8_t MAX_CHECKS_ON_NR_OF_UNIS_AND_ANIS = 4;
89 
113 typedef struct _rth_task {
114  amxc_string_t path;
115  uint8_t cntr;
116  amxc_llist_it_t it;
118 
119 
120 static void rth_task_clean(rth_task_t* const task) {
121  amxc_string_clean(&task->path);
122 }
123 
132 static rth_task_t* rth_task_create(const char* const path) {
133 
134  rth_task_t* task = (rth_task_t*) calloc(1, sizeof(rth_task_t));
135  when_null_trace(task, exit, ERROR, "Failed to allocate memory");
136 
137  amxc_string_init(&task->path, 0);
138  amxc_string_set(&task->path, path);
139 
140  if(amxc_llist_append(&s_rth_tasks, &task->it)) {
141  SAH_TRACEZ_ERROR(ME, "Failed to append task to 's_rth_tasks'");
142  SAH_TRACEZ_ERROR(ME, " path='%s'", path);
143  rth_task_clean(task);
144  free(task);
145  task = NULL;
146  }
147 
148 exit:
149  return task;
150 }
151 
152 static void rth_task_delete(amxc_llist_it_t* hit) {
153  rth_task_t* task = amxc_container_of(hit, rth_task_t, it);
154  const char* path = amxc_string_get(&task->path, 0);
155  SAH_TRACEZ_DEBUG(ME, "path='%s'", path);
156  rth_task_clean(task);
157  free(task);
158 }
159 
177 static void handle_rth_tasks(amxp_timer_t* timer, UNUSED void* priv) {
178 
179  if(amxc_llist_is_empty(&s_rth_tasks)) {
180  SAH_TRACEZ_WARNING(ME, "No tasks");
181  return;
182  }
183 
184  rth_task_t* task;
185  const char* path;
186  object_id_t id;
187  bool delete_item;
188  uint32_t n_ethernet_unis;
189  uint32_t n_anis;
190  amxc_llist_for_each(it, &s_rth_tasks) {
191  delete_item = true;
192  task = amxc_llist_it_get_data(it, rth_task_t, it);
193  path = amxc_string_get(&task->path, 0);
194  id = dm_get_object_id(path);
195  SAH_TRACEZ_DEBUG(ME, "path='%s'", path);
196  if(obj_id_onu == id) {
197  n_ethernet_unis = dm_get_nr_of_ethernet_uni_instances(path);
198  n_anis = dm_get_nr_of_ani_instances(path);
199  SAH_TRACEZ_DEBUG(ME, "path='%s' n_ethernet_unis=%d n_anis=%d cntr=%d",
200  path, n_ethernet_unis, n_anis, task->cntr);
201  if((n_ethernet_unis != 0) && (n_anis != 0)) {
202  pon_ctrl_set_enable(path, /*enable=*/ true);
203  } else if(task->cntr > MAX_CHECKS_ON_NR_OF_UNIS_AND_ANIS) {
204  SAH_TRACEZ_WARNING(ME, "Enable %s despite n_ethernet_unis=%d n_anis=%d",
205  path, n_ethernet_unis, n_anis);
206  pon_ctrl_set_enable(path, /*enable=*/ true);
207  } else {
208  ++task->cntr;
209  delete_item = false;
210  }
211  } else {
212  pon_ctrl_set_enable(path, /*enable=*/ true);
213  }
214  if(delete_item) {
215  amxc_llist_it_take(it);
216  rth_task_clean(task);
217  free(task);
218  }
219  }
220  if(!amxc_llist_is_empty(&s_rth_tasks)) {
221  amxp_timer_start(timer, /*timeout_msec=*/ 1000);
222  }
223 }
224 
225 
226 void rth_init(void) {
227  amxc_llist_init(&s_rth_tasks);
228 
229  if(amxp_timer_new(&s_timer_handle_rth_tasks, handle_rth_tasks, NULL)) {
230  SAH_TRACEZ_ERROR(ME, "Failed to create timer to handle tasks");
231  }
232 }
233 
234 void rth_cleanup(void) {
235  if(!amxc_llist_is_empty(&s_rth_tasks)) {
236  /* Normally s_rth_tasks should be empty upon stopping */
237  SAH_TRACEZ_WARNING(ME, "size(s_rth_tasks)=%zd != 0",
238  amxc_llist_size(&s_rth_tasks));
239  amxc_llist_clean(&s_rth_tasks, rth_task_delete);
240  }
241  amxp_timer_delete(&s_timer_handle_rth_tasks);
242 }
243 
256 void rth_schedule_enable(const char* const object) {
257 
258  SAH_TRACEZ_DEBUG(ME, "object='%s'", object);
259 
260  when_null_trace(s_timer_handle_rth_tasks, exit, ERROR, "No timer");
261 
262  const rth_task_t* task;
263  const char* path;
264  amxc_llist_iterate(it, &s_rth_tasks) {
265  task = amxc_llist_it_get_data(it, rth_task_t, it);
266  path = amxc_string_get(&task->path, 0);
267  if(strncmp(path, object, strlen(object)) == 0) {
268  SAH_TRACEZ_DEBUG(ME, "%s is already scheduled to be enabled", object);
269  return;
270  }
271  }
272 
273  if(rth_task_create(object) != NULL) {
274  amxp_timer_start(s_timer_handle_rth_tasks, SHORT_TIMEOUT_MS);
275  }
276 
277 exit:
278  return;
279 }
280 
286 void rth_disable(const char* const object) {
287  if(amxc_llist_is_empty(&s_rth_tasks)) {
288  return;
289  }
290  rth_task_t* task;
291  const char* path;
292  amxc_llist_for_each(it, &s_rth_tasks) {
293  task = amxc_llist_it_get_data(it, rth_task_t, it);
294  path = amxc_string_get(&task->path, 0);
295  if(strcmp(object, path) == 0) {
296  amxc_llist_it_take(it);
297  rth_task_delete(it);
298  break; /* out of iteration over s_rth_tasks */
299  }
300  }
301 }
302 
uint32_t dm_get_nr_of_ani_instances(const char *const onu_path)
Definition: data_model.c:1198
uint32_t dm_get_nr_of_ethernet_uni_instances(const char *const onu_path)
Definition: data_model.c:1187
object_id_t dm_get_object_id(const char *path)
Definition: dm_info.c:380
enum _xpon_object_id object_id_t
@ obj_id_onu
Definition: dm_info.h:80
void pon_ctrl_set_enable(const char *const path, bool enable)
Definition: pon_ctrl.c:153
static void rth_task_delete(amxc_llist_it_t *hit)
static rth_task_t * rth_task_create(const char *const path)
void rth_schedule_enable(const char *const object)
static const uint8_t MAX_CHECKS_ON_NR_OF_UNIS_AND_ANIS
struct _rth_task rth_task_t
static amxc_llist_t s_rth_tasks
static void handle_rth_tasks(amxp_timer_t *timer, UNUSED void *priv)
static void rth_task_clean(rth_task_t *const task)
void rth_init(void)
static amxp_timer_t * s_timer_handle_rth_tasks
void rth_disable(const char *const object)
void rth_cleanup(void)
amxc_string_t path
amxc_llist_it_t it
uint8_t cntr
#define SHORT_TIMEOUT_MS
#define SAH_TRACEZ_DEBUG(zone, format,...)
Definition: xpon_trace.h:115
#define ME
Definition: xpon_trace.h:78