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