1 /*************************************************************************
3 * Copyright 2020 highstreet technologies GmbH and others
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
20 #include "supervisor.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
23 #include "utils/network_emulation.h"
27 #include "core/session.h"
28 #include "core/xpath.h"
29 #include "core/framework.h"
31 static int app_common_populate_info(void);
32 static int app_common_populate_network_emulation_info(void);
33 static int app_common_populate_network_emulation_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data);
35 int app_common_init(void) {
38 int rc = app_common_populate_info();
39 if(rc != NTS_ERR_OK) {
40 log_error("app_common_populate_info() failed\n");
41 return NTS_ERR_FAILED;
44 network_emulation_init();
46 rc = app_common_populate_network_emulation_info();
47 if(rc != NTS_ERR_OK) {
48 log_error("app_common_populate_network_emulation() failed\n");
49 return NTS_ERR_FAILED;
52 rc = sr_module_change_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH, app_common_populate_network_emulation_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_UPDATE, &session_subscription);
54 log_error("could not subscribe to faults");
55 return NTS_ERR_FAILED;
61 static int app_common_populate_info(void) {
64 if (framework_environment.nts.build_time && strlen(framework_environment.nts.build_time) > 0) {
65 rc = sr_set_item_str(session_operational, NTS_NF_INFO_SCHEMA_XPATH"/build-time", framework_environment.nts.build_time, 0, 0);
67 log_error("sr_set_item_str failed\n");
68 return NTS_ERR_FAILED;
72 rc = sr_set_item_str(session_operational, NTS_NF_INFO_SCHEMA_XPATH"/version", framework_environment.nts.version, 0, 0);
74 log_error("sr_set_item_str failed\n");
75 return NTS_ERR_FAILED;
78 rc = sr_apply_changes(session_operational, 0, 0);
80 log_error("sr_apply_changes failed: %s\n", sr_strerror(rc));
81 return NTS_ERR_FAILED;
87 static int app_common_populate_network_emulation_info(void) {
90 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/limit", NETWORK_EMULATION_DEFAULT_LIMIT, 0, 0);
92 log_error("sr_set_item_str failed\n");
93 return NTS_ERR_FAILED;
96 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/time", "0", 0, 0);
98 log_error("sr_set_item_str failed\n");
99 return NTS_ERR_FAILED;
102 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/jitter", "0", 0, 0);
103 if(rc != SR_ERR_OK) {
104 log_error("sr_set_item_str failed\n");
105 return NTS_ERR_FAILED;
108 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/correlation", "0", 0, 0);
109 if(rc != SR_ERR_OK) {
110 log_error("sr_set_item_str failed\n");
111 return NTS_ERR_FAILED;
114 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/distribution", "normal", 0, 0);
115 if(rc != SR_ERR_OK) {
116 log_error("sr_set_item_str failed\n");
117 return NTS_ERR_FAILED;
120 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/loss", "0", 0, 0);
121 if(rc != SR_ERR_OK) {
122 log_error("sr_set_item_str failed\n");
123 return NTS_ERR_FAILED;
126 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/corruption/percentage", "0", 0, 0);
127 if(rc != SR_ERR_OK) {
128 log_error("sr_set_item_str failed\n");
129 return NTS_ERR_FAILED;
132 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/corruption/correlation", "0", 0, 0);
133 if(rc != SR_ERR_OK) {
134 log_error("sr_set_item_str failed\n");
135 return NTS_ERR_FAILED;
138 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/duplication/percentage", "0", 0, 0);
139 if(rc != SR_ERR_OK) {
140 log_error("sr_set_item_str failed\n");
141 return NTS_ERR_FAILED;
144 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/duplication/correlation", "0", 0, 0);
145 if(rc != SR_ERR_OK) {
146 log_error("sr_set_item_str failed\n");
147 return NTS_ERR_FAILED;
150 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/reordering/percentage", "0", 0, 0);
151 if(rc != SR_ERR_OK) {
152 log_error("sr_set_item_str failed\n");
153 return NTS_ERR_FAILED;
156 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/reordering/correlation", "0", 0, 0);
157 if(rc != SR_ERR_OK) {
158 log_error("sr_set_item_str failed\n");
159 return NTS_ERR_FAILED;
162 rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/rate", "0", 0, 0);
163 if(rc != SR_ERR_OK) {
164 log_error("sr_set_item_str failed\n");
165 return NTS_ERR_FAILED;
168 rc = sr_apply_changes(session_running, 0, 0);
169 if(rc != SR_ERR_OK) {
170 log_error("sr_apply_changes failed: %s\n", sr_strerror(rc));
171 return NTS_ERR_FAILED;
177 static int app_common_populate_network_emulation_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) {
179 if(event == SR_EV_UPDATE) {
180 sr_change_iter_t *it = 0;
182 sr_change_oper_t oper;
183 sr_val_t *old_value = 0;
184 sr_val_t *new_value = 0;
186 rc = sr_get_changes_iter(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"//.", &it);
187 if(rc != SR_ERR_OK) {
188 log_error("sr_get_changes_iter failed\n");
189 return SR_ERR_VALIDATION_FAILED;
192 uint16_t delay_time = 0;
193 uint16_t delay_jitter = 0;
195 while((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) {
196 if(new_value->xpath && (strstr(new_value->xpath, "/delay/time"))) {
197 delay_time = new_value->data.uint16_val;
200 if(new_value->xpath && (strstr(new_value->xpath, "/delay/jitter"))) {
201 delay_jitter = new_value->data.uint16_val;
203 sr_free_val(old_value);
204 sr_free_val(new_value);
207 sr_free_change_iter(it);
209 if((delay_time == 0) || (delay_jitter == 0)) {
210 rc = sr_set_item_str(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/distribution", "normal", 0, 0);
211 if(rc != SR_ERR_OK) {
212 log_error("sr_set_item failed\n");
213 return SR_ERR_VALIDATION_FAILED;
217 if(delay_time == 0) {
218 rc = sr_set_item_str(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/jitter", "0", 0, 0);
219 if(rc != SR_ERR_OK) {
220 log_error("sr_set_item failed\n");
221 return SR_ERR_VALIDATION_FAILED;
224 rc = sr_set_item_str(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/correlation", "0", 0, 0);
225 if(rc != SR_ERR_OK) {
226 log_error("sr_set_item failed\n");
227 return SR_ERR_VALIDATION_FAILED;
231 else if(event == SR_EV_DONE) {
232 sr_val_t *values = NULL;
235 int rc = sr_get_items(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"//.", 0, 0, &values, &count);
236 if (rc != SR_ERR_OK) {
237 log_error("sr_get_items failed\n");
241 network_emultation_settings_t s;
243 for(size_t i = 0; i < count; i++) {
244 if(strstr(values[i].xpath, "/limit")) {
245 s.limit = values[i].data.uint16_val;
247 else if(strstr(values[i].xpath, "/delay/time")) {
248 s.delay.time = values[i].data.uint16_val;
250 else if(strstr(values[i].xpath, "/delay/jitter")) {
251 s.delay.jitter = values[i].data.uint16_val;
253 else if(strstr(values[i].xpath, "/delay/correlation")) {
254 s.delay.correlation = values[i].data.uint16_val;
256 else if(strstr(values[i].xpath, "/delay/distribution")) {
257 s.delay.distribution = strdup(values[i].data.string_val);
259 else if(strstr(values[i].xpath, "/loss")) {
260 s.loss = values[i].data.uint16_val;
262 else if(strstr(values[i].xpath, "/corruption/percentage")) {
263 s.corruption.percentage = values[i].data.uint16_val;
265 else if(strstr(values[i].xpath, "/corruption/correlation")) {
266 s.corruption.correlation = values[i].data.uint16_val;
268 else if(strstr(values[i].xpath, "/duplication/percentage")) {
269 s.duplication.percentage = values[i].data.uint16_val;
271 else if(strstr(values[i].xpath, "/duplication/correlation")) {
272 s.duplication.correlation = values[i].data.uint16_val;
274 else if(strstr(values[i].xpath, "/reordering/percentage")) {
275 s.reordering.percentage = values[i].data.uint16_val;
277 else if(strstr(values[i].xpath, "/reordering/correlation")) {
278 s.reordering.correlation = values[i].data.uint16_val;
280 else if(strstr(values[i].xpath, "/rate")) {
281 s.rate = values[i].data.uint16_val;
285 sr_free_values(values, count);
286 if(network_emulation_update(&s) != NTS_ERR_OK) {
287 log_error("network_emulation_update() failed\n");
288 free(s.delay.distribution);
289 return SR_ERR_OPERATION_FAILED;
291 free(s.delay.distribution);