745718bf84d3638f5c7a24d8db834947c8b2f4d4
[sim/o1-interface.git] / ntsimulator / src / utils / utils.c
1 /*
2  * utils.c
3  *
4  *  Created on: Feb 19, 2019
5  *      Author: parallels
6  */
7
8 #include "utils.h"
9
10 #include <math.h>
11 #include <time.h>
12 #include <sys/time.h>
13 #include <stdio.h>
14
15 void set_curl_common_info_ves(CURL *curl)
16 {
17         struct curl_slist *chunk = NULL;
18         chunk = curl_slist_append(chunk, "Content-Type: application/json");
19         chunk = curl_slist_append(chunk, "Accept: application/json");
20
21     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
22
23     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
24     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); //seconds timeout for an operation
25
26     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
27 }
28
29 void getCurrentDateAndTime(char *date_and_time)
30 {
31         time_t t = time(NULL);
32         struct tm tm = *localtime(&t);
33         struct timeval tv;
34         int millisec;
35
36         gettimeofday(&tv, NULL);
37         millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
38         if (millisec>=1000)
39         { // Allow for rounding up to nearest second
40                 millisec -=1000;
41                 tv.tv_sec++;
42                 millisec /= 100;
43         }
44         sprintf(date_and_time, "%04d-%02d-%02dT%02d:%02d:%02d.%01dZ",
45         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
46         tm.tm_hour, tm.tm_min, tm.tm_sec, millisec/100);
47
48         return;
49 }
50
51 void    generateRandomMacAddress(char *mac_address)
52 {
53         long rand1, rand2, rand3, rand4, rand5, rand6;
54         rand1 = random_at_most(255);
55         rand2 = random_at_most(255);
56         rand3 = random_at_most(255);
57         rand4 = random_at_most(255);
58         rand5 = random_at_most(255);
59         rand6 = random_at_most(255);
60
61         sprintf(mac_address, "%02X:%02X:%02X:%02X:%02X:%02X", rand1, rand2, rand3, rand4, rand5, rand6);
62
63         return;
64 }
65
66 long random_at_most(long max) {
67   unsigned long
68     // max <= RAND_MAX < ULONG_MAX, so this is okay.
69     num_bins = (unsigned long) max + 1,
70     num_rand = (unsigned long) RAND_MAX + 1,
71     bin_size = num_rand / num_bins,
72     defect   = num_rand % num_bins;
73
74   long x;
75   do {
76    x = random();
77   }
78   // This is carefully written not to overflow
79   while (num_rand - defect <= (unsigned long)x);
80
81   // Truncated division is intentional
82   return x/bin_size;
83 }
84
85 int getSecondsFromLastQuarterInterval(void)
86 {
87         time_t t = time(NULL);
88         time_t t_past = time(NULL);
89         struct tm tm = *localtime(&t);
90         struct tm tm_15_min_ago = tm;
91
92         //round to the last quarter hour
93         tm_15_min_ago.tm_min -= (tm_15_min_ago.tm_min % 15);
94         tm_15_min_ago.tm_sec = 0;
95
96         t=mktime(&tm_15_min_ago);
97         t_past=mktime(&tm);
98
99         double seconds = difftime(t_past, t);
100
101         return (int)seconds;
102 }
103
104 int getSecondsFromLastDayInterval(void)
105 {
106         time_t t = time(NULL);
107         time_t t_past = time(NULL);
108         struct tm tm = *localtime(&t);
109         struct tm tm_day_ago = tm;
110
111         //round to the last quarter hour
112         tm_day_ago.tm_hour = 0;
113         tm_day_ago.tm_min = 0;
114         tm_day_ago.tm_sec = 0;
115
116         t=mktime(&tm_day_ago);
117         t_past=mktime(&tm);
118
119         double seconds = difftime(t_past, t);
120
121         return (int)seconds;
122 }
123
124 void getPreviousQuarterInterval(int number_of_intervals, char *date_and_time)
125 {
126         time_t t = time(NULL);
127         t -= 15 * 60 * number_of_intervals;
128         struct tm tm = *localtime(&t);
129
130         tm.tm_min -= (tm.tm_min % 15);
131         tm.tm_sec = 0;
132
133         sprintf(date_and_time, "%04d-%02d-%02dT%02d:%02d:%02d.0Z",
134         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
135         tm.tm_hour, tm.tm_min, tm.tm_sec);
136
137         return;
138 }
139
140 void getPreviousDayPmTimestamp(int number_of_intervals, char *date_and_time)
141 {
142         time_t t = time(NULL);
143         t -= 24 * 60 * 60 * number_of_intervals;
144         struct tm tm = *localtime(&t);
145
146         tm.tm_hour = 0;
147         tm.tm_min = 0;
148         tm.tm_sec = 0;
149
150         sprintf(date_and_time, "%04d-%02d-%02dT%02d:%02d:%02d.0Z",
151         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
152         tm.tm_hour, tm.tm_min, tm.tm_sec);
153
154         return;
155 }
156
157 long int getMicrosecondsSinceEpoch(void)
158 {
159         time_t t = time(NULL);
160         struct tm tm = *localtime(&t);
161         struct timeval tv;
162         long int useconds;
163
164         gettimeofday(&tv, NULL);
165         useconds = t*1000 + tv.tv_usec; //add the microseconds to the seconds
166
167         return useconds;
168 }
169
170 //TODO need to implement other authentication methods as well, not only no-auth
171 void prepare_ves_message_curl(CURL *curl)
172 {
173         curl_easy_reset(curl);
174         set_curl_common_info_ves(curl);
175
176         char *ves_ip = getVesIpFromConfigJson();
177         int ves_port = getVesPortFromConfigJson();
178
179         char url[100];
180         sprintf(url, "http://%s:%d/eventListener/v7", ves_ip, ves_port);
181         curl_easy_setopt(curl, CURLOPT_URL, url);
182
183         free(ves_ip);
184
185 //      curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
186
187         return;
188 }
189
190 cJSON*  vesCreateCommonEventHeader(char *domain, char *event_type, char *source_name, int seq_id)
191 {
192         char dateAndTime[50];
193         getCurrentDateAndTime(dateAndTime);
194
195     char hostname[100];
196     sprintf(hostname, "%s", getenv("HOSTNAME"));
197
198         long int useconds = getMicrosecondsSinceEpoch;
199
200         cJSON *commonEventHeader = cJSON_CreateObject();
201         if (commonEventHeader == NULL)
202         {
203                 printf("Could not create JSON object: commonEventHeader\n");
204                 return NULL;
205         }
206
207         if (cJSON_AddStringToObject(commonEventHeader, "domain", domain) == NULL)
208         {
209                 printf("Could not create JSON object: domain\n");
210                 return NULL;
211         }
212
213         char eventId[200];
214         sprintf(eventId, "%s_%s", hostname, dateAndTime);
215
216         if (cJSON_AddStringToObject(commonEventHeader, "eventId", eventId) == NULL)
217         {
218                 printf("Could not create JSON object: eventId\n");
219                 return NULL;
220         }
221
222         char event_name[200];
223         sprintf(event_name, "%s_%s", domain, event_type);
224
225         if (cJSON_AddStringToObject(commonEventHeader, "eventName", event_name) == NULL)
226         {
227                 printf("Could not create JSON object: eventName\n");
228                 return NULL;
229         }
230
231         if (cJSON_AddStringToObject(commonEventHeader, "eventType", event_type) == NULL)
232         {
233                 printf("Could not create JSON object: eventType\n");
234                 return NULL;
235         }
236
237         if (cJSON_AddNumberToObject(commonEventHeader, "sequence", (double)(seq_id)) == NULL)
238         {
239                 printf("Could not create JSON object: sequence\n");
240                 return NULL;
241         }
242
243         if (cJSON_AddStringToObject(commonEventHeader, "priority", "Low") == NULL)
244         {
245                 printf("Could not create JSON object: priority\n");
246                 return NULL;
247         }
248
249         if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityId", "") == NULL)
250         {
251                 printf("Could not create JSON object: reportingEntityId\n");
252                 return NULL;
253         }
254
255         if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityName", hostname) == NULL)
256         {
257                 printf("Could not create JSON object: reportingEntityName\n");
258                 return NULL;
259         }
260
261         if (cJSON_AddStringToObject(commonEventHeader, "sourceId", "") == NULL)
262         {
263                 printf("Could not create JSON object: sourceId\n");
264                 return NULL;
265         }
266
267         if (cJSON_AddStringToObject(commonEventHeader, "sourceName", source_name) == NULL)
268         {
269                 printf("Could not create JSON object: sourceName\n");
270                 return NULL;
271         }
272
273         if (cJSON_AddNumberToObject(commonEventHeader, "startEpochMicrosec", (double)(useconds)) == NULL)
274         {
275                 printf("Could not create JSON object: startEpochMicrosec\n");
276                 return NULL;
277         }
278
279         if (cJSON_AddNumberToObject(commonEventHeader, "lastEpochMicrosec", (double)(useconds)) == NULL)
280         {
281                 printf("Could not create JSON object: lastEpochMicrosec\n");
282                 return NULL;
283         }
284
285         if (cJSON_AddStringToObject(commonEventHeader, "nfNamingCode", "sdn controller") == NULL)
286         {
287                 printf("Could not create JSON object: nfNamingCode\n");
288                 return NULL;
289         }
290
291         if (cJSON_AddStringToObject(commonEventHeader, "nfVendorName", "sdn") == NULL)
292         {
293                 printf("Could not create JSON object: nfVendorName\n");
294                 return NULL;
295         }
296
297         if (cJSON_AddStringToObject(commonEventHeader, "timeZoneOffset", "+00:00") == NULL)
298         {
299                 printf("Could not create JSON object: timeZoneOffset\n");
300                 return NULL;
301         }
302
303         if (cJSON_AddStringToObject(commonEventHeader, "version", "4.0.1") == NULL)
304         {
305                 printf("Could not create JSON object: version\n");
306                 return NULL;
307         }
308
309         if (cJSON_AddStringToObject(commonEventHeader, "vesEventListenerVersion", "7.0.1") == NULL)
310         {
311                 printf("Could not create JSON object: vesEventListenerVersion\n");
312                 return NULL;
313         }
314
315         return commonEventHeader;
316 }
317
318 cJSON*  vesCreateHeartbeatFields(int heartbeat_interval)
319 {
320         char dateAndTime[50];
321         getCurrentDateAndTime(dateAndTime);
322
323         cJSON *heartbeatFields = cJSON_CreateObject();
324         if (heartbeatFields == NULL)
325         {
326                 printf("Could not create JSON object: heartbeatFields\n");
327                 return NULL;
328         }
329
330         if (cJSON_AddStringToObject(heartbeatFields, "heartbeatFieldsVersion", "3.0") == NULL)
331         {
332                 printf("Could not create JSON object: heartbeatFieldsVersion\n");
333                 return NULL;
334         }
335
336         if (cJSON_AddNumberToObject(heartbeatFields, "heartbeatInterval", (double)(heartbeat_interval)) == NULL)
337         {
338                 printf("Could not create JSON object: heartbeatInterval\n");
339                 return NULL;
340         }
341
342         cJSON *additionalFields = cJSON_CreateObject();
343         if (additionalFields == NULL)
344         {
345                 printf("Could not create JSON object: additionalFields\n");
346                 return NULL;
347         }
348         cJSON_AddItemToObject(heartbeatFields, "additionalFields", additionalFields);
349
350         if (cJSON_AddStringToObject(additionalFields, "eventTime", dateAndTime) == NULL)
351         {
352                 printf("Could not create JSON object: eventTime\n");
353                 return NULL;
354         }
355
356         return heartbeatFields;
357 }
358
359 char*   readConfigFileInString(void)
360 {
361         char * buffer = 0;
362         long length;
363         char config_file[200];
364         sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
365         FILE * f = fopen (config_file, "rb");
366
367         if (f)
368         {
369           fseek (f, 0, SEEK_END);
370           length = ftell (f);
371           fseek (f, 0, SEEK_SET);
372           buffer = malloc (length + 1);
373           if (buffer)
374           {
375             fread (buffer, 1, length, f);
376           }
377           fclose (f);
378           buffer[length] = '\0';
379         }
380
381         if (buffer)
382         {
383           return buffer;
384         }
385
386         return NULL;
387 }
388
389 void    writeConfigFile(char *config)
390 {
391         char * buffer = 0;
392         long length;
393         char config_file[200];
394         sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
395         FILE * f = fopen (config_file, "w");
396
397         if (f)
398         {
399                 fputs(config, f);
400                 fclose(f);
401         }
402         else
403         {
404                 printf("Could not write configuration file");
405         }
406 }
407
408 int     getFaultNotificationDelayPeriodFromConfigJson(void)
409 {
410         char *stringConfig = readConfigFileInString();
411         int notificationDelay = 0;
412
413         if (stringConfig == NULL)
414         {
415                 printf("Could not read JSON configuration file in string.");
416                 return 0;
417         }
418
419         cJSON *jsonConfig = cJSON_Parse(stringConfig);
420         if (jsonConfig == NULL)
421         {
422                 free(stringConfig);
423                 const char *error_ptr = cJSON_GetErrorPtr();
424                 if (error_ptr != NULL)
425                 {
426                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
427                 }
428                 return SR_ERR_OPERATION_FAILED;
429         }
430         //we don't need the string anymore
431         free(stringConfig);
432
433         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
434         if (!cJSON_IsObject(notifConfig))
435         {
436                 printf("Configuration JSON is not as expected: notification-config is not an object");
437                 free(jsonConfig);
438                 return SR_ERR_OPERATION_FAILED;
439         }
440
441         cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
442         if (!cJSON_IsNumber(faultNotifDelay))
443         {
444                 printf("Configuration JSON is not as expected: fault-notification-delay-period is not a number");
445                 free(jsonConfig);
446                 return SR_ERR_OPERATION_FAILED;
447         }
448
449         notificationDelay = (int)(faultNotifDelay->valuedouble);
450
451         free(jsonConfig);
452
453         return notificationDelay;
454 }
455
456 int     getVesHeartbeatPeriodFromConfigJson(void)
457 {
458         char *stringConfig = readConfigFileInString();
459         int vesHeartbeat = 0;
460
461         if (stringConfig == NULL)
462         {
463                 printf("Could not read JSON configuration file in string.");
464                 return 0;
465         }
466
467         cJSON *jsonConfig = cJSON_Parse(stringConfig);
468         if (jsonConfig == NULL)
469         {
470                 free(stringConfig);
471                 const char *error_ptr = cJSON_GetErrorPtr();
472                 if (error_ptr != NULL)
473                 {
474                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
475                 }
476                 return SR_ERR_OPERATION_FAILED;
477         }
478         //we don't need the string anymore
479         free(stringConfig);
480
481         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
482         if (!cJSON_IsObject(notifConfig))
483         {
484                 printf("Configuration JSON is not as expected: notification-config is not an object");
485                 free(jsonConfig);
486                 return SR_ERR_OPERATION_FAILED;
487         }
488
489         cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
490         if (!cJSON_IsNumber(vesHeartbeatPeriod))
491         {
492                 printf("Configuration JSON is not as expected: ves-heartbeat-period is not a number");
493                 free(jsonConfig);
494                 return SR_ERR_OPERATION_FAILED;
495         }
496
497         vesHeartbeat = (int)(vesHeartbeatPeriod->valuedouble);
498
499         free(jsonConfig);
500
501         return vesHeartbeat;
502 }
503
504
505 /*
506  * Dynamically allocated memory;
507  * Caller needs to free the memory after it uses the value.
508  *
509 */
510 char*   getVesAuthMethodFromConfigJson(void)
511 {
512         char *stringConfig = readConfigFileInString();
513
514         if (stringConfig == NULL)
515         {
516                 printf("Could not read JSON configuration file in string.");
517                 return 0;
518         }
519
520         cJSON *jsonConfig = cJSON_Parse(stringConfig);
521         if (jsonConfig == NULL)
522         {
523                 free(stringConfig);
524                 const char *error_ptr = cJSON_GetErrorPtr();
525                 if (error_ptr != NULL)
526                 {
527                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
528                 }
529                 return SR_ERR_OPERATION_FAILED;
530         }
531         //we don't need the string anymore
532         free(stringConfig);
533
534         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
535         if (!cJSON_IsObject(vesDetails))
536         {
537                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
538                 free(jsonConfig);
539                 return SR_ERR_OPERATION_FAILED;
540         }
541
542         cJSON *vesAuthMethod = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-auth-method");
543         if (!cJSON_IsString(vesAuthMethod))
544         {
545                 printf("Configuration JSON is not as expected: ves-endpoint-auth-method is not an object");
546                 free(jsonConfig);
547                 return SR_ERR_OPERATION_FAILED;
548         }
549
550         char *auth_method_string = strdup(cJSON_GetStringValue(vesAuthMethod));
551
552         free(jsonConfig);
553
554         return auth_method_string;
555 }
556
557 /*
558  * Dynamically allocated memory;
559  * Caller needs to free the memory after it uses the value.
560  *
561 */
562 char*   getVesIpFromConfigJson(void)
563 {
564         char *stringConfig = readConfigFileInString();
565
566         if (stringConfig == NULL)
567         {
568                 printf("Could not read JSON configuration file in string.");
569                 return 0;
570         }
571
572         cJSON *jsonConfig = cJSON_Parse(stringConfig);
573         if (jsonConfig == NULL)
574         {
575                 free(stringConfig);
576                 const char *error_ptr = cJSON_GetErrorPtr();
577                 if (error_ptr != NULL)
578                 {
579                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
580                 }
581                 return SR_ERR_OPERATION_FAILED;
582         }
583         //we don't need the string anymore
584         free(stringConfig);
585
586         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
587         if (!cJSON_IsObject(vesDetails))
588         {
589                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
590                 free(jsonConfig);
591                 return SR_ERR_OPERATION_FAILED;
592         }
593
594         cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
595         if (!cJSON_IsString(vesIp))
596         {
597                 printf("Configuration JSON is not as expected: ves-endpoint-ip is not an object");
598                 free(jsonConfig);
599                 return SR_ERR_OPERATION_FAILED;
600         }
601
602         char *ves_ip = strdup(cJSON_GetStringValue(vesIp));
603
604         free(jsonConfig);
605
606         return ves_ip;
607 }
608
609 int     getVesPortFromConfigJson(void)
610 {
611         char *stringConfig = readConfigFileInString();
612
613         if (stringConfig == NULL)
614         {
615                 printf("Could not read JSON configuration file in string.");
616                 return 0;
617         }
618
619         cJSON *jsonConfig = cJSON_Parse(stringConfig);
620         if (jsonConfig == NULL)
621         {
622                 free(stringConfig);
623                 const char *error_ptr = cJSON_GetErrorPtr();
624                 if (error_ptr != NULL)
625                 {
626                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
627                 }
628                 return SR_ERR_OPERATION_FAILED;
629         }
630         //we don't need the string anymore
631         free(stringConfig);
632
633         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
634         if (!cJSON_IsObject(vesDetails))
635         {
636                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
637                 free(jsonConfig);
638                 return SR_ERR_OPERATION_FAILED;
639         }
640
641         cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
642         if (!cJSON_IsNumber(vesPort))
643         {
644                 printf("Configuration JSON is not as expected: ves-endpoint-port is not an object");
645                 free(jsonConfig);
646                 return SR_ERR_OPERATION_FAILED;
647         }
648
649         int port = (int)(vesPort->valuedouble);
650
651         free(jsonConfig);
652
653         return port;
654 }
655
656 int     getVesRegistrationFromConfigJson(void)
657 {
658         char *stringConfig = readConfigFileInString();
659
660         if (stringConfig == NULL)
661         {
662                 printf("Could not read JSON configuration file in string.");
663                 return 0;
664         }
665
666         cJSON *jsonConfig = cJSON_Parse(stringConfig);
667         if (jsonConfig == NULL)
668         {
669                 free(stringConfig);
670                 const char *error_ptr = cJSON_GetErrorPtr();
671                 if (error_ptr != NULL)
672                 {
673                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
674                 }
675                 return SR_ERR_OPERATION_FAILED;
676         }
677         //we don't need the string anymore
678         free(stringConfig);
679
680         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
681         if (!cJSON_IsObject(vesDetails))
682         {
683                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
684                 free(jsonConfig);
685                 return SR_ERR_OPERATION_FAILED;
686         }
687
688         cJSON *vesReg = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
689         if (!cJSON_IsBool(vesReg))
690         {
691                 printf("Configuration JSON is not as expected: ves-registration is not an object");
692                 free(jsonConfig);
693                 return SR_ERR_OPERATION_FAILED;
694         }
695
696         int is_ves_reg = (cJSON_IsTrue(vesReg)) ? TRUE : FALSE;
697
698         free(jsonConfig);
699
700         return is_ves_reg;
701 }
702
703 cJSON*  vesCreatePnfRegistrationFields(int port, bool is_tls)
704 {
705         cJSON *pnfRegistrationFields = cJSON_CreateObject();
706         if (pnfRegistrationFields == NULL)
707         {
708                 printf("Could not create JSON object: pnfRegistrationFields\n");
709                 return NULL;
710         }
711
712         if (cJSON_AddStringToObject(pnfRegistrationFields, "pnfRegistrationFieldsVersion", "2.0") == NULL)
713         {
714                 printf("Could not create JSON object: pnfRegistrationFieldsVersion\n");
715                 return NULL;
716         }
717
718         if (cJSON_AddStringToObject(pnfRegistrationFields, "lastServiceDate", "2019-08-16") == NULL)
719         {
720                 printf("Could not create JSON object: lastServiceDate\n");
721                 return NULL;
722         }
723
724         char mac_addr[40];
725         generateRandomMacAddress(mac_addr);
726
727         if (cJSON_AddStringToObject(pnfRegistrationFields, "macAddress", mac_addr) == NULL)
728         {
729                 printf("Could not create JSON object: macAddress\n");
730                 return NULL;
731         }
732
733         if (cJSON_AddStringToObject(pnfRegistrationFields, "manufactureDate", "2019-08-16") == NULL)
734         {
735                 printf("Could not create JSON object: manufactureDate\n");
736                 return NULL;
737         }
738
739         if (cJSON_AddStringToObject(pnfRegistrationFields, "modelNumber", "Simulated Device Melacon") == NULL)
740         {
741                 printf("Could not create JSON object: manufactureDate\n");
742                 return NULL;
743         }
744
745         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV4IpAddress", getenv("NTS_IP")) == NULL)
746         {
747                 printf("Could not create JSON object: oamV4IpAddress\n");
748                 return NULL;
749         }
750
751         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV6IpAddress", "0:0:0:0:0:ffff:a0a:011") == NULL)
752         {
753                 printf("Could not create JSON object: oamV6IpAddress\n");
754                 return NULL;
755         }
756
757         char serial_number[100];
758         sprintf(serial_number, "%s-%s-%d-Simulated Device Melacon", getenv("HOSTNAME"), getenv("NTS_IP"), port);
759
760         if (cJSON_AddStringToObject(pnfRegistrationFields, "serialNumber", serial_number) == NULL)
761         {
762                 printf("Could not create JSON object: serialNumber\n");
763                 return NULL;
764         }
765
766         if (cJSON_AddStringToObject(pnfRegistrationFields, "softwareVersion", "2.3.5") == NULL)
767         {
768                 printf("Could not create JSON object: softwareVersion\n");
769                 return NULL;
770         }
771
772         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitFamily", "Simulated Device") == NULL)
773         {
774                 printf("Could not create JSON object: unitFamily\n");
775                 return NULL;
776         }
777
778         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitType", "O-RAN-sim") == NULL)
779         {
780                 printf("Could not create JSON object: unitType\n");
781                 return NULL;
782         }
783
784         if (cJSON_AddStringToObject(pnfRegistrationFields, "vendorName", "Melacon") == NULL)
785         {
786                 printf("Could not create JSON object: vendorName\n");
787                 return NULL;
788         }
789
790         cJSON *additionalFields = cJSON_CreateObject();
791         if (additionalFields == NULL)
792         {
793                 printf("Could not create JSON object: additionalFields\n");
794                 return NULL;
795         }
796         cJSON_AddItemToObject(pnfRegistrationFields, "additionalFields", additionalFields);
797
798         char portString[10];
799         sprintf(portString, "%d", port);
800
801         if (cJSON_AddStringToObject(additionalFields, "oamPort", portString) == NULL)
802         {
803                 printf("Could not create JSON object: oamPort\n");
804                 return NULL;
805         }
806
807         if (is_tls)
808         {
809                 //TLS specific configuration
810                 if (cJSON_AddStringToObject(additionalFields, "protocol", "TLS") == NULL)
811                 {
812                         printf("Could not create JSON object: protocol\n");
813                         return NULL;
814                 }
815
816                 //TODO here we have the username from the docker container hardcoded: netconf
817                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
818                 {
819                         printf("Could not create JSON object: username\n");
820                         return NULL;
821                 }
822
823                 if (cJSON_AddStringToObject(additionalFields, "keyId", "device-key") == NULL)
824                 {
825                         printf("Could not create JSON object: keyId\n");
826                         return NULL;
827                 }
828         }
829         else
830         {
831                 //SSH specific configuration
832                 if (cJSON_AddStringToObject(additionalFields, "protocol", "SSH") == NULL)
833                 {
834                         printf("Could not create JSON object: protocol\n");
835                         return NULL;
836                 }
837
838                 //TODO here we have the username from the docker container hardcoded: netconf
839                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
840                 {
841                         printf("Could not create JSON object: username\n");
842                         return NULL;
843                 }
844
845                 //TODO here we have the password from the docker container hardcoded: netconf
846                 if (cJSON_AddStringToObject(additionalFields, "password", "netconf") == NULL)
847                 {
848                         printf("Could not create JSON object: password\n");
849                         return NULL;
850                 }
851         }
852
853         if (cJSON_AddStringToObject(additionalFields, "reconnectOnChangedSchema", "false") == NULL)
854         {
855                 printf("Could not create JSON object: reconnectOnChangedSchema\n");
856                 return NULL;
857         }
858
859         if (cJSON_AddStringToObject(additionalFields, "sleep-factor", "1.5") == NULL)
860         {
861                 printf("Could not create JSON object: sleep-factor\n");
862                 return NULL;
863         }
864
865         if (cJSON_AddStringToObject(additionalFields, "tcpOnly", "false") == NULL)
866         {
867                 printf("Could not create JSON object: tcpOnly\n");
868                 return NULL;
869         }
870
871         if (cJSON_AddStringToObject(additionalFields, "connectionTimeout", "20000") == NULL)
872         {
873                 printf("Could not create JSON object: connectionTimeout\n");
874                 return NULL;
875         }
876
877         if (cJSON_AddStringToObject(additionalFields, "maxConnectionAttempts", "100") == NULL)
878         {
879                 printf("Could not create JSON object: maxConnectionAttempts\n");
880                 return NULL;
881         }
882
883         if (cJSON_AddStringToObject(additionalFields, "betweenAttemptsTimeout", "2000") == NULL)
884         {
885                 printf("Could not create JSON object: betweenAttemptsTimeout\n");
886                 return NULL;
887         }
888
889         if (cJSON_AddStringToObject(additionalFields, "keepaliveDelay", "120") == NULL)
890         {
891                 printf("Could not create JSON object: keepaliveDelay\n");
892                 return NULL;
893         }
894
895         return pnfRegistrationFields;
896 }
897
898 int     getNetconfAvailableFromConfigJson(void)
899 {
900         char *stringConfig = readConfigFileInString();
901
902         if (stringConfig == NULL)
903         {
904                 printf("Could not read JSON configuration file in string.");
905                 return 0;
906         }
907
908         cJSON *jsonConfig = cJSON_Parse(stringConfig);
909         if (jsonConfig == NULL)
910         {
911                 free(stringConfig);
912                 const char *error_ptr = cJSON_GetErrorPtr();
913                 if (error_ptr != NULL)
914                 {
915                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
916                 }
917                 return SR_ERR_OPERATION_FAILED;
918         }
919         //we don't need the string anymore
920         free(stringConfig);
921
922         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
923         if (!cJSON_IsObject(notifDetails))
924         {
925                 printf("Configuration JSON is not as expected: notification-config is not an object");
926                 free(jsonConfig);
927                 return SR_ERR_OPERATION_FAILED;
928         }
929
930         cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-netconf-available");
931         if (!cJSON_IsBool(isNetconfAvailable))
932         {
933                 printf("Configuration JSON is not as expected: is-netconf-available is not an object");
934                 free(jsonConfig);
935                 return SR_ERR_OPERATION_FAILED;
936         }
937
938         int is_netconf_available = (cJSON_IsTrue(isNetconfAvailable)) ? TRUE : FALSE;
939
940         free(jsonConfig);
941
942         return is_netconf_available;
943 }
944
945 int     getVesAvailableFromConfigJson(void)
946 {
947         char *stringConfig = readConfigFileInString();
948
949         if (stringConfig == NULL)
950         {
951                 printf("Could not read JSON configuration file in string.");
952                 return 0;
953         }
954
955         cJSON *jsonConfig = cJSON_Parse(stringConfig);
956         if (jsonConfig == NULL)
957         {
958                 free(stringConfig);
959                 const char *error_ptr = cJSON_GetErrorPtr();
960                 if (error_ptr != NULL)
961                 {
962                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
963                 }
964                 return SR_ERR_OPERATION_FAILED;
965         }
966         //we don't need the string anymore
967         free(stringConfig);
968
969         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
970         if (!cJSON_IsObject(notifDetails))
971         {
972                 printf("Configuration JSON is not as expected: notification-config is not an object");
973                 free(jsonConfig);
974                 return SR_ERR_OPERATION_FAILED;
975         }
976
977         cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-ves-available");
978         if (!cJSON_IsBool(isVesAvailable))
979         {
980                 printf("Configuration JSON is not as expected: is-ves-available is not an object");
981                 free(jsonConfig);
982                 return SR_ERR_OPERATION_FAILED;
983         }
984
985         int is_netconf_available = (cJSON_IsTrue(isVesAvailable)) ? TRUE : FALSE;
986
987         free(jsonConfig);
988
989         return is_netconf_available;
990 }
991
992 cJSON*  vesCreateFaultFields(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem)
993 {
994         cJSON *faultFields = cJSON_CreateObject();
995         if (faultFields == NULL)
996         {
997                 printf("Could not create JSON object: faultFields\n");
998                 return NULL;
999         }
1000
1001         if (cJSON_AddStringToObject(faultFields, "faultFieldsVersion", "4.0") == NULL)
1002         {
1003                 printf("Could not create JSON object: faultFieldsVersion\n");
1004                 return NULL;
1005         }
1006
1007         if (cJSON_AddStringToObject(faultFields, "alarmCondition", alarm_condition) == NULL)
1008         {
1009                 printf("Could not create JSON object: alarmCondition\n");
1010                 return NULL;
1011         }
1012
1013         if (cJSON_AddStringToObject(faultFields, "alarmInterfaceA", alarm_object) == NULL)
1014         {
1015                 printf("Could not create JSON object: alarmInterfaceA\n");
1016                 return NULL;
1017         }
1018
1019         if (cJSON_AddStringToObject(faultFields, "eventSourceType", "O_RAN_COMPONENT") == NULL)
1020         {
1021                 printf("Could not create JSON object: eventSourceType\n");
1022                 return NULL;
1023         }
1024
1025         if (cJSON_AddStringToObject(faultFields, "specificProblem", specific_problem) == NULL)
1026         {
1027                 printf("Could not create JSON object: specificProblem\n");
1028                 return NULL;
1029         }
1030
1031         if (cJSON_AddStringToObject(faultFields, "eventSeverity", severity) == NULL)
1032         {
1033                 printf("Could not create JSON object: eventSeverity\n");
1034                 return NULL;
1035         }
1036
1037         if (cJSON_AddStringToObject(faultFields, "vfStatus", "Active") == NULL)
1038         {
1039                 printf("Could not create JSON object: vfStatus\n");
1040                 return NULL;
1041         }
1042
1043         cJSON *alarmAdditionalInformation = cJSON_CreateObject();
1044         if (alarmAdditionalInformation == NULL)
1045         {
1046                 printf("Could not create JSON object: alarmAdditionalInformation\n");
1047                 return NULL;
1048         }
1049         cJSON_AddItemToObject(faultFields, "alarmAdditionalInformation", alarmAdditionalInformation);
1050
1051         if (cJSON_AddStringToObject(alarmAdditionalInformation, "eventTime", date_time) == NULL)
1052         {
1053                 printf("Could not create JSON object: eventTime\n");
1054                 return NULL;
1055         }
1056
1057         if (cJSON_AddStringToObject(alarmAdditionalInformation, "equipType", "O-RAN-sim") == NULL)
1058         {
1059                 printf("Could not create JSON object: equipType\n");
1060                 return NULL;
1061         }
1062
1063         if (cJSON_AddStringToObject(alarmAdditionalInformation, "vendor", "Melacon") == NULL)
1064         {
1065                 printf("Could not create JSON object: vendor\n");
1066                 return NULL;
1067         }
1068
1069         if (cJSON_AddStringToObject(alarmAdditionalInformation, "model", "Simulated Device") == NULL)
1070         {
1071                 printf("Could not create JSON object: model\n");
1072                 return NULL;
1073         }
1074
1075         return faultFields;
1076 }