c41e432a28dc239acbcbf4369b63ee6dc87aeba6
[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         long int useconds = getMicrosecondsSinceEpoch;
196
197         cJSON *commonEventHeader = cJSON_CreateObject();
198         if (commonEventHeader == NULL)
199         {
200                 printf("Could not create JSON object: commonEventHeader\n");
201                 return NULL;
202         }
203
204         if (cJSON_AddStringToObject(commonEventHeader, "domain", domain) == NULL)
205         {
206                 printf("Could not create JSON object: domain\n");
207                 return NULL;
208         }
209
210         char eventId[200];
211         sprintf(eventId, "%s_%s", source_name, dateAndTime);
212
213         if (cJSON_AddStringToObject(commonEventHeader, "eventId", eventId) == NULL)
214         {
215                 printf("Could not create JSON object: eventId\n");
216                 return NULL;
217         }
218
219         char event_name[200];
220         sprintf(event_name, "%s_%s", domain, event_type);
221
222         if (cJSON_AddStringToObject(commonEventHeader, "eventName", event_name) == NULL)
223         {
224                 printf("Could not create JSON object: eventName\n");
225                 return NULL;
226         }
227
228         if (cJSON_AddStringToObject(commonEventHeader, "eventType", event_type) == NULL)
229         {
230                 printf("Could not create JSON object: eventType\n");
231                 return NULL;
232         }
233
234         if (cJSON_AddNumberToObject(commonEventHeader, "sequence", (double)(seq_id)) == NULL)
235         {
236                 printf("Could not create JSON object: sequence\n");
237                 return NULL;
238         }
239
240         if (cJSON_AddStringToObject(commonEventHeader, "priority", "Low") == NULL)
241         {
242                 printf("Could not create JSON object: priority\n");
243                 return NULL;
244         }
245
246         if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityId", "") == NULL)
247         {
248                 printf("Could not create JSON object: reportingEntityId\n");
249                 return NULL;
250         }
251
252         if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityName", source_name) == NULL)
253         {
254                 printf("Could not create JSON object: reportingEntityName\n");
255                 return NULL;
256         }
257
258         if (cJSON_AddStringToObject(commonEventHeader, "sourceId", "") == NULL)
259         {
260                 printf("Could not create JSON object: sourceId\n");
261                 return NULL;
262         }
263
264         if (cJSON_AddStringToObject(commonEventHeader, "sourceName", source_name) == NULL)
265         {
266                 printf("Could not create JSON object: sourceName\n");
267                 return NULL;
268         }
269
270         if (cJSON_AddNumberToObject(commonEventHeader, "startEpochMicrosec", (double)(useconds)) == NULL)
271         {
272                 printf("Could not create JSON object: startEpochMicrosec\n");
273                 return NULL;
274         }
275
276         if (cJSON_AddNumberToObject(commonEventHeader, "lastEpochMicrosec", (double)(useconds)) == NULL)
277         {
278                 printf("Could not create JSON object: lastEpochMicrosec\n");
279                 return NULL;
280         }
281
282         if (cJSON_AddStringToObject(commonEventHeader, "nfNamingCode", "sdn controller") == NULL)
283         {
284                 printf("Could not create JSON object: nfNamingCode\n");
285                 return NULL;
286         }
287
288         if (cJSON_AddStringToObject(commonEventHeader, "nfVendorName", "sdn") == NULL)
289         {
290                 printf("Could not create JSON object: nfVendorName\n");
291                 return NULL;
292         }
293
294         if (cJSON_AddStringToObject(commonEventHeader, "timeZoneOffset", "+00:00") == NULL)
295         {
296                 printf("Could not create JSON object: timeZoneOffset\n");
297                 return NULL;
298         }
299
300         if (cJSON_AddStringToObject(commonEventHeader, "version", "4.0.1") == NULL)
301         {
302                 printf("Could not create JSON object: version\n");
303                 return NULL;
304         }
305
306         if (cJSON_AddStringToObject(commonEventHeader, "vesEventListenerVersion", "7.0.1") == NULL)
307         {
308                 printf("Could not create JSON object: vesEventListenerVersion\n");
309                 return NULL;
310         }
311
312         return commonEventHeader;
313 }
314
315 cJSON*  vesCreateHeartbeatFields(int heartbeat_interval)
316 {
317         char dateAndTime[50];
318         getCurrentDateAndTime(dateAndTime);
319
320         cJSON *heartbeatFields = cJSON_CreateObject();
321         if (heartbeatFields == NULL)
322         {
323                 printf("Could not create JSON object: heartbeatFields\n");
324                 return NULL;
325         }
326
327         if (cJSON_AddStringToObject(heartbeatFields, "heartbeatFieldsVersion", "3.0") == NULL)
328         {
329                 printf("Could not create JSON object: heartbeatFieldsVersion\n");
330                 return NULL;
331         }
332
333         if (cJSON_AddNumberToObject(heartbeatFields, "heartbeatInterval", (double)(heartbeat_interval)) == NULL)
334         {
335                 printf("Could not create JSON object: heartbeatInterval\n");
336                 return NULL;
337         }
338
339         cJSON *additionalFields = cJSON_CreateObject();
340         if (additionalFields == NULL)
341         {
342                 printf("Could not create JSON object: additionalFields\n");
343                 return NULL;
344         }
345         cJSON_AddItemToObject(heartbeatFields, "additionalFields", additionalFields);
346
347         if (cJSON_AddStringToObject(additionalFields, "eventTime", dateAndTime) == NULL)
348         {
349                 printf("Could not create JSON object: eventTime\n");
350                 return NULL;
351         }
352
353         return heartbeatFields;
354 }
355
356 char*   readConfigFileInString(void)
357 {
358         char * buffer = 0;
359         long length;
360         char config_file[200];
361         sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
362         FILE * f = fopen (config_file, "rb");
363
364         if (f)
365         {
366           fseek (f, 0, SEEK_END);
367           length = ftell (f);
368           fseek (f, 0, SEEK_SET);
369           buffer = malloc (length + 1);
370           if (buffer)
371           {
372             fread (buffer, 1, length, f);
373           }
374           fclose (f);
375           buffer[length] = '\0';
376         }
377
378         if (buffer)
379         {
380           return buffer;
381         }
382
383         return NULL;
384 }
385
386 void    writeConfigFile(char *config)
387 {
388         char * buffer = 0;
389         long length;
390         char config_file[200];
391         sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
392         FILE * f = fopen (config_file, "w");
393
394         if (f)
395         {
396                 fputs(config, f);
397                 fclose(f);
398         }
399         else
400         {
401                 printf("Could not write configuration file");
402         }
403 }
404
405 int     getFaultNotificationDelayPeriodFromConfigJson(void)
406 {
407         char *stringConfig = readConfigFileInString();
408         int notificationDelay = 0;
409
410         if (stringConfig == NULL)
411         {
412                 printf("Could not read JSON configuration file in string.");
413                 return 0;
414         }
415
416         cJSON *jsonConfig = cJSON_Parse(stringConfig);
417         if (jsonConfig == NULL)
418         {
419                 free(stringConfig);
420                 const char *error_ptr = cJSON_GetErrorPtr();
421                 if (error_ptr != NULL)
422                 {
423                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
424                 }
425                 return SR_ERR_OPERATION_FAILED;
426         }
427         //we don't need the string anymore
428         free(stringConfig);
429
430         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
431         if (!cJSON_IsObject(notifConfig))
432         {
433                 printf("Configuration JSON is not as expected: notification-config is not an object");
434                 free(jsonConfig);
435                 return SR_ERR_OPERATION_FAILED;
436         }
437
438         cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
439         if (!cJSON_IsNumber(faultNotifDelay))
440         {
441                 printf("Configuration JSON is not as expected: fault-notification-delay-period is not a number");
442                 free(jsonConfig);
443                 return SR_ERR_OPERATION_FAILED;
444         }
445
446         notificationDelay = (int)(faultNotifDelay->valuedouble);
447
448         free(jsonConfig);
449
450         return notificationDelay;
451 }
452
453 int     getVesHeartbeatPeriodFromConfigJson(void)
454 {
455         char *stringConfig = readConfigFileInString();
456         int vesHeartbeat = 0;
457
458         if (stringConfig == NULL)
459         {
460                 printf("Could not read JSON configuration file in string.");
461                 return 0;
462         }
463
464         cJSON *jsonConfig = cJSON_Parse(stringConfig);
465         if (jsonConfig == NULL)
466         {
467                 free(stringConfig);
468                 const char *error_ptr = cJSON_GetErrorPtr();
469                 if (error_ptr != NULL)
470                 {
471                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
472                 }
473                 return SR_ERR_OPERATION_FAILED;
474         }
475         //we don't need the string anymore
476         free(stringConfig);
477
478         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
479         if (!cJSON_IsObject(notifConfig))
480         {
481                 printf("Configuration JSON is not as expected: notification-config is not an object");
482                 free(jsonConfig);
483                 return SR_ERR_OPERATION_FAILED;
484         }
485
486         cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
487         if (!cJSON_IsNumber(vesHeartbeatPeriod))
488         {
489                 printf("Configuration JSON is not as expected: ves-heartbeat-period is not a number");
490                 free(jsonConfig);
491                 return SR_ERR_OPERATION_FAILED;
492         }
493
494         vesHeartbeat = (int)(vesHeartbeatPeriod->valuedouble);
495
496         free(jsonConfig);
497
498         return vesHeartbeat;
499 }
500
501
502 /*
503  * Dynamically allocated memory;
504  * Caller needs to free the memory after it uses the value.
505  *
506 */
507 char*   getVesAuthMethodFromConfigJson(void)
508 {
509         char *stringConfig = readConfigFileInString();
510
511         if (stringConfig == NULL)
512         {
513                 printf("Could not read JSON configuration file in string.");
514                 return 0;
515         }
516
517         cJSON *jsonConfig = cJSON_Parse(stringConfig);
518         if (jsonConfig == NULL)
519         {
520                 free(stringConfig);
521                 const char *error_ptr = cJSON_GetErrorPtr();
522                 if (error_ptr != NULL)
523                 {
524                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
525                 }
526                 return SR_ERR_OPERATION_FAILED;
527         }
528         //we don't need the string anymore
529         free(stringConfig);
530
531         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
532         if (!cJSON_IsObject(vesDetails))
533         {
534                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
535                 free(jsonConfig);
536                 return SR_ERR_OPERATION_FAILED;
537         }
538
539         cJSON *vesAuthMethod = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-auth-method");
540         if (!cJSON_IsString(vesAuthMethod))
541         {
542                 printf("Configuration JSON is not as expected: ves-endpoint-auth-method is not an object");
543                 free(jsonConfig);
544                 return SR_ERR_OPERATION_FAILED;
545         }
546
547         char *auth_method_string = strdup(cJSON_GetStringValue(vesAuthMethod));
548
549         free(jsonConfig);
550
551         return auth_method_string;
552 }
553
554 /*
555  * Dynamically allocated memory;
556  * Caller needs to free the memory after it uses the value.
557  *
558 */
559 char*   getVesIpFromConfigJson(void)
560 {
561         char *stringConfig = readConfigFileInString();
562
563         if (stringConfig == NULL)
564         {
565                 printf("Could not read JSON configuration file in string.");
566                 return 0;
567         }
568
569         cJSON *jsonConfig = cJSON_Parse(stringConfig);
570         if (jsonConfig == NULL)
571         {
572                 free(stringConfig);
573                 const char *error_ptr = cJSON_GetErrorPtr();
574                 if (error_ptr != NULL)
575                 {
576                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
577                 }
578                 return SR_ERR_OPERATION_FAILED;
579         }
580         //we don't need the string anymore
581         free(stringConfig);
582
583         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
584         if (!cJSON_IsObject(vesDetails))
585         {
586                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
587                 free(jsonConfig);
588                 return SR_ERR_OPERATION_FAILED;
589         }
590
591         cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
592         if (!cJSON_IsString(vesIp))
593         {
594                 printf("Configuration JSON is not as expected: ves-endpoint-ip is not an object");
595                 free(jsonConfig);
596                 return SR_ERR_OPERATION_FAILED;
597         }
598
599         char *ves_ip = strdup(cJSON_GetStringValue(vesIp));
600
601         free(jsonConfig);
602
603         return ves_ip;
604 }
605
606 int     getVesPortFromConfigJson(void)
607 {
608         char *stringConfig = readConfigFileInString();
609
610         if (stringConfig == NULL)
611         {
612                 printf("Could not read JSON configuration file in string.");
613                 return 0;
614         }
615
616         cJSON *jsonConfig = cJSON_Parse(stringConfig);
617         if (jsonConfig == NULL)
618         {
619                 free(stringConfig);
620                 const char *error_ptr = cJSON_GetErrorPtr();
621                 if (error_ptr != NULL)
622                 {
623                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
624                 }
625                 return SR_ERR_OPERATION_FAILED;
626         }
627         //we don't need the string anymore
628         free(stringConfig);
629
630         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
631         if (!cJSON_IsObject(vesDetails))
632         {
633                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
634                 free(jsonConfig);
635                 return SR_ERR_OPERATION_FAILED;
636         }
637
638         cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
639         if (!cJSON_IsNumber(vesPort))
640         {
641                 printf("Configuration JSON is not as expected: ves-endpoint-port is not an object");
642                 free(jsonConfig);
643                 return SR_ERR_OPERATION_FAILED;
644         }
645
646         int port = (int)(vesPort->valuedouble);
647
648         free(jsonConfig);
649
650         return port;
651 }
652
653 int     getVesRegistrationFromConfigJson(void)
654 {
655         char *stringConfig = readConfigFileInString();
656
657         if (stringConfig == NULL)
658         {
659                 printf("Could not read JSON configuration file in string.");
660                 return 0;
661         }
662
663         cJSON *jsonConfig = cJSON_Parse(stringConfig);
664         if (jsonConfig == NULL)
665         {
666                 free(stringConfig);
667                 const char *error_ptr = cJSON_GetErrorPtr();
668                 if (error_ptr != NULL)
669                 {
670                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
671                 }
672                 return SR_ERR_OPERATION_FAILED;
673         }
674         //we don't need the string anymore
675         free(stringConfig);
676
677         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
678         if (!cJSON_IsObject(vesDetails))
679         {
680                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
681                 free(jsonConfig);
682                 return SR_ERR_OPERATION_FAILED;
683         }
684
685         cJSON *vesReg = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
686         if (!cJSON_IsBool(vesReg))
687         {
688                 printf("Configuration JSON is not as expected: ves-registration is not an object");
689                 free(jsonConfig);
690                 return SR_ERR_OPERATION_FAILED;
691         }
692
693         int is_ves_reg = (cJSON_IsTrue(vesReg)) ? TRUE : FALSE;
694
695         free(jsonConfig);
696
697         return is_ves_reg;
698 }
699
700 cJSON*  vesCreatePnfRegistrationFields(int port, bool is_tls)
701 {
702         cJSON *pnfRegistrationFields = cJSON_CreateObject();
703         if (pnfRegistrationFields == NULL)
704         {
705                 printf("Could not create JSON object: pnfRegistrationFields\n");
706                 return NULL;
707         }
708
709         if (cJSON_AddStringToObject(pnfRegistrationFields, "pnfRegistrationFieldsVersion", "2.0") == NULL)
710         {
711                 printf("Could not create JSON object: pnfRegistrationFieldsVersion\n");
712                 return NULL;
713         }
714
715         if (cJSON_AddStringToObject(pnfRegistrationFields, "lastServiceDate", "2019-08-16") == NULL)
716         {
717                 printf("Could not create JSON object: lastServiceDate\n");
718                 return NULL;
719         }
720
721         char mac_addr[40];
722         generateRandomMacAddress(mac_addr);
723
724         if (cJSON_AddStringToObject(pnfRegistrationFields, "macAddress", mac_addr) == NULL)
725         {
726                 printf("Could not create JSON object: macAddress\n");
727                 return NULL;
728         }
729
730         if (cJSON_AddStringToObject(pnfRegistrationFields, "manufactureDate", "2019-08-16") == NULL)
731         {
732                 printf("Could not create JSON object: manufactureDate\n");
733                 return NULL;
734         }
735
736         if (cJSON_AddStringToObject(pnfRegistrationFields, "modelNumber", "Simulated Device Melacon") == NULL)
737         {
738                 printf("Could not create JSON object: manufactureDate\n");
739                 return NULL;
740         }
741
742         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV4IpAddress", getenv("NTS_IP")) == NULL)
743         {
744                 printf("Could not create JSON object: oamV4IpAddress\n");
745                 return NULL;
746         }
747
748         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV6IpAddress", "0:0:0:0:0:ffff:a0a:011") == NULL)
749         {
750                 printf("Could not create JSON object: oamV6IpAddress\n");
751                 return NULL;
752         }
753
754         char serial_number[100];
755         sprintf(serial_number, "%s-%s-%d-Simulated Device Melacon", getenv("HOSTNAME"), getenv("NTS_IP"), port);
756
757         if (cJSON_AddStringToObject(pnfRegistrationFields, "serialNumber", serial_number) == NULL)
758         {
759                 printf("Could not create JSON object: serialNumber\n");
760                 return NULL;
761         }
762
763         if (cJSON_AddStringToObject(pnfRegistrationFields, "softwareVersion", "2.3.5") == NULL)
764         {
765                 printf("Could not create JSON object: softwareVersion\n");
766                 return NULL;
767         }
768
769         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitFamily", "Simulated Device") == NULL)
770         {
771                 printf("Could not create JSON object: unitFamily\n");
772                 return NULL;
773         }
774
775         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitType", "O-RAN-sim") == NULL)
776         {
777                 printf("Could not create JSON object: unitType\n");
778                 return NULL;
779         }
780
781         if (cJSON_AddStringToObject(pnfRegistrationFields, "vendorName", "Melacon") == NULL)
782         {
783                 printf("Could not create JSON object: vendorName\n");
784                 return NULL;
785         }
786
787         cJSON *additionalFields = cJSON_CreateObject();
788         if (additionalFields == NULL)
789         {
790                 printf("Could not create JSON object: additionalFields\n");
791                 return NULL;
792         }
793         cJSON_AddItemToObject(pnfRegistrationFields, "additionalFields", additionalFields);
794
795         char portString[10];
796         sprintf(portString, "%d", port);
797
798         if (cJSON_AddStringToObject(additionalFields, "oamPort", portString) == NULL)
799         {
800                 printf("Could not create JSON object: oamPort\n");
801                 return NULL;
802         }
803
804         if (is_tls)
805         {
806                 //TLS specific configuration
807                 if (cJSON_AddStringToObject(additionalFields, "protocol", "TLS") == NULL)
808                 {
809                         printf("Could not create JSON object: protocol\n");
810                         return NULL;
811                 }
812
813                 //TODO here we have the username from the docker container hardcoded: netconf
814                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
815                 {
816                         printf("Could not create JSON object: username\n");
817                         return NULL;
818                 }
819
820                 if (cJSON_AddStringToObject(additionalFields, "keyId", "device-key") == NULL)
821                 {
822                         printf("Could not create JSON object: keyId\n");
823                         return NULL;
824                 }
825         }
826         else
827         {
828                 //SSH specific configuration
829                 if (cJSON_AddStringToObject(additionalFields, "protocol", "SSH") == NULL)
830                 {
831                         printf("Could not create JSON object: protocol\n");
832                         return NULL;
833                 }
834
835                 //TODO here we have the username from the docker container hardcoded: netconf
836                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
837                 {
838                         printf("Could not create JSON object: username\n");
839                         return NULL;
840                 }
841
842                 //TODO here we have the password from the docker container hardcoded: netconf
843                 if (cJSON_AddStringToObject(additionalFields, "password", "netconf") == NULL)
844                 {
845                         printf("Could not create JSON object: password\n");
846                         return NULL;
847                 }
848         }
849
850         if (cJSON_AddStringToObject(additionalFields, "reconnectOnChangedSchema", "false") == NULL)
851         {
852                 printf("Could not create JSON object: reconnectOnChangedSchema\n");
853                 return NULL;
854         }
855
856         if (cJSON_AddStringToObject(additionalFields, "sleep-factor", "1.5") == NULL)
857         {
858                 printf("Could not create JSON object: sleep-factor\n");
859                 return NULL;
860         }
861
862         if (cJSON_AddStringToObject(additionalFields, "tcpOnly", "false") == NULL)
863         {
864                 printf("Could not create JSON object: tcpOnly\n");
865                 return NULL;
866         }
867
868         if (cJSON_AddStringToObject(additionalFields, "connectionTimeout", "20000") == NULL)
869         {
870                 printf("Could not create JSON object: connectionTimeout\n");
871                 return NULL;
872         }
873
874         if (cJSON_AddStringToObject(additionalFields, "maxConnectionAttempts", "100") == NULL)
875         {
876                 printf("Could not create JSON object: maxConnectionAttempts\n");
877                 return NULL;
878         }
879
880         if (cJSON_AddStringToObject(additionalFields, "betweenAttemptsTimeout", "2000") == NULL)
881         {
882                 printf("Could not create JSON object: betweenAttemptsTimeout\n");
883                 return NULL;
884         }
885
886         if (cJSON_AddStringToObject(additionalFields, "keepaliveDelay", "120") == NULL)
887         {
888                 printf("Could not create JSON object: keepaliveDelay\n");
889                 return NULL;
890         }
891
892         return pnfRegistrationFields;
893 }
894
895 int     getNetconfAvailableFromConfigJson(void)
896 {
897         char *stringConfig = readConfigFileInString();
898
899         if (stringConfig == NULL)
900         {
901                 printf("Could not read JSON configuration file in string.");
902                 return 0;
903         }
904
905         cJSON *jsonConfig = cJSON_Parse(stringConfig);
906         if (jsonConfig == NULL)
907         {
908                 free(stringConfig);
909                 const char *error_ptr = cJSON_GetErrorPtr();
910                 if (error_ptr != NULL)
911                 {
912                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
913                 }
914                 return SR_ERR_OPERATION_FAILED;
915         }
916         //we don't need the string anymore
917         free(stringConfig);
918
919         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
920         if (!cJSON_IsObject(notifDetails))
921         {
922                 printf("Configuration JSON is not as expected: notification-config is not an object");
923                 free(jsonConfig);
924                 return SR_ERR_OPERATION_FAILED;
925         }
926
927         cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-netconf-available");
928         if (!cJSON_IsBool(isNetconfAvailable))
929         {
930                 printf("Configuration JSON is not as expected: is-netconf-available is not an object");
931                 free(jsonConfig);
932                 return SR_ERR_OPERATION_FAILED;
933         }
934
935         int is_netconf_available = (cJSON_IsTrue(isNetconfAvailable)) ? TRUE : FALSE;
936
937         free(jsonConfig);
938
939         return is_netconf_available;
940 }
941
942 int     getVesAvailableFromConfigJson(void)
943 {
944         char *stringConfig = readConfigFileInString();
945
946         if (stringConfig == NULL)
947         {
948                 printf("Could not read JSON configuration file in string.");
949                 return 0;
950         }
951
952         cJSON *jsonConfig = cJSON_Parse(stringConfig);
953         if (jsonConfig == NULL)
954         {
955                 free(stringConfig);
956                 const char *error_ptr = cJSON_GetErrorPtr();
957                 if (error_ptr != NULL)
958                 {
959                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
960                 }
961                 return SR_ERR_OPERATION_FAILED;
962         }
963         //we don't need the string anymore
964         free(stringConfig);
965
966         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
967         if (!cJSON_IsObject(notifDetails))
968         {
969                 printf("Configuration JSON is not as expected: notification-config is not an object");
970                 free(jsonConfig);
971                 return SR_ERR_OPERATION_FAILED;
972         }
973
974         cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-ves-available");
975         if (!cJSON_IsBool(isVesAvailable))
976         {
977                 printf("Configuration JSON is not as expected: is-ves-available is not an object");
978                 free(jsonConfig);
979                 return SR_ERR_OPERATION_FAILED;
980         }
981
982         int is_netconf_available = (cJSON_IsTrue(isVesAvailable)) ? TRUE : FALSE;
983
984         free(jsonConfig);
985
986         return is_netconf_available;
987 }
988
989 cJSON*  vesCreateFaultFields(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem)
990 {
991         cJSON *faultFields = cJSON_CreateObject();
992         if (faultFields == NULL)
993         {
994                 printf("Could not create JSON object: faultFields\n");
995                 return NULL;
996         }
997
998         if (cJSON_AddStringToObject(faultFields, "faultFieldsVersion", "4.0") == NULL)
999         {
1000                 printf("Could not create JSON object: faultFieldsVersion\n");
1001                 return NULL;
1002         }
1003
1004         if (cJSON_AddStringToObject(faultFields, "alarmCondition", alarm_condition) == NULL)
1005         {
1006                 printf("Could not create JSON object: alarmCondition\n");
1007                 return NULL;
1008         }
1009
1010         if (cJSON_AddStringToObject(faultFields, "alarmInterfaceA", alarm_object) == NULL)
1011         {
1012                 printf("Could not create JSON object: alarmInterfaceA\n");
1013                 return NULL;
1014         }
1015
1016         if (cJSON_AddStringToObject(faultFields, "eventSourceType", "O_RAN_COMPONENT") == NULL)
1017         {
1018                 printf("Could not create JSON object: eventSourceType\n");
1019                 return NULL;
1020         }
1021
1022         if (cJSON_AddStringToObject(faultFields, "specificProblem", specific_problem) == NULL)
1023         {
1024                 printf("Could not create JSON object: specificProblem\n");
1025                 return NULL;
1026         }
1027
1028         if (cJSON_AddStringToObject(faultFields, "eventSeverity", severity) == NULL)
1029         {
1030                 printf("Could not create JSON object: eventSeverity\n");
1031                 return NULL;
1032         }
1033
1034         if (cJSON_AddStringToObject(faultFields, "vfStatus", "Active") == NULL)
1035         {
1036                 printf("Could not create JSON object: vfStatus\n");
1037                 return NULL;
1038         }
1039
1040         cJSON *alarmAdditionalInformation = cJSON_CreateObject();
1041         if (alarmAdditionalInformation == NULL)
1042         {
1043                 printf("Could not create JSON object: alarmAdditionalInformation\n");
1044                 return NULL;
1045         }
1046         cJSON_AddItemToObject(faultFields, "alarmAdditionalInformation", alarmAdditionalInformation);
1047
1048         if (cJSON_AddStringToObject(alarmAdditionalInformation, "eventTime", date_time) == NULL)
1049         {
1050                 printf("Could not create JSON object: eventTime\n");
1051                 return NULL;
1052         }
1053
1054         if (cJSON_AddStringToObject(alarmAdditionalInformation, "equipType", "O-RAN-sim") == NULL)
1055         {
1056                 printf("Could not create JSON object: equipType\n");
1057                 return NULL;
1058         }
1059
1060         if (cJSON_AddStringToObject(alarmAdditionalInformation, "vendor", "Melacon") == NULL)
1061         {
1062                 printf("Could not create JSON object: vendor\n");
1063                 return NULL;
1064         }
1065
1066         if (cJSON_AddStringToObject(alarmAdditionalInformation, "model", "Simulated Device") == NULL)
1067         {
1068                 printf("Could not create JSON object: model\n");
1069                 return NULL;
1070         }
1071
1072         return faultFields;
1073 }