blob: 747bec9abafff708ba1085b9163601e6fadeac11 [file] [log] [blame]
Alex Stancu29ce3682019-11-02 10:38:59 +02001/*
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
26volatile int exit_application = 0;
27
28struct faultAlarms
29{
30 int faultId;
31 char* faultSource;
Alex Stancud7d89e02019-11-13 14:40:21 +020032 int cleared[10];
Alex Stancu29ce3682019-11-02 10:38:59 +020033 char* faultSeverity;
34 char* faultText;
35 char* affectedObjects[AFFECTED_OBJECTS_MAX_NUMBER];
36};
37struct faultAlarms oran_fault_alarms[ORAN_FAULT_ALARMS_NUMBER] = {
Alex Stancud7d89e02019-11-13 14:40:21 +020038 {.faultId = 1, .faultSource = "jknsdfnui", .affectedObjects = {"akddconoj", "asodmnjvf", "roiemfkmods"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "sdnjosopnojnsd"},
39 {.faultId = 2, .faultSource = "onascokjnasc", .affectedObjects = {"sdouvncsjdfv13", "asjdn13ejlncd4"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "WARNING", .faultText = "4pionfcsofn42on"},
40 {.faultId = 3, .faultSource = "asonxpkn", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "CRITICAL", .faultText = "sdjnonj32onjsa23"},
41 {.faultId = 4, .faultSource = "asnjcpkd", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023", "laksmdklmdas21"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MINOR", .faultText = "asdjln12osa453"},
42 {.faultId = 5, .faultSource = "dskmfl", .affectedObjects = {"sdkm31wdlk"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "dknovrf34ekl"},
43 {.faultId = 6, .faultSource = "dsllkje232kl", .affectedObjects = {"sFKOM24KLMerw"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "frpkm24k lsd kmewfpm"},
44 {.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"},
45 {.faultId = 8, .faultSource = "dkom32", .affectedObjects = {"kmsdfkpm23ds", "sdmkp32"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "CRITICAL", .faultText = "dsonj32 don32 mdson32pk654"},
46 {.faultId = 9, .faultSource = "weflm3", .affectedObjects = {"klklm32kl3", "dsfln234poewj23-", "spmd32k"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MINOR", .faultText = "dsflknjwej32"},
47 {.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 +020048};
49
50static CURL *curl;
51
52static 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
64static int cleanup_curl()
65{
66 if (curl != NULL)
67 {
68 curl_easy_cleanup(curl);
69 }
70
71 return SR_ERR_OK;
72}
73
Alex Stancud7d89e02019-11-13 14:40:21 +020074static 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 +020075{
Alex Stancud7d89e02019-11-13 14:40:21 +020076 int rc = SR_ERR_OK;
Alex Stancu29ce3682019-11-02 10:38:59 +020077 CURLcode res;
78 static sequence_id = 0;
Alex Stancud7d89e02019-11-13 14:40:21 +020079 int netconf_port_base = 0;
Alex Stancu29ce3682019-11-02 10:38:59 +020080
81 prepare_ves_message_curl(curl);
82
83 cJSON *postDataJson = cJSON_CreateObject();
84
85 cJSON *event = cJSON_CreateObject();
86 if (event == NULL)
87 {
88 printf("Could not create JSON object: event\n");
89 return 1;
90 }
91 cJSON_AddItemToObject(postDataJson, "event", event);
92
93 char *hostname = getenv("HOSTNAME");
Alex Stancud7d89e02019-11-13 14:40:21 +020094 char *netconf_base_string = getenv("NETCONF_BASE");
Alex Stancu29ce3682019-11-02 10:38:59 +020095
Alex Stancud7d89e02019-11-13 14:40:21 +020096 if (netconf_base_string != NULL)
97 {
98 rc = sscanf(netconf_base_string, "%d", &netconf_port_base);
99 if (rc != 1)
100 {
101 printf("Could not find the NETCONF base port, aborting the PNF registration...\n");
102 return 1;
103 }
104 netconf_port_base += port;
105 }
106
107 char source_name[100];
108 sprintf(source_name, "%s_%d", hostname, netconf_port_base);
109
110 cJSON *commonEventHeader = vesCreateCommonEventHeader("fault", "O_RAN_COMPONENT_Alarms", source_name, sequence_id++);
Alex Stancu29ce3682019-11-02 10:38:59 +0200111 if (commonEventHeader == NULL)
112 {
113 printf("Could not create JSON object: commonEventHeader\n");
114 return 1;
115 }
116 cJSON_AddItemToObject(event, "commonEventHeader", commonEventHeader);
117
118 cJSON *faultFields = vesCreateFaultFields(alarm_condition, alarm_object, severity, date_time, specific_problem);
119 if (faultFields == NULL)
120 {
121 printf("Could not create JSON object: faultFields\n");
122 return 1;
123 }
124 cJSON_AddItemToObject(event, "faultFields", faultFields);
125
126 char *post_data_string = NULL;
127
128 post_data_string = cJSON_PrintUnformatted(postDataJson);
129
130 printf("Post data JSON:\n%s\n", post_data_string);
131
132 if (postDataJson != NULL)
133 {
134 cJSON_Delete(postDataJson);
135 }
136
137 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
138
139 res = curl_easy_perform(curl);
140
141 if (res != CURLE_OK)
142 {
143 printf("Failed to send cURL...\n");
144 return SR_ERR_OPERATION_FAILED;
145 }
146
147 return SR_ERR_OK;
148}
149
150static int send_dummy_notif_file_mgmt(sr_session_ctx_t *sess)
151{
152 int rc;
153
154 sr_val_t *vnotif;
155 size_t current_num_of_values= 0;
156
157 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
158
159 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-file-management:file-upload-notification/local-logical-file-path");
160 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, "odsanzucjsdoj");
161
162 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
163
164 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-file-management:file-upload-notification/remote-file-path");
165 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, "jsdknvjnkfd");
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/status");
170 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_ENUM_T, "SUCCESS");
171
172 rc = sr_event_notif_send(sess, "/o-ran-file-management:file-upload-notification", vnotif, current_num_of_values, SR_EV_NOTIF_DEFAULT);
173 if (rc != SR_ERR_OK) {
174 printf("Failed to send notification send_dummy_notif_file_mgmt\n");
175 return SR_ERR_OPERATION_FAILED;
176 }
177
178 printf("Successfully sent notification...\n");
179
180 sr_free_values(vnotif, current_num_of_values);
181
182 return SR_ERR_OK;
183}
184
185static int send_dummy_notif(sr_session_ctx_t *sess)
186{
187 int rc;
188
189 char dateAndTime[256];
190 time_t t = time(NULL);
191 struct tm tm = *localtime(&t);
192 struct timeval tv;
193 int millisec;
194
195 gettimeofday(&tv, NULL);
196 millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
197 if (millisec>=1000)
198 { // Allow for rounding up to nearest second
199 millisec -=1000;
200 tv.tv_sec++;
201 millisec /= 100;
202 }
203 sprintf(dateAndTime, "%04d-%02d-%02dT%02d:%02d:%02d.%01dZ",
204 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
205 tm.tm_hour, tm.tm_min, tm.tm_sec, millisec/100);
206
207 int ran = (int) random_at_most(ORAN_FAULT_ALARMS_NUMBER - 1);
208
Alex Stancud7d89e02019-11-13 14:40:21 +0200209 //TODO we hardcode here the number of ports for each device, 10
210 int random_port = (int) random_at_most(9);
211
212 if (oran_fault_alarms[ran].cleared[random_port] == 1)
Alex Stancu29ce3682019-11-02 10:38:59 +0200213 {
Alex Stancud7d89e02019-11-13 14:40:21 +0200214 oran_fault_alarms[ran].cleared[random_port] = 0;
Alex Stancu29ce3682019-11-02 10:38:59 +0200215 }
216 else
217 {
Alex Stancud7d89e02019-11-13 14:40:21 +0200218 oran_fault_alarms[ran].cleared[random_port] = 1;
Alex Stancu29ce3682019-11-02 10:38:59 +0200219 }
220
221 sr_val_t *vnotif;
222 size_t current_num_of_values= 0;
223
224 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
225
226 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-id");
227 vnotif[current_num_of_values - 1].type = SR_UINT16_T;
228 vnotif[current_num_of_values - 1].data.uint16_val = oran_fault_alarms[ran].faultId;
229
230 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
231
232 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-source");
233 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, oran_fault_alarms[ran].faultSource);
234
235 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
236
237 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-severity");
238 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_ENUM_T, oran_fault_alarms[ran].faultSeverity);
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/is-cleared");
243 vnotif[current_num_of_values - 1].type = SR_BOOL_T;
Alex Stancud7d89e02019-11-13 14:40:21 +0200244 vnotif[current_num_of_values - 1].data.bool_val = oran_fault_alarms[ran].cleared[random_port];
Alex Stancu29ce3682019-11-02 10:38:59 +0200245
246 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
247
248 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/fault-text");
249 sr_val_set_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, oran_fault_alarms[ran].faultText);
250
251 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
252
253 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/event-time");
254 sr_val_build_str_data(&vnotif[current_num_of_values - 1], SR_STRING_T, "%s", dateAndTime);
255
256 for (int i = 0; i < AFFECTED_OBJECTS_MAX_NUMBER; ++i)
257 {
258 char path[400];
259 if (oran_fault_alarms[ran].affectedObjects[i] == NULL)
260 {
261 break;
262 }
263
264 sprintf(path, "/o-ran-fm:alarm-notif/affected-objects[name='%s']", oran_fault_alarms[ran].affectedObjects[i]);
265
266 CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
267
268 sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", path);
269 vnotif[current_num_of_values - 1].type = SR_LIST_T;
270 }
271
272 int isNetconfAvailable = getNetconfAvailableFromConfigJson();
273 int isVesAvailable = getVesAvailableFromConfigJson();
274
275 if (isNetconfAvailable)
276 {
277 rc = sr_event_notif_send(sess, "/o-ran-fm:alarm-notif", vnotif, current_num_of_values, SR_EV_NOTIF_DEFAULT);
278 if (rc != SR_ERR_OK)
279 {
280 printf("Failed to send notification send_dummy_notif\n");
281 return SR_ERR_OPERATION_FAILED;
282 }
283 printf("Successfully sent notification with timestamp=\"%s\"\n", dateAndTime);
284 }
285 if (isVesAvailable)
286 {
287 char faultId[10];
288 sprintf(faultId, "%d", oran_fault_alarms[ran].faultId);
289 rc = send_fault_ves_message(faultId, oran_fault_alarms[ran].faultSource,
Alex Stancud7d89e02019-11-13 14:40:21 +0200290 (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 +0200291 if (rc != SR_ERR_OK)
292 {
293 printf("Could not send Fault VES message\n");
294 }
295 }
296
297 sr_free_values(vnotif, current_num_of_values);
298
299 return SR_ERR_OK;
300}
301
302static void
303sigint_handler(int signum)
304{
305 exit_application = 1;
306}
307
308int
309main(int argc, char **argv)
310{
311 sr_conn_ctx_t *connection = NULL;
312 sr_session_ctx_t *session = NULL;
313 sr_subscription_ctx_t *subscription = NULL;
314 int rc = SR_ERR_OK;
315 int notification_delay_period = 0; //seconds
316
317 setbuf(stdout, NULL);
318
319 /* connect to sysrepo */
320 rc = sr_connect("oran_notifications", SR_CONN_DEFAULT, &connection);
321 if (SR_ERR_OK != rc) {
322 fprintf(stderr, "Error by sr_connect: %s\n", sr_strerror(rc));
323 goto cleanup;
324 }
325
326 /* start session */
327 rc = sr_session_start(connection, SR_DS_RUNNING, SR_SESS_DEFAULT, &session);
328 if (SR_ERR_OK != rc) {
329 fprintf(stderr, "Error by sr_session_start: %s\n", sr_strerror(rc));
330 goto cleanup;
331 }
332
333 rc = _init_curl();
334 if (rc != SR_ERR_OK)
335 {
336 fprintf(stderr, "Could not initialize cURL: %s\n", sr_strerror(rc));
337 goto cleanup;
338 }
339
340 /* loop until ctrl-c is pressed / SIGINT is received */
341 signal(SIGINT, sigint_handler);
342 signal(SIGPIPE, SIG_IGN);
343
344
345 while (!exit_application) {
346 notification_delay_period = getFaultNotificationDelayPeriodFromConfigJson();
347
348 if (notification_delay_period > 0)
349 {
350 send_dummy_notif(session);
351// send_dummy_notif_file_mgmt(session);
352
353 sleep(notification_delay_period);
354 }
355 else
356 {
357 sleep(1);
358 }
359
360 }
361
362 printf("Application exit requested, exiting.\n");
363
364cleanup:
365 if (NULL != subscription) {
366 sr_unsubscribe(session, subscription);
367 }
368 if (NULL != session) {
369 sr_session_stop(session);
370 }
371 if (NULL != connection) {
372 sr_disconnect(connection);
373 }
374 cleanup_curl();
375 printf("Error encountered. Exiting...");
376 return rc;
377}
378
379
380
381