blob: ae6e0c69eb10dbdca262889db4400bb9ce88ded9 [file] [log] [blame]
Alex Stancu0c001822019-11-13 15:05:10 +02001/*************************************************************************
2*
3* Copyright 2019 highstreet technologies GmbH and others
4*
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
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
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***************************************************************************/
Alex Stancu29ce3682019-11-02 10:38:59 +020017
18#include <stdio.h>
19#include <stdlib.h>
20#include <unistd.h>
21#include <signal.h>
22#include <inttypes.h>
23#include <time.h>
24#include <math.h>
25#include <sys/time.h>
26
27#include "sysrepo.h"
28#include "sysrepo/values.h"
29
30#include "utils.h"
31
32#define LINE_BUFSIZE 128
33#define ORAN_FAULT_ALARMS_NUMBER 10
34#define AFFECTED_OBJECTS_MAX_NUMBER 100
35
36volatile int exit_application = 0;
37
38struct faultAlarms
39{
40 int faultId;
41 char* faultSource;
Alex Stancud7d89e02019-11-13 14:40:21 +020042 int cleared[10];
Alex Stancu29ce3682019-11-02 10:38:59 +020043 char* faultSeverity;
44 char* faultText;
45 char* affectedObjects[AFFECTED_OBJECTS_MAX_NUMBER];
46};
47struct faultAlarms oran_fault_alarms[ORAN_FAULT_ALARMS_NUMBER] = {
Alex Stancud7d89e02019-11-13 14:40:21 +020048 {.faultId = 1, .faultSource = "jknsdfnui", .affectedObjects = {"akddconoj", "asodmnjvf", "roiemfkmods"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "sdnjosopnojnsd"},
49 {.faultId = 2, .faultSource = "onascokjnasc", .affectedObjects = {"sdouvncsjdfv13", "asjdn13ejlncd4"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "WARNING", .faultText = "4pionfcsofn42on"},
50 {.faultId = 3, .faultSource = "asonxpkn", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "CRITICAL", .faultText = "sdjnonj32onjsa23"},
51 {.faultId = 4, .faultSource = "asnjcpkd", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023", "laksmdklmdas21"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MINOR", .faultText = "asdjln12osa453"},
52 {.faultId = 5, .faultSource = "dskmfl", .affectedObjects = {"sdkm31wdlk"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "dknovrf34ekl"},
53 {.faultId = 6, .faultSource = "dsllkje232kl", .affectedObjects = {"sFKOM24KLMerw"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "frpkm24k lsd kmewfpm"},
54 {.faultId = 7, .faultSource = "fvkdlsfjnwej23kloe", .affectedObjects = {"fvkm24km", "sdfk23d", "kmdfkmo32", "wekl2332"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "WARNING", .faultText = "dsm 2d 32j sdfmr32"},
55 {.faultId = 8, .faultSource = "dkom32", .affectedObjects = {"kmsdfkpm23ds", "sdmkp32"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "CRITICAL", .faultText = "dsonj32 don32 mdson32pk654"},
56 {.faultId = 9, .faultSource = "weflm3", .affectedObjects = {"klklm32kl3", "dsfln234poewj23-", "spmd32k"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MINOR", .faultText = "dsflknjwej32"},
57 {.faultId = 10, .faultSource = "fweiunvfrem32", .affectedObjects = {"sfkm23klsdf2343"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "dfskjnl4j dsfknl2 fodn54 65k"}
Alex Stancu29ce3682019-11-02 10:38:59 +020058};
59
60static CURL *curl;
61
62static int _init_curl()
63{
64 curl = curl_easy_init();
65
66 if (curl == NULL) {
67 printf("cURL initialization error! Aborting call!\n");
68 return SR_ERR_OPERATION_FAILED;
69 }
70
71 return SR_ERR_OK;
72}
73
74static int cleanup_curl()
75{
76 if (curl != NULL)
77 {
78 curl_easy_cleanup(curl);
79 }
80
81 return SR_ERR_OK;
82}
83
Alex Stancud7d89e02019-11-13 14:40:21 +020084static int send_fault_ves_message(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem, int port)
Alex Stancu29ce3682019-11-02 10:38:59 +020085{
Alex Stancud7d89e02019-11-13 14:40:21 +020086 int rc = SR_ERR_OK;
Alex Stancu29ce3682019-11-02 10:38:59 +020087 CURLcode res;
88 static sequence_id = 0;
Alex Stancud7d89e02019-11-13 14:40:21 +020089 int netconf_port_base = 0;
Alex Stancu29ce3682019-11-02 10:38:59 +020090
91 prepare_ves_message_curl(curl);
92
93 cJSON *postDataJson = cJSON_CreateObject();
94
95 cJSON *event = cJSON_CreateObject();
96 if (event == NULL)
97 {
98 printf("Could not create JSON object: event\n");
99 return 1;
100 }
101 cJSON_AddItemToObject(postDataJson, "event", event);
102
103 char *hostname = getenv("HOSTNAME");
Alex Stancud7d89e02019-11-13 14:40:21 +0200104 char *netconf_base_string = getenv("NETCONF_BASE");
Alex Stancu29ce3682019-11-02 10:38:59 +0200105
Alex Stancud7d89e02019-11-13 14:40:21 +0200106 if (netconf_base_string != NULL)
107 {
108 rc = sscanf(netconf_base_string, "%d", &netconf_port_base);
109 if (rc != 1)
110 {
111 printf("Could not find the NETCONF base port, aborting the PNF registration...\n");
112 return 1;
113 }
114 netconf_port_base += port;
115 }
116
117 char source_name[100];
118 sprintf(source_name, "%s_%d", hostname, netconf_port_base);
119
120 cJSON *commonEventHeader = vesCreateCommonEventHeader("fault", "O_RAN_COMPONENT_Alarms", source_name, sequence_id++);
Alex Stancu29ce3682019-11-02 10:38:59 +0200121 if (commonEventHeader == NULL)
122 {
123 printf("Could not create JSON object: commonEventHeader\n");
124 return 1;
125 }
126 cJSON_AddItemToObject(event, "commonEventHeader", commonEventHeader);
127
128 cJSON *faultFields = vesCreateFaultFields(alarm_condition, alarm_object, severity, date_time, specific_problem);
129 if (faultFields == NULL)
130 {
131 printf("Could not create JSON object: faultFields\n");
132 return 1;
133 }
134 cJSON_AddItemToObject(event, "faultFields", faultFields);
135
136 char *post_data_string = NULL;
137
138 post_data_string = cJSON_PrintUnformatted(postDataJson);
139
140 printf("Post data JSON:\n%s\n", post_data_string);
141
142 if (postDataJson != NULL)
143 {
144 cJSON_Delete(postDataJson);
145 }
146
147 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
148
149 res = curl_easy_perform(curl);
150
151 if (res != CURLE_OK)
152 {
153 printf("Failed to send cURL...\n");
154 return SR_ERR_OPERATION_FAILED;
155 }
156
157 return SR_ERR_OK;
158}
159
160static int send_dummy_notif_file_mgmt(sr_session_ctx_t *sess)
161{
162 int rc;
163
164 sr_val_t *vnotif;
165 size_t current_num_of_values= 0;
166
167 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
168
169 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-file-management:file-upload-notification/local-logical-file-path");
170 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, "odsanzucjsdoj");
171
172 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
173
174 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-file-management:file-upload-notification/remote-file-path");
175 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, "jsdknvjnkfd");
176
177 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
178
179 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-file-management:file-upload-notification/status");
180 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_ENUM_T, "SUCCESS");
181
182 rc = sr_event_notif_send(sess, "/o-ran-file-management:file-upload-notification", vnotif, current_num_of_values, SR_EV_NOTIF_DEFAULT);
183 if (rc != SR_ERR_OK) {
184 printf("Failed to send notification send_dummy_notif_file_mgmt\n");
185 return SR_ERR_OPERATION_FAILED;
186 }
187
188 printf("Successfully sent notification...\n");
189
190 sr_free_values(vnotif, current_num_of_values);
191
192 return SR_ERR_OK;
193}
194
195static int send_dummy_notif(sr_session_ctx_t *sess)
196{
197 int rc;
198
199 char dateAndTime[256];
200 time_t t = time(NULL);
201 struct tm tm = *localtime(&t);
202 struct timeval tv;
203 int millisec;
204
205 gettimeofday(&tv, NULL);
206 millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
207 if (millisec>=1000)
208 { // Allow for rounding up to nearest second
209 millisec -=1000;
210 tv.tv_sec++;
211 millisec /= 100;
212 }
213 sprintf(dateAndTime, "%04d-%02d-%02dT%02d:%02d:%02d.%01dZ",
214 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
215 tm.tm_hour, tm.tm_min, tm.tm_sec, millisec/100);
216
217 int ran = (int) random_at_most(ORAN_FAULT_ALARMS_NUMBER - 1);
218
Alex Stancud7d89e02019-11-13 14:40:21 +0200219 //TODO we hardcode here the number of ports for each device, 10
220 int random_port = (int) random_at_most(9);
221
222 if (oran_fault_alarms[ran].cleared[random_port] == 1)
Alex Stancu29ce3682019-11-02 10:38:59 +0200223 {
Alex Stancud7d89e02019-11-13 14:40:21 +0200224 oran_fault_alarms[ran].cleared[random_port] = 0;
Alex Stancu29ce3682019-11-02 10:38:59 +0200225 }
226 else
227 {
Alex Stancud7d89e02019-11-13 14:40:21 +0200228 oran_fault_alarms[ran].cleared[random_port] = 1;
Alex Stancu29ce3682019-11-02 10:38:59 +0200229 }
230
231 sr_val_t *vnotif;
232 size_t current_num_of_values= 0;
233
234 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
235
236 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-id");
237 vnotif[current_num_of_values - 1].type = SR_UINT16_T;
238 vnotif[current_num_of_values - 1].data.uint16_val = oran_fault_alarms[ran].faultId;
239
240 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
241
242 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-source");
243 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, oran_fault_alarms[ran].faultSource);
244
245 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
246
247 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-severity");
248 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_ENUM_T, oran_fault_alarms[ran].faultSeverity);
249
250 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
251
252 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/is-cleared");
253 vnotif[current_num_of_values - 1].type = SR_BOOL_T;
Alex Stancud7d89e02019-11-13 14:40:21 +0200254 vnotif[current_num_of_values - 1].data.bool_val = oran_fault_alarms[ran].cleared[random_port];
Alex Stancu29ce3682019-11-02 10:38:59 +0200255
256 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
257
258 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-text");
259 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, oran_fault_alarms[ran].faultText);
260
261 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
262
263 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/event-time");
264 sr_val_build_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, "%s", dateAndTime);
265
266 for (int i = 0; i < AFFECTED_OBJECTS_MAX_NUMBER; ++i)
267 {
268 char path[400];
269 if (oran_fault_alarms[ran].affectedObjects[i] == NULL)
270 {
271 break;
272 }
273
274 sprintf(path, "/o-ran-fm:alarm-notif/affected-objects[name='%s']", oran_fault_alarms[ran].affectedObjects[i]);
275
276 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
277
278 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", path);
279 vnotif[current_num_of_values - 1].type = SR_LIST_T;
280 }
281
282 int isNetconfAvailable = getNetconfAvailableFromConfigJson();
283 int isVesAvailable = getVesAvailableFromConfigJson();
284
285 if (isNetconfAvailable)
286 {
287 rc = sr_event_notif_send(sess, "/o-ran-fm:alarm-notif", vnotif, current_num_of_values, SR_EV_NOTIF_DEFAULT);
288 if (rc != SR_ERR_OK)
289 {
290 printf("Failed to send notification send_dummy_notif\n");
291 return SR_ERR_OPERATION_FAILED;
292 }
293 printf("Successfully sent notification with timestamp=\"%s\"\n", dateAndTime);
294 }
295 if (isVesAvailable)
296 {
297 char faultId[10];
298 sprintf(faultId, "%d", oran_fault_alarms[ran].faultId);
299 rc = send_fault_ves_message(faultId, oran_fault_alarms[ran].faultSource,
Alex Stancud7d89e02019-11-13 14:40:21 +0200300 (oran_fault_alarms[ran].cleared[random_port]) ? "NORMAL" : oran_fault_alarms[ran].faultSeverity, dateAndTime, oran_fault_alarms[ran].faultText, random_port);
Alex Stancu29ce3682019-11-02 10:38:59 +0200301 if (rc != SR_ERR_OK)
302 {
303 printf("Could not send Fault VES message\n");
304 }
305 }
306
307 sr_free_values(vnotif, current_num_of_values);
308
309 return SR_ERR_OK;
310}
311
312static void
313sigint_handler(int signum)
314{
315 exit_application = 1;
316}
317
318int
319main(int argc, char **argv)
320{
321 sr_conn_ctx_t *connection = NULL;
322 sr_session_ctx_t *session = NULL;
323 sr_subscription_ctx_t *subscription = NULL;
324 int rc = SR_ERR_OK;
325 int notification_delay_period = 0; //seconds
326
327 setbuf(stdout, NULL);
328
329 /* connect to sysrepo */
330 rc = sr_connect("oran_notifications", SR_CONN_DEFAULT, &connection);
331 if (SR_ERR_OK != rc) {
332 fprintf(stderr, "Error by sr_connect: %s\n", sr_strerror(rc));
333 goto cleanup;
334 }
335
336 /* start session */
337 rc = sr_session_start(connection, SR_DS_RUNNING, SR_SESS_DEFAULT, &session);
338 if (SR_ERR_OK != rc) {
339 fprintf(stderr, "Error by sr_session_start: %s\n", sr_strerror(rc));
340 goto cleanup;
341 }
342
343 rc = _init_curl();
344 if (rc != SR_ERR_OK)
345 {
346 fprintf(stderr, "Could not initialize cURL: %s\n", sr_strerror(rc));
347 goto cleanup;
348 }
349
350 /* loop until ctrl-c is pressed / SIGINT is received */
351 signal(SIGINT, sigint_handler);
352 signal(SIGPIPE, SIG_IGN);
353
354
355 while (!exit_application) {
356 notification_delay_period = getFaultNotificationDelayPeriodFromConfigJson();
357
358 if (notification_delay_period > 0)
359 {
360 send_dummy_notif(session);
361// send_dummy_notif_file_mgmt(session);
362
363 sleep(notification_delay_period);
364 }
365 else
366 {
367 sleep(1);
368 }
369
370 }
371
372 printf("Application exit requested, exiting.\n");
373
374cleanup:
375 if (NULL != subscription) {
376 sr_unsubscribe(session, subscription);
377 }
378 if (NULL != session) {
379 sr_session_stop(session);
380 }
381 if (NULL != connection) {
382 sr_disconnect(connection);
383 }
384 cleanup_curl();
385 printf("Error encountered. Exiting...");
386 return rc;
387}
388
389
390
391