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