217675be4625e8f78bfb612642d445585cc30aee
[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 #include <string.h>
25
26 void set_curl_common_info_ves(CURL *curl)
27 {
28         struct curl_slist *chunk = NULL;
29         chunk = curl_slist_append(chunk, "Content-Type: application/json");
30         chunk = curl_slist_append(chunk, "Accept: application/json");
31
32     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
33
34     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
35     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); //seconds timeout for an operation
36
37     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
38 }
39
40 void getCurrentDateAndTime(char *date_and_time)
41 {
42         time_t t = time(NULL);
43         struct tm tm = *localtime(&t);
44         struct timeval tv;
45         int millisec;
46
47         gettimeofday(&tv, NULL);
48         millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
49         if (millisec>=1000)
50         { // Allow for rounding up to nearest second
51                 millisec -=1000;
52                 tv.tv_sec++;
53                 millisec /= 100;
54         }
55         sprintf(date_and_time, "%04d-%02d-%02dT%02d:%02d:%02d.%01dZ",
56         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
57         tm.tm_hour, tm.tm_min, tm.tm_sec, millisec/100);
58
59         return;
60 }
61
62 void    generateRandomMacAddress(char *mac_address)
63 {
64         long rand1, rand2, rand3, rand4, rand5, rand6;
65         rand1 = random_at_most(255);
66         rand2 = random_at_most(255);
67         rand3 = random_at_most(255);
68         rand4 = random_at_most(255);
69         rand5 = random_at_most(255);
70         rand6 = random_at_most(255);
71
72         sprintf(mac_address, "%02X:%02X:%02X:%02X:%02X:%02X", rand1, rand2, rand3, rand4, rand5, rand6);
73
74         return;
75 }
76
77 long random_at_most(long max) 
78 {
79     unsigned long
80         // max <= RAND_MAX < ULONG_MAX, so this is okay.
81         num_bins = (unsigned long) max + 1,
82         num_rand = (unsigned long) RAND_MAX + 1,
83         bin_size = num_rand / num_bins,
84         defect   = num_rand % num_bins;
85
86     unsigned int seed;
87     FILE* urandom = fopen("/dev/urandom", "r");
88     fread(&seed, sizeof(int), 1, urandom);
89     fclose(urandom);
90     srandom(seed);
91
92     long x;
93     do 
94     {
95         x = random();
96     }
97     // This is carefully written not to overflow
98     while (num_rand - defect <= (unsigned long)x);
99
100     // Truncated division is intentional
101     return x/bin_size;
102 }
103
104 int getSecondsFromLastQuarterInterval(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_15_min_ago = tm;
110
111         //round to the last quarter hour
112         tm_15_min_ago.tm_min -= (tm_15_min_ago.tm_min % 15);
113         tm_15_min_ago.tm_sec = 0;
114
115         t=mktime(&tm_15_min_ago);
116         t_past=mktime(&tm);
117
118         double seconds = difftime(t_past, t);
119
120         return (int)seconds;
121 }
122
123 int getSecondsFromLastDayInterval(void)
124 {
125         time_t t = time(NULL);
126         time_t t_past = time(NULL);
127         struct tm tm = *localtime(&t);
128         struct tm tm_day_ago = tm;
129
130         //round to the last quarter hour
131         tm_day_ago.tm_hour = 0;
132         tm_day_ago.tm_min = 0;
133         tm_day_ago.tm_sec = 0;
134
135         t=mktime(&tm_day_ago);
136         t_past=mktime(&tm);
137
138         double seconds = difftime(t_past, t);
139
140         return (int)seconds;
141 }
142
143 void getPreviousQuarterInterval(int number_of_intervals, char *date_and_time)
144 {
145         time_t t = time(NULL);
146         t -= 15 * 60 * number_of_intervals;
147         struct tm tm = *localtime(&t);
148
149         tm.tm_min -= (tm.tm_min % 15);
150         tm.tm_sec = 0;
151
152         sprintf(date_and_time, "%04d-%02d-%02dT%02d:%02d:%02d.0Z",
153         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
154         tm.tm_hour, tm.tm_min, tm.tm_sec);
155
156         return;
157 }
158
159 void getPreviousDayPmTimestamp(int number_of_intervals, char *date_and_time)
160 {
161         time_t t = time(NULL);
162         t -= 24 * 60 * 60 * number_of_intervals;
163         struct tm tm = *localtime(&t);
164
165         tm.tm_hour = 0;
166         tm.tm_min = 0;
167         tm.tm_sec = 0;
168
169         sprintf(date_and_time, "%04d-%02d-%02dT%02d:%02d:%02d.0Z",
170         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
171         tm.tm_hour, tm.tm_min, tm.tm_sec);
172
173         return;
174 }
175
176 long int getMicrosecondsSinceEpoch(void)
177 {
178         time_t t = time(NULL);
179         struct timeval tv;
180         long int useconds;
181
182         gettimeofday(&tv, NULL);
183         useconds = t*1000 + tv.tv_usec; //add the microseconds to the seconds
184
185         return useconds;
186 }
187
188 //TODO need to implement other authentication methods as well, not only no-auth
189 void prepare_ves_message_curl(CURL *curl)
190 {
191         curl_easy_reset(curl);
192         set_curl_common_info_ves(curl);
193
194         char *ves_ip = getVesIpFromConfigJson();
195         int ves_port = getVesPortFromConfigJson();
196
197         char url[100];
198         sprintf(url, "http://%s:%d/eventListener/v7", ves_ip, ves_port);
199         curl_easy_setopt(curl, CURLOPT_URL, url);
200
201         free(ves_ip);
202
203         return;
204 }
205
206 /*
207  * Dynamically allocated memory;
208  * Caller needs to free the memory after it uses the value.
209  *
210 */
211 cJSON*  vesCreateCommonEventHeader(char *domain, char *event_type, char *source_name, int seq_id)
212 {
213         char dateAndTime[50];
214         getCurrentDateAndTime(dateAndTime);
215
216         long useconds = getMicrosecondsSinceEpoch();
217
218         cJSON *commonEventHeader = cJSON_CreateObject();
219         if (commonEventHeader == NULL)
220         {
221                 printf("Could not create JSON object: commonEventHeader\n");
222                 return NULL;
223         }
224
225         if (cJSON_AddStringToObject(commonEventHeader, "domain", domain) == NULL)
226         {
227                 printf("Could not create JSON object: domain\n");
228                 cJSON_Delete(commonEventHeader);
229                 return NULL;
230         }
231
232         char eventId[200];
233         sprintf(eventId, "%s_%s", source_name, dateAndTime);
234
235         if (cJSON_AddStringToObject(commonEventHeader, "eventId", eventId) == NULL)
236         {
237                 printf("Could not create JSON object: eventId\n");
238                 cJSON_Delete(commonEventHeader);
239                 return NULL;
240         }
241
242         char event_name[200];
243         sprintf(event_name, "%s_%s", domain, event_type);
244
245         if (cJSON_AddStringToObject(commonEventHeader, "eventName", event_name) == NULL)
246         {
247                 printf("Could not create JSON object: eventName\n");
248                 cJSON_Delete(commonEventHeader);
249                 return NULL;
250         }
251
252         if (cJSON_AddStringToObject(commonEventHeader, "eventType", event_type) == NULL)
253         {
254                 printf("Could not create JSON object: eventType\n");
255                 cJSON_Delete(commonEventHeader);
256                 return NULL;
257         }
258
259         if (cJSON_AddNumberToObject(commonEventHeader, "sequence", (double)(seq_id)) == NULL)
260         {
261                 printf("Could not create JSON object: sequence\n");
262                 cJSON_Delete(commonEventHeader);
263                 return NULL;
264         }
265
266         if (cJSON_AddStringToObject(commonEventHeader, "priority", "Low") == NULL)
267         {
268                 printf("Could not create JSON object: priority\n");
269                 cJSON_Delete(commonEventHeader);
270                 return NULL;
271         }
272
273         if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityId", "") == NULL)
274         {
275                 printf("Could not create JSON object: reportingEntityId\n");
276                 cJSON_Delete(commonEventHeader);
277                 return NULL;
278         }
279
280         if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityName", source_name) == NULL)
281         {
282                 printf("Could not create JSON object: reportingEntityName\n");
283                 cJSON_Delete(commonEventHeader);
284                 return NULL;
285         }
286
287         if (cJSON_AddStringToObject(commonEventHeader, "sourceId", "") == NULL)
288         {
289                 printf("Could not create JSON object: sourceId\n");
290                 cJSON_Delete(commonEventHeader);
291                 return NULL;
292         }
293
294         if (cJSON_AddStringToObject(commonEventHeader, "sourceName", source_name) == NULL)
295         {
296                 printf("Could not create JSON object: sourceName\n");
297                 cJSON_Delete(commonEventHeader);
298                 return NULL;
299         }
300
301         if (cJSON_AddNumberToObject(commonEventHeader, "startEpochMicrosec", (double)(useconds)) == NULL)
302         {
303                 printf("Could not create JSON object: startEpochMicrosec\n");
304                 cJSON_Delete(commonEventHeader);
305                 return NULL;
306         }
307
308         if (cJSON_AddNumberToObject(commonEventHeader, "lastEpochMicrosec", (double)(useconds)) == NULL)
309         {
310                 printf("Could not create JSON object: lastEpochMicrosec\n");
311                 cJSON_Delete(commonEventHeader);
312                 return NULL;
313         }
314
315         if (cJSON_AddStringToObject(commonEventHeader, "nfNamingCode", "sdn controller") == NULL)
316         {
317                 printf("Could not create JSON object: nfNamingCode\n");
318                 cJSON_Delete(commonEventHeader);
319                 return NULL;
320         }
321
322         if (cJSON_AddStringToObject(commonEventHeader, "nfVendorName", "sdn") == NULL)
323         {
324                 printf("Could not create JSON object: nfVendorName\n");
325                 cJSON_Delete(commonEventHeader);
326                 return NULL;
327         }
328
329         if (cJSON_AddStringToObject(commonEventHeader, "timeZoneOffset", "+00:00") == NULL)
330         {
331                 printf("Could not create JSON object: timeZoneOffset\n");
332                 cJSON_Delete(commonEventHeader);
333                 return NULL;
334         }
335
336         if (cJSON_AddStringToObject(commonEventHeader, "version", "4.0.1") == NULL)
337         {
338                 printf("Could not create JSON object: version\n");
339                 cJSON_Delete(commonEventHeader);
340                 return NULL;
341         }
342
343         if (cJSON_AddStringToObject(commonEventHeader, "vesEventListenerVersion", "7.0.1") == NULL)
344         {
345                 printf("Could not create JSON object: vesEventListenerVersion\n");
346                 cJSON_Delete(commonEventHeader);
347                 return NULL;
348         }
349
350         return commonEventHeader;
351 }
352
353 /*
354  * Dynamically allocated memory;
355  * Caller needs to free the memory after it uses the value.
356  *
357 */
358 cJSON*  vesCreateHeartbeatFields(int heartbeat_interval)
359 {
360         char dateAndTime[50];
361         getCurrentDateAndTime(dateAndTime);
362
363         cJSON *heartbeatFields = cJSON_CreateObject();
364         if (heartbeatFields == NULL)
365         {
366                 printf("Could not create JSON object: heartbeatFields\n");
367                 return NULL;
368         }
369
370         if (cJSON_AddStringToObject(heartbeatFields, "heartbeatFieldsVersion", "3.0") == NULL)
371         {
372                 printf("Could not create JSON object: heartbeatFieldsVersion\n");
373                 cJSON_Delete(heartbeatFields);
374                 return NULL;
375         }
376
377         if (cJSON_AddNumberToObject(heartbeatFields, "heartbeatInterval", (double)(heartbeat_interval)) == NULL)
378         {
379                 printf("Could not create JSON object: heartbeatInterval\n");
380                 cJSON_Delete(heartbeatFields);
381                 return NULL;
382         }
383
384         cJSON *additionalFields = cJSON_CreateObject();
385         if (additionalFields == NULL)
386         {
387                 printf("Could not create JSON object: additionalFields\n");
388                 cJSON_Delete(heartbeatFields);
389                 return NULL;
390         }
391         cJSON_AddItemToObject(heartbeatFields, "additionalFields", additionalFields);
392
393         if (cJSON_AddStringToObject(additionalFields, "eventTime", dateAndTime) == NULL)
394         {
395                 printf("Could not create JSON object: eventTime\n");
396                 cJSON_Delete(heartbeatFields);
397                 return NULL;
398         }
399
400         return heartbeatFields;
401 }
402
403 /*
404  * Dynamically allocated memory;
405  * Caller needs to free the memory after it uses the value.
406  *
407 */
408 char*   readConfigFileInString(void)
409 {
410         char * buffer = 0;
411         long length;
412         char config_file[200];
413
414         //sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
415
416         // --> recommended fix, Karl Koch, Deutsche Telekom AG, 22. 5. 2020.
417         //     Path to config_file contains NULL when env variable is unset.
418         char *scripts_dir = getenv("SCRIPTS_DIR");
419         char *scripts_dir_default = "/opt/dev/ntsimulator/scripts";
420
421         if(NULL != scripts_dir)
422         {
423             sprintf(config_file, "%s/configuration.json", scripts_dir);
424         }
425         else
426         {
427             sprintf(config_file, "%s/configuration.json", scripts_dir_default);
428             printf("warning: opening config file in default path: <%s>\n",
429                    config_file);
430         }
431         // end of fix <--
432
433         FILE * f = fopen (config_file, "rb");
434
435         if (f)
436         {
437           fseek (f, 0, SEEK_END);
438           length = ftell (f);
439           fseek (f, 0, SEEK_SET);
440           buffer = malloc (length + 1);
441           if (buffer)
442           {
443             fread (buffer, 1, length, f);
444           }
445           fclose (f);
446           buffer[length] = '\0';
447         }
448
449         if (buffer)
450         {
451           return buffer;
452         }
453
454         return NULL;
455 }
456
457 void    writeConfigFile(char *config)
458 {
459         char config_file[200];
460
461         //sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
462
463         // --> recommended fix, Karl Koch, Deutsche Telekom AG, 22. 5. 2020.
464         //     Path to config_file contains NULL when env variable is unset.
465         char *scripts_dir = getenv("SCRIPTS_DIR");
466         char *scripts_dir_default = "/opt/dev/ntsimulator/scripts";
467
468         if(NULL != scripts_dir)
469         {
470             sprintf(config_file, "%s/configuration.json", scripts_dir);
471         }
472         else
473         {
474             sprintf(config_file, "%s/configuration.json", scripts_dir_default);
475             printf("warning: opening config file in default path: <%s>\n",
476                    config_file);
477         }
478         // end of fix <--
479
480         FILE * f = fopen (config_file, "w");
481
482         if (f)
483         {
484                 fputs(config, f);
485                 fclose(f);
486         }
487         else
488         {
489                 printf("Could not write configuration file");
490         }
491 }
492
493 int getFaultNotificationDelayPeriodFromConfigJson(int *period_array, int *count)
494 {
495         char *stringConfig = readConfigFileInString();
496
497         if (stringConfig == NULL)
498         {
499                 printf("Could not read JSON configuration file in string.");
500                 return 0;
501         }
502
503         cJSON *jsonConfig = cJSON_Parse(stringConfig);
504         if (jsonConfig == NULL)
505         {
506                 free(stringConfig);
507                 const char *error_ptr = cJSON_GetErrorPtr();
508                 if (error_ptr != NULL)
509                 {
510                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
511                 }
512                 return SR_ERR_OPERATION_FAILED;
513         }
514         //we don't need the string anymore
515         free(stringConfig);
516         stringConfig = NULL;
517
518         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
519         if (!cJSON_IsObject(notifConfig))
520         {
521                 printf("Configuration JSON is not as expected: notification-config is not an object");
522                 cJSON_Delete(jsonConfig);
523                 return SR_ERR_OPERATION_FAILED;
524         }
525
526         cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
527         if (!cJSON_IsArray(faultNotifDelay))
528         {
529                 printf("Configuration JSON is not as expected: fault-notification-delay-period is not an array.");
530                 cJSON_Delete(jsonConfig);
531                 return SR_ERR_OPERATION_FAILED;
532         }
533
534     cJSON *iterator = NULL;
535     *count = 0;
536     int i = 0;
537
538     cJSON_ArrayForEach(iterator, faultNotifDelay) 
539     {
540         if (cJSON_IsNumber(iterator)) 
541         {
542             period_array[i++] = iterator->valueint;
543         } 
544         else 
545         {
546             printf("Invalid number in array!");
547         }
548     }
549
550     *count = i;
551
552         cJSON_Delete(jsonConfig);
553
554         return SR_ERR_OK;
555 }
556
557 int     getVesHeartbeatPeriodFromConfigJson(void)
558 {
559         char *stringConfig = readConfigFileInString();
560         int vesHeartbeat = 0;
561
562         if (stringConfig == NULL)
563         {
564                 printf("Could not read JSON configuration file in string.");
565                 return 0;
566         }
567
568         cJSON *jsonConfig = cJSON_Parse(stringConfig);
569         if (jsonConfig == NULL)
570         {
571                 free(stringConfig);
572                 const char *error_ptr = cJSON_GetErrorPtr();
573                 if (error_ptr != NULL)
574                 {
575                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
576                 }
577                 return SR_ERR_OPERATION_FAILED;
578         }
579         //we don't need the string anymore
580         free(stringConfig);
581         stringConfig = NULL;
582
583         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
584         if (!cJSON_IsObject(notifConfig))
585         {
586                 printf("Configuration JSON is not as expected: notification-config is not an object");
587                 cJSON_Delete(jsonConfig);
588                 return SR_ERR_OPERATION_FAILED;
589         }
590
591         cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
592         if (!cJSON_IsNumber(vesHeartbeatPeriod))
593         {
594                 printf("Configuration JSON is not as expected: ves-heartbeat-period is not a number");
595                 cJSON_Delete(jsonConfig);
596                 return SR_ERR_OPERATION_FAILED;
597         }
598
599         vesHeartbeat = (int)(vesHeartbeatPeriod->valuedouble);
600
601         cJSON_Delete(jsonConfig);
602
603         return vesHeartbeat;
604 }
605
606
607 /*
608  * Dynamically allocated memory;
609  * Caller needs to free the memory after it uses the value.
610  *
611 */
612 char*   getVesAuthMethodFromConfigJson(void)
613 {
614         char *stringConfig = readConfigFileInString();
615
616         if (stringConfig == NULL)
617         {
618                 printf("Could not read JSON configuration file in string.");
619                 return 0;
620         }
621
622         cJSON *jsonConfig = cJSON_Parse(stringConfig);
623         if (jsonConfig == NULL)
624         {
625                 free(stringConfig);
626                 const char *error_ptr = cJSON_GetErrorPtr();
627                 if (error_ptr != NULL)
628                 {
629                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
630                 }
631                 return NULL;
632         }
633         //we don't need the string anymore
634         free(stringConfig);
635         stringConfig = NULL;
636
637         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
638         if (!cJSON_IsObject(vesDetails))
639         {
640                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
641                 cJSON_Delete(jsonConfig);
642                 return NULL;
643         }
644
645         cJSON *vesAuthMethod = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-auth-method");
646         if (!cJSON_IsString(vesAuthMethod))
647         {
648                 printf("Configuration JSON is not as expected: ves-endpoint-auth-method is not an object");
649                 cJSON_Delete(jsonConfig);
650                 return NULL;
651         }
652
653         char *auth_method_string = strdup(cJSON_GetStringValue(vesAuthMethod));
654
655         cJSON_Delete(jsonConfig);
656
657         return auth_method_string;
658 }
659
660 /*
661  * Dynamically allocated memory;
662  * Caller needs to free the memory after it uses the value.
663  *
664 */
665 char*   getVesIpFromConfigJson(void)
666 {
667         char *stringConfig = readConfigFileInString();
668
669         if (stringConfig == NULL)
670         {
671                 printf("Could not read JSON configuration file in string.");
672                 return 0;
673         }
674
675         cJSON *jsonConfig = cJSON_Parse(stringConfig);
676         if (jsonConfig == NULL)
677         {
678                 free(stringConfig);
679                 const char *error_ptr = cJSON_GetErrorPtr();
680                 if (error_ptr != NULL)
681                 {
682                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
683                 }
684                 return NULL;
685         }
686         //we don't need the string anymore
687         free(stringConfig);
688         stringConfig = NULL;
689
690         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
691         if (!cJSON_IsObject(vesDetails))
692         {
693                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
694                 cJSON_Delete(jsonConfig);
695                 return NULL;
696         }
697
698         cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
699         if (!cJSON_IsString(vesIp))
700         {
701                 printf("Configuration JSON is not as expected: ves-endpoint-ip is not an object");
702                 cJSON_Delete(jsonConfig);
703                 return NULL;
704         }
705
706         char *ves_ip = strdup(cJSON_GetStringValue(vesIp));
707
708         cJSON_Delete(jsonConfig);
709
710         return ves_ip;
711 }
712
713 int     getVesPortFromConfigJson(void)
714 {
715         char *stringConfig = readConfigFileInString();
716
717         if (stringConfig == NULL)
718         {
719                 printf("Could not read JSON configuration file in string.");
720                 return 0;
721         }
722
723         cJSON *jsonConfig = cJSON_Parse(stringConfig);
724         if (jsonConfig == NULL)
725         {
726                 free(stringConfig);
727                 const char *error_ptr = cJSON_GetErrorPtr();
728                 if (error_ptr != NULL)
729                 {
730                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
731                 }
732                 return SR_ERR_OPERATION_FAILED;
733         }
734         //we don't need the string anymore
735         free(stringConfig);
736         stringConfig = NULL;
737
738         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
739         if (!cJSON_IsObject(vesDetails))
740         {
741                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
742                 cJSON_Delete(jsonConfig);
743                 return SR_ERR_OPERATION_FAILED;
744         }
745
746         cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
747         if (!cJSON_IsNumber(vesPort))
748         {
749                 printf("Configuration JSON is not as expected: ves-endpoint-port is not an object");
750                 cJSON_Delete(jsonConfig);
751                 return SR_ERR_OPERATION_FAILED;
752         }
753
754         int port = (int)(vesPort->valuedouble);
755
756         cJSON_Delete(jsonConfig);
757
758         return port;
759 }
760
761 int     getVesRegistrationFromConfigJson(void)
762 {
763         char *stringConfig = readConfigFileInString();
764
765         if (stringConfig == NULL)
766         {
767                 printf("Could not read JSON configuration file in string.");
768                 return 0;
769         }
770
771         cJSON *jsonConfig = cJSON_Parse(stringConfig);
772         if (jsonConfig == NULL)
773         {
774                 free(stringConfig);
775                 const char *error_ptr = cJSON_GetErrorPtr();
776                 if (error_ptr != NULL)
777                 {
778                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
779                 }
780                 return SR_ERR_OPERATION_FAILED;
781         }
782         //we don't need the string anymore
783         free(stringConfig);
784         stringConfig = NULL;
785
786         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
787         if (!cJSON_IsObject(vesDetails))
788         {
789                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
790                 cJSON_Delete(jsonConfig);
791                 return SR_ERR_OPERATION_FAILED;
792         }
793
794         cJSON *vesReg = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
795         if (!cJSON_IsBool(vesReg))
796         {
797                 printf("Configuration JSON is not as expected: ves-registration is not an object");
798                 cJSON_Delete(jsonConfig);
799                 return SR_ERR_OPERATION_FAILED;
800         }
801
802         int is_ves_reg = (cJSON_IsTrue(vesReg)) ? TRUE : FALSE;
803
804         cJSON_Delete(jsonConfig);
805
806         return is_ves_reg;
807 }
808
809 /*
810  * Dynamically allocated memory;
811  * Caller needs to free the memory after it uses the value.
812  *
813 */
814 cJSON*  vesCreatePnfRegistrationFields(int port, bool is_tls)
815 {
816         cJSON *pnfRegistrationFields = cJSON_CreateObject();
817         if (pnfRegistrationFields == NULL)
818         {
819                 printf("Could not create JSON object: pnfRegistrationFields\n");
820                 return NULL;
821         }
822
823         if (cJSON_AddStringToObject(pnfRegistrationFields, "pnfRegistrationFieldsVersion", "2.0") == NULL)
824         {
825                 printf("Could not create JSON object: pnfRegistrationFieldsVersion\n");
826                 cJSON_Delete(pnfRegistrationFields);
827                 return NULL;
828         }
829
830         if (cJSON_AddStringToObject(pnfRegistrationFields, "lastServiceDate", "2019-08-16") == NULL)
831         {
832                 printf("Could not create JSON object: lastServiceDate\n");
833                 cJSON_Delete(pnfRegistrationFields);
834                 return NULL;
835         }
836
837         char mac_addr[40];
838         generateRandomMacAddress(mac_addr);
839
840         if (cJSON_AddStringToObject(pnfRegistrationFields, "macAddress", mac_addr) == NULL)
841         {
842                 printf("Could not create JSON object: macAddress\n");
843                 cJSON_Delete(pnfRegistrationFields);
844                 return NULL;
845         }
846
847         if (cJSON_AddStringToObject(pnfRegistrationFields, "manufactureDate", "2019-08-16") == NULL)
848         {
849                 printf("Could not create JSON object: manufactureDate\n");
850                 cJSON_Delete(pnfRegistrationFields);
851                 return NULL;
852         }
853
854         if (cJSON_AddStringToObject(pnfRegistrationFields, "modelNumber", "Simulated Device Melacon") == NULL)
855         {
856                 printf("Could not create JSON object: manufactureDate\n");
857                 cJSON_Delete(pnfRegistrationFields);
858                 return NULL;
859         }
860
861         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV4IpAddress", getenv("NTS_IP")) == NULL)
862         {
863                 printf("Could not create JSON object: oamV4IpAddress\n");
864                 cJSON_Delete(pnfRegistrationFields);
865                 return NULL;
866         }
867
868         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV6IpAddress", "0:0:0:0:0:ffff:a0a:011") == NULL)
869         {
870                 printf("Could not create JSON object: oamV6IpAddress\n");
871                 cJSON_Delete(pnfRegistrationFields);
872                 return NULL;
873         }
874
875         char serial_number[100];
876         sprintf(serial_number, "%s-%s-%d-Simulated Device Melacon", getenv("HOSTNAME"), getenv("NTS_IP"), port);
877
878         if (cJSON_AddStringToObject(pnfRegistrationFields, "serialNumber", serial_number) == NULL)
879         {
880                 printf("Could not create JSON object: serialNumber\n");
881                 cJSON_Delete(pnfRegistrationFields);
882                 return NULL;
883         }
884
885         if (cJSON_AddStringToObject(pnfRegistrationFields, "softwareVersion", "2.3.5") == NULL)
886         {
887                 printf("Could not create JSON object: softwareVersion\n");
888                 cJSON_Delete(pnfRegistrationFields);
889                 return NULL;
890         }
891
892         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitFamily", "Simulated Device") == NULL)
893         {
894                 printf("Could not create JSON object: unitFamily\n");
895                 cJSON_Delete(pnfRegistrationFields);
896                 return NULL;
897         }
898
899         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitType", "O-RAN-sim") == NULL)
900         {
901                 printf("Could not create JSON object: unitType\n");
902                 cJSON_Delete(pnfRegistrationFields);
903                 return NULL;
904         }
905
906         if (cJSON_AddStringToObject(pnfRegistrationFields, "vendorName", "Melacon") == NULL)
907         {
908                 printf("Could not create JSON object: vendorName\n");
909                 cJSON_Delete(pnfRegistrationFields);
910                 return NULL;
911         }
912
913         cJSON *additionalFields = cJSON_CreateObject();
914         if (additionalFields == NULL)
915         {
916                 printf("Could not create JSON object: additionalFields\n");
917                 cJSON_Delete(pnfRegistrationFields);
918                 return NULL;
919         }
920         cJSON_AddItemToObject(pnfRegistrationFields, "additionalFields", additionalFields);
921
922         char portString[10];
923         sprintf(portString, "%d", port);
924
925         if (cJSON_AddStringToObject(additionalFields, "oamPort", portString) == NULL)
926         {
927                 printf("Could not create JSON object: oamPort\n");
928                 cJSON_Delete(pnfRegistrationFields);
929                 return NULL;
930         }
931
932         if (is_tls)
933         {
934                 //TLS specific configuration
935                 if (cJSON_AddStringToObject(additionalFields, "protocol", "TLS") == NULL)
936                 {
937                         printf("Could not create JSON object: protocol\n");
938                         cJSON_Delete(pnfRegistrationFields);
939                         return NULL;
940                 }
941
942                 //TODO here we have the username from the docker container hardcoded: netconf
943                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
944                 {
945                         printf("Could not create JSON object: username\n");
946                         cJSON_Delete(pnfRegistrationFields);
947                         return NULL;
948                 }
949
950                 if (cJSON_AddStringToObject(additionalFields, "keyId", "device-key") == NULL)
951                 {
952                         printf("Could not create JSON object: keyId\n");
953                         cJSON_Delete(pnfRegistrationFields);
954                         return NULL;
955                 }
956         }
957         else
958         {
959                 //SSH specific configuration
960                 if (cJSON_AddStringToObject(additionalFields, "protocol", "SSH") == NULL)
961                 {
962                         printf("Could not create JSON object: protocol\n");
963                         cJSON_Delete(pnfRegistrationFields);
964                         return NULL;
965                 }
966
967                 //TODO here we have the username from the docker container hardcoded: netconf
968                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
969                 {
970                         printf("Could not create JSON object: username\n");
971                         cJSON_Delete(pnfRegistrationFields);
972                         return NULL;
973                 }
974
975                 //TODO here we have the password from the docker container hardcoded: netconf
976                 if (cJSON_AddStringToObject(additionalFields, "password", "netconf") == NULL)
977                 {
978                         printf("Could not create JSON object: password\n");
979                         cJSON_Delete(pnfRegistrationFields);
980                         return NULL;
981                 }
982         }
983
984         if (cJSON_AddStringToObject(additionalFields, "reconnectOnChangedSchema", "false") == NULL)
985         {
986                 printf("Could not create JSON object: reconnectOnChangedSchema\n");
987                 cJSON_Delete(pnfRegistrationFields);
988                 return NULL;
989         }
990
991         if (cJSON_AddStringToObject(additionalFields, "sleep-factor", "1.5") == NULL)
992         {
993                 printf("Could not create JSON object: sleep-factor\n");
994                 cJSON_Delete(pnfRegistrationFields);
995                 return NULL;
996         }
997
998         if (cJSON_AddStringToObject(additionalFields, "tcpOnly", "false") == NULL)
999         {
1000                 printf("Could not create JSON object: tcpOnly\n");
1001                 cJSON_Delete(pnfRegistrationFields);
1002                 return NULL;
1003         }
1004
1005         if (cJSON_AddStringToObject(additionalFields, "connectionTimeout", "20000") == NULL)
1006         {
1007                 printf("Could not create JSON object: connectionTimeout\n");
1008                 cJSON_Delete(pnfRegistrationFields);
1009                 return NULL;
1010         }
1011
1012         if (cJSON_AddStringToObject(additionalFields, "maxConnectionAttempts", "100") == NULL)
1013         {
1014                 printf("Could not create JSON object: maxConnectionAttempts\n");
1015                 cJSON_Delete(pnfRegistrationFields);
1016                 return NULL;
1017         }
1018
1019         if (cJSON_AddStringToObject(additionalFields, "betweenAttemptsTimeout", "2000") == NULL)
1020         {
1021                 printf("Could not create JSON object: betweenAttemptsTimeout\n");
1022                 cJSON_Delete(pnfRegistrationFields);
1023                 return NULL;
1024         }
1025
1026         if (cJSON_AddStringToObject(additionalFields, "keepaliveDelay", "120") == NULL)
1027         {
1028                 printf("Could not create JSON object: keepaliveDelay\n");
1029                 cJSON_Delete(pnfRegistrationFields);
1030                 return NULL;
1031         }
1032
1033         return pnfRegistrationFields;
1034 }
1035
1036 int     getNetconfAvailableFromConfigJson(void)
1037 {
1038         char *stringConfig = readConfigFileInString();
1039
1040         if (stringConfig == NULL)
1041         {
1042                 printf("Could not read JSON configuration file in string.");
1043                 return 0;
1044         }
1045
1046         cJSON *jsonConfig = cJSON_Parse(stringConfig);
1047         if (jsonConfig == NULL)
1048         {
1049                 free(stringConfig);
1050                 const char *error_ptr = cJSON_GetErrorPtr();
1051                 if (error_ptr != NULL)
1052                 {
1053                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1054                 }
1055                 return SR_ERR_OPERATION_FAILED;
1056         }
1057         //we don't need the string anymore
1058         free(stringConfig);
1059         stringConfig = NULL;
1060
1061         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1062         if (!cJSON_IsObject(notifDetails))
1063         {
1064                 printf("Configuration JSON is not as expected: notification-config is not an object");
1065                 cJSON_Delete(jsonConfig);
1066                 return SR_ERR_OPERATION_FAILED;
1067         }
1068
1069         cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-netconf-available");
1070         if (!cJSON_IsBool(isNetconfAvailable))
1071         {
1072                 printf("Configuration JSON is not as expected: is-netconf-available is not an object");
1073                 cJSON_Delete(jsonConfig);
1074                 return SR_ERR_OPERATION_FAILED;
1075         }
1076
1077         int is_netconf_available = (cJSON_IsTrue(isNetconfAvailable)) ? TRUE : FALSE;
1078
1079         cJSON_Delete(jsonConfig);
1080
1081         return is_netconf_available;
1082 }
1083
1084 int     getVesAvailableFromConfigJson(void)
1085 {
1086         char *stringConfig = readConfigFileInString();
1087
1088         if (stringConfig == NULL)
1089         {
1090                 printf("Could not read JSON configuration file in string.");
1091                 return 0;
1092         }
1093
1094         cJSON *jsonConfig = cJSON_Parse(stringConfig);
1095         if (jsonConfig == NULL)
1096         {
1097                 free(stringConfig);
1098                 const char *error_ptr = cJSON_GetErrorPtr();
1099                 if (error_ptr != NULL)
1100                 {
1101                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1102                 }
1103                 return SR_ERR_OPERATION_FAILED;
1104         }
1105         //we don't need the string anymore
1106         free(stringConfig);
1107         stringConfig = NULL;
1108
1109         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1110         if (!cJSON_IsObject(notifDetails))
1111         {
1112                 printf("Configuration JSON is not as expected: notification-config is not an object");
1113                 cJSON_Delete(jsonConfig);
1114                 return SR_ERR_OPERATION_FAILED;
1115         }
1116
1117         cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-ves-available");
1118         if (!cJSON_IsBool(isVesAvailable))
1119         {
1120                 printf("Configuration JSON is not as expected: is-ves-available is not an object");
1121                 cJSON_Delete(jsonConfig);
1122                 return SR_ERR_OPERATION_FAILED;
1123         }
1124
1125         int is_netconf_available = (cJSON_IsTrue(isVesAvailable)) ? TRUE : FALSE;
1126
1127         cJSON_Delete(jsonConfig);
1128
1129         return is_netconf_available;
1130 }
1131
1132 /*
1133  * Dynamically allocated memory;
1134  * Caller needs to free the memory after it uses the value.
1135  *
1136 */
1137 cJSON*  vesCreateFaultFields(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem)
1138 {
1139         cJSON *faultFields = cJSON_CreateObject();
1140         if (faultFields == NULL)
1141         {
1142                 printf("Could not create JSON object: faultFields\n");
1143                 return NULL;
1144         }
1145
1146         if (cJSON_AddStringToObject(faultFields, "faultFieldsVersion", "4.0") == NULL)
1147         {
1148                 printf("Could not create JSON object: faultFieldsVersion\n");
1149                 cJSON_Delete(faultFields);
1150                 return NULL;
1151         }
1152
1153         if (cJSON_AddStringToObject(faultFields, "alarmCondition", alarm_condition) == NULL)
1154         {
1155                 printf("Could not create JSON object: alarmCondition\n");
1156                 cJSON_Delete(faultFields);
1157                 return NULL;
1158         }
1159
1160         if (cJSON_AddStringToObject(faultFields, "alarmInterfaceA", alarm_object) == NULL)
1161         {
1162                 printf("Could not create JSON object: alarmInterfaceA\n");
1163                 cJSON_Delete(faultFields);
1164                 return NULL;
1165         }
1166
1167         if (cJSON_AddStringToObject(faultFields, "eventSourceType", "O_RAN_COMPONENT") == NULL)
1168         {
1169                 printf("Could not create JSON object: eventSourceType\n");
1170                 cJSON_Delete(faultFields);
1171                 return NULL;
1172         }
1173
1174         if (cJSON_AddStringToObject(faultFields, "specificProblem", specific_problem) == NULL)
1175         {
1176                 printf("Could not create JSON object: specificProblem\n");
1177                 cJSON_Delete(faultFields);
1178                 return NULL;
1179         }
1180
1181         if (cJSON_AddStringToObject(faultFields, "eventSeverity", severity) == NULL)
1182         {
1183                 printf("Could not create JSON object: eventSeverity\n");
1184                 cJSON_Delete(faultFields);
1185                 return NULL;
1186         }
1187
1188         if (cJSON_AddStringToObject(faultFields, "vfStatus", "Active") == NULL)
1189         {
1190                 printf("Could not create JSON object: vfStatus\n");
1191                 cJSON_Delete(faultFields);
1192                 return NULL;
1193         }
1194
1195         cJSON *alarmAdditionalInformation = cJSON_CreateObject();
1196         if (alarmAdditionalInformation == NULL)
1197         {
1198                 printf("Could not create JSON object: alarmAdditionalInformation\n");
1199                 cJSON_Delete(faultFields);
1200                 return NULL;
1201         }
1202         cJSON_AddItemToObject(faultFields, "alarmAdditionalInformation", alarmAdditionalInformation);
1203
1204         if (cJSON_AddStringToObject(alarmAdditionalInformation, "eventTime", date_time) == NULL)
1205         {
1206                 printf("Could not create JSON object: eventTime\n");
1207                 cJSON_Delete(faultFields);
1208                 return NULL;
1209         }
1210
1211         if (cJSON_AddStringToObject(alarmAdditionalInformation, "equipType", "O-RAN-sim") == NULL)
1212         {
1213                 printf("Could not create JSON object: equipType\n");
1214                 cJSON_Delete(faultFields);
1215                 return NULL;
1216         }
1217
1218         if (cJSON_AddStringToObject(alarmAdditionalInformation, "vendor", "Melacon") == NULL)
1219         {
1220                 printf("Could not create JSON object: vendor\n");
1221                 cJSON_Delete(faultFields);
1222                 return NULL;
1223         }
1224
1225         if (cJSON_AddStringToObject(alarmAdditionalInformation, "model", "Simulated Device") == NULL)
1226         {
1227                 printf("Could not create JSON object: model\n");
1228                 cJSON_Delete(faultFields);
1229                 return NULL;
1230         }
1231
1232         return faultFields;
1233 }
1234
1235 static cJSON* createSeverityCounters(counterAlarms count)
1236 {
1237     cJSON *severityCounters = cJSON_CreateObject();
1238     if (severityCounters == NULL)
1239     {
1240         printf("Could not create JSON object: severityCounters\n");
1241         return NULL;
1242     }
1243
1244     if (cJSON_AddNumberToObject(severityCounters, "severity-normal", count.normal) == NULL)
1245     {
1246         printf("Could not create JSON object: severity-normal\n");
1247         return NULL;
1248     }
1249
1250     if (cJSON_AddNumberToObject(severityCounters, "severity-warning", count.warning) == NULL)
1251     {
1252         printf("Could not create JSON object: severity-warning\n");
1253         return NULL;
1254     }
1255
1256     if (cJSON_AddNumberToObject(severityCounters, "severity-minor", count.minor) == NULL)
1257     {
1258         printf("Could not create JSON object: severity-minor\n");
1259         return NULL;
1260     }
1261
1262     if (cJSON_AddNumberToObject(severityCounters, "severity-major", count.major) == NULL)
1263     {
1264         printf("Could not create JSON object: severity-major\n");
1265         return NULL;
1266     }
1267
1268     if (cJSON_AddNumberToObject(severityCounters, "severity-critical", count.critical) == NULL)
1269     {
1270         printf("Could not create JSON object: severity-critical\n");
1271         return NULL;
1272     }
1273
1274     return severityCounters;
1275 }
1276
1277 void writeStatusFile(char *status)
1278 {
1279         char status_file[200];
1280         sprintf(status_file, "%s/status.json", getenv("SCRIPTS_DIR"));
1281         FILE * f = fopen (status_file, "w");
1282
1283         if (f)
1284         {
1285                 fputs(status, f);
1286                 fclose(f);
1287         }
1288         else
1289         {
1290                 printf("Could not write status file!\n");
1291         }
1292 }
1293
1294 int     writeSkeletonStatusFile()
1295 {
1296     cJSON *statusObject = cJSON_CreateObject();
1297     if (statusObject == NULL)
1298     {
1299         printf("Could not create JSON object: statusObject\n");
1300         return SR_ERR_OPERATION_FAILED;
1301     }
1302
1303     // counterAlarms counter = {
1304     //     .normal = 0,
1305     //     .warning = 0,
1306     //     .minor = 0,
1307     //     .major = 0,
1308     //     .critical = 0
1309     // };
1310
1311     // cJSON *totalVesNotifications = createSeverityCounters(counter);
1312     // if (totalVesNotifications == NULL)
1313     // {
1314     //     printf("Could not create JSON object: totalVesNotifications\n");
1315     //     cJSON_Delete(statusObject);
1316     //     return SR_ERR_OPERATION_FAILED;
1317     // }
1318     // cJSON_AddItemToObject(statusObject, "total-ves-notifications-sent", totalVesNotifications);
1319
1320     // cJSON *totalNetconfNotifications = createSeverityCounters(counter);
1321     // if (totalNetconfNotifications == NULL)
1322     // {
1323     //     printf("Could not create JSON object: totalNetconfNotifications\n");
1324     //     cJSON_Delete(statusObject);
1325     //     return SR_ERR_OPERATION_FAILED;
1326     // }
1327     // cJSON_AddItemToObject(statusObject, "total-netconf-notifications-sent", totalNetconfNotifications);
1328
1329     cJSON *deviceList = cJSON_CreateArray();
1330     if (deviceList == NULL)
1331     {
1332         printf("Could not create JSON object: deviceList\n");
1333         cJSON_Delete(statusObject);
1334         return SR_ERR_OPERATION_FAILED;
1335         }
1336     cJSON_AddItemToObject(statusObject, "device-list", deviceList);
1337
1338     char *status_string = NULL;
1339
1340     status_string = cJSON_PrintUnformatted(statusObject);
1341
1342     writeStatusFile(status_string);
1343
1344     if (status_string != NULL)
1345     {
1346         free(status_string);
1347         status_string = NULL;
1348     }
1349
1350     if (statusObject != NULL)
1351     {
1352             cJSON_Delete(statusObject);
1353     }
1354
1355     return SR_ERR_OK;
1356 }
1357
1358 /*
1359  * Dynamically allocated memory;
1360  * Caller needs to free the memory after it uses the value.
1361  *
1362 */
1363 char*   readStatusFileInString(void)
1364 {
1365         char * buffer = 0;
1366         long length;
1367         char config_file[200];
1368         sprintf(config_file, "%s/status.json", getenv("SCRIPTS_DIR"));
1369         FILE * f = fopen (config_file, "rb");
1370
1371         if (f)
1372         {
1373           fseek (f, 0, SEEK_END);
1374           length = ftell (f);
1375           fseek (f, 0, SEEK_SET);
1376           buffer = malloc (length + 1);
1377           if (buffer)
1378           {
1379             fread (buffer, 1, length, f);
1380           }
1381           fclose (f);
1382           buffer[length] = '\0';
1383         }
1384
1385         if (buffer)
1386         {
1387           return buffer;
1388         }
1389
1390         return NULL;
1391 }
1392
1393 /*
1394  * Dynamically allocated memory;
1395  * Caller needs to free the memory after it uses the value.
1396  *
1397 */
1398 cJSON*  getDeviceListFromStatusFile(void)
1399 {
1400     char *stringStatus = readStatusFileInString();
1401
1402         if (stringStatus == NULL)
1403         {
1404                 printf("Could not read status file!\n");
1405                 return NULL;
1406         }
1407
1408         cJSON *jsonStatus = cJSON_Parse(stringStatus);
1409         if (jsonStatus == NULL)
1410         {
1411                 free(stringStatus);
1412                 const char *error_ptr = cJSON_GetErrorPtr();
1413                 if (error_ptr != NULL)
1414                 {
1415                         fprintf(stderr, "Could not parse JSON status! Error before: %s\n", error_ptr);
1416                 }
1417                 return NULL;
1418         }
1419         //we don't need the string anymore
1420         free(stringStatus);
1421         stringStatus = NULL;
1422
1423     return jsonStatus;
1424 }
1425
1426 cJSON* createDeviceListEntry(counterAlarms ves_counter, counterAlarms netconf_counter)
1427 {
1428     cJSON *deviceListEntry = cJSON_CreateObject();
1429     if (deviceListEntry == NULL)
1430     {
1431         printf("Could not create JSON object: deviceListEntry\n");
1432         return NULL;
1433     }
1434
1435     char hostname[100];
1436     sprintf(hostname, "%s", getenv("HOSTNAME"));
1437
1438     if (cJSON_AddStringToObject(deviceListEntry, "device-name", hostname) == NULL)
1439     {
1440         printf("Could not create JSON object: device-name\n");
1441         cJSON_Delete(deviceListEntry);
1442         return NULL;
1443     }
1444
1445     cJSON *vesNotificationsSent = createSeverityCounters(ves_counter);
1446     if (vesNotificationsSent == NULL)
1447     {
1448         printf("Could not create JSON object: vesNotificationsSent\n");
1449         cJSON_Delete(deviceListEntry);
1450         return NULL;
1451     }
1452     cJSON_AddItemToObject(deviceListEntry, "ves-notifications-sent", vesNotificationsSent);
1453
1454     cJSON *netconfNotificationsSent = createSeverityCounters(netconf_counter);
1455     if (netconfNotificationsSent == NULL)
1456     {
1457         printf("Could not create JSON object: netconfNotificationsSent\n");
1458         cJSON_Delete(deviceListEntry);
1459         return NULL;
1460     }
1461     cJSON_AddItemToObject(deviceListEntry, "netconf-notifications-sent", netconfNotificationsSent);
1462
1463     return deviceListEntry;
1464 }
1465
1466 static void modifySeverityCounters(cJSON **severityCounters, counterAlarms count)
1467 {
1468     cJSON *severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-normal");
1469     if (!cJSON_IsNumber(severity))
1470     {
1471         printf("Status JSON is not as expected: severity-normal is not an number");
1472         return;
1473     }
1474     //we set the value of the severity-normal object
1475     cJSON_SetNumberValue(severity, count.normal);
1476
1477     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-warning");
1478     if (!cJSON_IsNumber(severity))
1479     {
1480         printf("Status JSON is not as expected: severity-warning is not an number");
1481         return;
1482     }
1483     //we set the value of the severity-warning object
1484     cJSON_SetNumberValue(severity, count.warning);
1485
1486     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-minor");
1487     if (!cJSON_IsNumber(severity))
1488     {
1489         printf("Status JSON is not as expected: severity-minor is not an number");
1490         return;
1491     }
1492     //we set the value of the severity-minor object
1493     cJSON_SetNumberValue(severity, count.minor);
1494
1495     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-major");
1496     if (!cJSON_IsNumber(severity))
1497     {
1498         printf("Status JSON is not as expected: severity-major is not an number");
1499         return;
1500     }
1501     //we set the value of the severity-major object
1502         cJSON_SetNumberValue(severity, count.major);
1503
1504     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-critical");
1505     if (!cJSON_IsNumber(severity))
1506     {
1507         printf("Status JSON is not as expected: severity-critical is not an number");
1508         return;
1509     }
1510     //we set the value of the severity-critical object
1511         cJSON_SetNumberValue(severity, count.critical);
1512
1513     return;
1514 }
1515
1516 static void modifyDeviceListEntry(cJSON **deviceListEntry, counterAlarms ves_counter, counterAlarms netconf_counter)
1517 {
1518     cJSON *vesNotificationsSent= cJSON_GetObjectItemCaseSensitive(*deviceListEntry, "ves-notifications-sent");
1519     if (!cJSON_IsObject(vesNotificationsSent))
1520     {
1521         printf("Status JSON is not as expected: ves-notifications-sent is not a object");
1522         return;
1523     }
1524
1525     modifySeverityCounters(&vesNotificationsSent, ves_counter);
1526
1527     cJSON *netconfNotificationsSent= cJSON_GetObjectItemCaseSensitive(*deviceListEntry, "netconf-notifications-sent");
1528     if (!cJSON_IsObject(netconfNotificationsSent))
1529     {
1530         printf("Status JSON is not as expected: netconf-notifications-sent is not a object");
1531         return;
1532     }
1533
1534     modifySeverityCounters(&netconfNotificationsSent, netconf_counter);
1535 }
1536
1537 int writeStatusNotificationCounters(counterAlarms ves_counter, counterAlarms netconf_counter)
1538 {
1539         cJSON *jsonStatus = getDeviceListFromStatusFile();
1540
1541         cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1542         if (!cJSON_IsArray(deviceList))
1543         {
1544                 printf("Status JSON is not as expected: device-list is not an object");
1545                 cJSON_Delete(jsonStatus);
1546                 return SR_ERR_OPERATION_FAILED;
1547         }
1548
1549     int array_size = cJSON_GetArraySize(deviceList);
1550
1551     int found = 0;
1552     for (int i=0; i<array_size; ++i)
1553     {
1554         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1555         char hostname[100];
1556         sprintf(hostname, "%s", getenv("HOSTNAME"));
1557
1558         cJSON *deviceName = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "device-name");
1559         if (!cJSON_IsString(deviceName))
1560         {
1561             printf("Status JSON is not as expected: device-name is not a string.");
1562             cJSON_Delete(jsonStatus);
1563             return SR_ERR_OPERATION_FAILED;
1564         }
1565         char *deviceNameString = cJSON_GetStringValue(deviceName);
1566
1567         if (strcmp(hostname, deviceNameString) == 0)
1568         {
1569             modifyDeviceListEntry(&deviceListEntry, ves_counter, netconf_counter);
1570             found = 1;
1571             break;
1572         }
1573     }
1574     if (found == 0)
1575     {
1576         cJSON* deviceListEntry = createDeviceListEntry(ves_counter, netconf_counter);
1577     
1578         cJSON_AddItemToArray(deviceList, deviceListEntry);  
1579     }
1580
1581         //writing the new JSON to the configuration file
1582         char *stringStatus = cJSON_PrintUnformatted(jsonStatus);
1583         writeStatusFile(stringStatus);
1584
1585     if (stringStatus != NULL)
1586     {
1587         free(stringStatus);
1588         stringStatus = NULL;
1589     }
1590
1591     if (jsonStatus != NULL)
1592     {
1593             cJSON_Delete(jsonStatus);
1594     }
1595
1596         return SR_ERR_OK;
1597 }
1598
1599
1600 int removeDeviceEntryFromStatusFile(char *containerId)
1601 {
1602     cJSON *jsonStatus = getDeviceListFromStatusFile();
1603
1604         cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1605         if (!cJSON_IsArray(deviceList))
1606         {
1607                 printf("Status JSON is not as expected: device-list is not an object");
1608                 cJSON_Delete(jsonStatus);
1609                 return SR_ERR_OPERATION_FAILED;
1610         }
1611
1612     int array_size = cJSON_GetArraySize(deviceList);
1613     int found = array_size;
1614
1615     for (int i=0; i<array_size; ++i)
1616     {
1617         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1618         char hostname[100];
1619         sprintf(hostname, "%s", getenv("HOSTNAME"));
1620
1621         cJSON *deviceName = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "device-name");
1622         if (!cJSON_IsString(deviceName))
1623         {
1624             printf("Status JSON is not as expected: device-name is not a string.");
1625             cJSON_Delete(jsonStatus);
1626             return SR_ERR_OPERATION_FAILED;
1627         }
1628         char *deviceNameString = cJSON_GetStringValue(deviceName);
1629
1630         if (strcmp(containerId, deviceNameString) == 0)
1631         {
1632             found = i;
1633             break;
1634         }
1635     }
1636
1637     if (found < array_size)
1638     {
1639         cJSON_DeleteItemFromArray(deviceList, found);
1640     }
1641     else
1642     {
1643         printf("Could not find status file entry for device with id=\"%s\"", containerId);
1644     }
1645
1646         //writing the new JSON to the configuration file
1647         char *stringStatus = cJSON_PrintUnformatted(jsonStatus);
1648         writeStatusFile(stringStatus);
1649
1650     if (stringStatus != NULL)
1651     {
1652         free(stringStatus);
1653         stringStatus = NULL;
1654     }
1655
1656     if (jsonStatus != NULL)
1657     {
1658         cJSON_Delete(jsonStatus);
1659     }
1660
1661         return SR_ERR_OK;
1662 }
1663
1664 int compute_notifications_count(counterAlarms *ves_counter, counterAlarms *netconf_counter)
1665 {
1666     ves_counter->normal = ves_counter->warning = \
1667             ves_counter->minor = ves_counter->major = \
1668             ves_counter->critical = 0;
1669     netconf_counter->normal = netconf_counter->warning = \
1670             netconf_counter->minor = netconf_counter->major = \
1671             netconf_counter->critical = 0;
1672
1673     cJSON *jsonStatus = getDeviceListFromStatusFile();
1674
1675     cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1676         if (!cJSON_IsArray(deviceList))
1677         {
1678                 printf("Status JSON is not as expected: device-list is not an object");
1679                 cJSON_Delete(jsonStatus);
1680                 return SR_ERR_OPERATION_FAILED;
1681         }
1682
1683     int array_size = cJSON_GetArraySize(deviceList);
1684
1685     for (int i=0; i<array_size; ++i)
1686     {
1687         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1688
1689         cJSON *vesNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "ves-notifications-sent");
1690         if (!cJSON_IsObject(vesNotifications))
1691         {
1692             printf("Status JSON is not as expected: ves-notifications-sent is not an object.");
1693             cJSON_Delete(jsonStatus);
1694             return SR_ERR_OPERATION_FAILED;
1695         }
1696
1697         cJSON *severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-normal");
1698         if (!cJSON_IsNumber(severity))
1699         {
1700             printf("Status JSON is not as expected: severity-normal is not a string.");
1701             cJSON_Delete(jsonStatus);
1702             return SR_ERR_OPERATION_FAILED;
1703         }
1704         int counter = (int)(severity->valuedouble);
1705         ves_counter->normal += counter;
1706
1707         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-warning");
1708         if (!cJSON_IsNumber(severity))
1709         {
1710             printf("Status JSON is not as expected: severity-warning is not a string.");
1711             cJSON_Delete(jsonStatus);
1712             return SR_ERR_OPERATION_FAILED;
1713         }
1714         counter = (int)(severity->valuedouble);
1715         ves_counter->warning += counter;
1716
1717         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-minor");
1718         if (!cJSON_IsNumber(severity))
1719         {
1720             printf("Status JSON is not as expected: severity-minor is not a string.");
1721             cJSON_Delete(jsonStatus);
1722             return SR_ERR_OPERATION_FAILED;
1723         }
1724         counter = (int)(severity->valuedouble);
1725         ves_counter->minor += counter;
1726
1727         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-major");
1728         if (!cJSON_IsNumber(severity))
1729         {
1730             printf("Status JSON is not as expected: severity-major is not a string.");
1731             cJSON_Delete(jsonStatus);
1732             return SR_ERR_OPERATION_FAILED;
1733         }
1734         counter = (int)(severity->valuedouble);
1735         ves_counter->major += counter;
1736
1737         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-critical");
1738         if (!cJSON_IsNumber(severity))
1739         {
1740             printf("Status JSON is not as expected: severity-critical is not a string.");
1741             cJSON_Delete(jsonStatus);
1742             return SR_ERR_OPERATION_FAILED;
1743         }
1744         counter = (int)(severity->valuedouble);
1745         ves_counter->critical += counter;
1746
1747         cJSON *netconfNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "netconf-notifications-sent");
1748         if (!cJSON_IsObject(netconfNotifications))
1749         {
1750             printf("Status JSON is not as expected: netconf-notifications-sent is not an object.");
1751             cJSON_Delete(jsonStatus);
1752             return SR_ERR_OPERATION_FAILED;
1753         }
1754
1755         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-normal");
1756         if (!cJSON_IsNumber(severity))
1757         {
1758             printf("Status JSON is not as expected: severity-normal is not a string.");
1759             cJSON_Delete(jsonStatus);
1760             return SR_ERR_OPERATION_FAILED;
1761         }
1762         
1763         counter = (int)(severity->valuedouble);
1764         netconf_counter->normal += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1765
1766         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-warning");
1767         if (!cJSON_IsNumber(severity))
1768         {
1769             printf("Status JSON is not as expected: severity-warning is not a string.");
1770             cJSON_Delete(jsonStatus);
1771             return SR_ERR_OPERATION_FAILED;
1772         }
1773         counter = (int)(severity->valuedouble);
1774         netconf_counter->warning += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1775
1776         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-minor");
1777         if (!cJSON_IsNumber(severity))
1778         {
1779             printf("Status JSON is not as expected: severity-minor is not a string.");
1780             cJSON_Delete(jsonStatus);
1781             return SR_ERR_OPERATION_FAILED;
1782         }
1783         counter = (int)(severity->valuedouble);
1784         netconf_counter->minor += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1785
1786         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-major");
1787         if (!cJSON_IsNumber(severity))
1788         {
1789             printf("Status JSON is not as expected: severity-major is not a string.");
1790             cJSON_Delete(jsonStatus);
1791             return SR_ERR_OPERATION_FAILED;
1792         }
1793         counter = (int)(severity->valuedouble);
1794         netconf_counter->major += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1795
1796         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-critical");
1797         if (!cJSON_IsNumber(severity))
1798         {
1799             printf("Status JSON is not as expected: severity-critical is not a string.");
1800             cJSON_Delete(jsonStatus);
1801             return SR_ERR_OPERATION_FAILED;
1802         }
1803         counter = (int)(severity->valuedouble);
1804         netconf_counter->critical += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1805     }
1806
1807     cJSON_Delete(jsonStatus);
1808
1809     return SR_ERR_OK;
1810 }
1811
1812 int getDeviceCounters(char *containerId, counterAlarms *ves_counter, counterAlarms *netconf_counter)
1813 {
1814     cJSON *jsonStatus = getDeviceListFromStatusFile();
1815
1816     cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1817         if (!cJSON_IsArray(deviceList))
1818         {
1819                 printf("Status JSON is not as expected: device-list is not an object");
1820                 cJSON_Delete(jsonStatus);
1821                 return SR_ERR_OPERATION_FAILED;
1822         }
1823
1824     int array_size = cJSON_GetArraySize(deviceList);
1825
1826     ves_counter->critical = ves_counter->major = ves_counter->minor = ves_counter->warning = ves_counter->normal = 0;
1827     netconf_counter->critical = netconf_counter->major = netconf_counter->minor = netconf_counter->warning = netconf_counter->normal = 0;
1828
1829     for (int i=0; i<array_size; ++i)
1830     {
1831         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1832
1833         cJSON *deviceName = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "device-name");
1834         if (!cJSON_IsString(deviceName))
1835         {
1836             printf("Status JSON is not as expected: device-name is not a string.");
1837             cJSON_Delete(jsonStatus);
1838             return SR_ERR_OPERATION_FAILED;
1839         }
1840         char *deviceNameString = cJSON_GetStringValue(deviceName);
1841
1842         if (strcmp(deviceNameString, containerId) != 0)
1843         {
1844             continue;
1845         }
1846
1847         cJSON *vesNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "ves-notifications-sent");
1848         if (!cJSON_IsObject(vesNotifications))
1849         {
1850             printf("Status JSON is not as expected: ves-notifications-sent is not an object.");
1851             cJSON_Delete(jsonStatus);
1852             return SR_ERR_OPERATION_FAILED;
1853         }
1854
1855         cJSON *severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-normal");
1856         if (!cJSON_IsNumber(severity))
1857         {
1858             printf("Status JSON is not as expected: severity-normal is not a string.");
1859             cJSON_Delete(jsonStatus);
1860             return SR_ERR_OPERATION_FAILED;
1861         }
1862         int counter = (int)(severity->valuedouble);
1863         ves_counter->normal = counter;
1864
1865         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-warning");
1866         if (!cJSON_IsNumber(severity))
1867         {
1868             printf("Status JSON is not as expected: severity-warning is not a string.");
1869             cJSON_Delete(jsonStatus);
1870             return SR_ERR_OPERATION_FAILED;
1871         }
1872         counter = (int)(severity->valuedouble);
1873         ves_counter->warning = counter;
1874
1875         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-minor");
1876         if (!cJSON_IsNumber(severity))
1877         {
1878             printf("Status JSON is not as expected: severity-minor is not a string.");
1879             cJSON_Delete(jsonStatus);
1880             return SR_ERR_OPERATION_FAILED;
1881         }
1882         counter = (int)(severity->valuedouble);
1883         ves_counter->minor = counter;
1884
1885         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-major");
1886         if (!cJSON_IsNumber(severity))
1887         {
1888             printf("Status JSON is not as expected: severity-major is not a string.");
1889             cJSON_Delete(jsonStatus);
1890             return SR_ERR_OPERATION_FAILED;
1891         }
1892         counter = (int)(severity->valuedouble);
1893         ves_counter->major = counter;
1894
1895         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-critical");
1896         if (!cJSON_IsNumber(severity))
1897         {
1898             printf("Status JSON is not as expected: severity-critical is not a string.");
1899             cJSON_Delete(jsonStatus);
1900             return SR_ERR_OPERATION_FAILED;
1901         }
1902         counter = (int)(severity->valuedouble);
1903         ves_counter->critical = counter;
1904
1905         cJSON *netconfNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "netconf-notifications-sent");
1906         if (!cJSON_IsObject(netconfNotifications))
1907         {
1908             printf("Status JSON is not as expected: netconf-notifications-sent is not an object.");
1909             cJSON_Delete(jsonStatus);
1910             return SR_ERR_OPERATION_FAILED;
1911         }
1912
1913         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-normal");
1914         if (!cJSON_IsNumber(severity))
1915         {
1916             printf("Status JSON is not as expected: severity-normal is not a string.");
1917             cJSON_Delete(jsonStatus);
1918             return SR_ERR_OPERATION_FAILED;
1919         }
1920         
1921         counter = (int)(severity->valuedouble);
1922         netconf_counter->normal = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1923
1924         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-warning");
1925         if (!cJSON_IsNumber(severity))
1926         {
1927             printf("Status JSON is not as expected: severity-warning is not a string.");
1928             cJSON_Delete(jsonStatus);
1929             return SR_ERR_OPERATION_FAILED;
1930         }
1931         counter = (int)(severity->valuedouble);
1932         netconf_counter->warning = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1933
1934         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-minor");
1935         if (!cJSON_IsNumber(severity))
1936         {
1937             printf("Status JSON is not as expected: severity-minor is not a string.");
1938             cJSON_Delete(jsonStatus);
1939             return SR_ERR_OPERATION_FAILED;
1940         }
1941         counter = (int)(severity->valuedouble);
1942         netconf_counter->minor = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1943
1944         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-major");
1945         if (!cJSON_IsNumber(severity))
1946         {
1947             printf("Status JSON is not as expected: severity-major is not a string.");
1948             cJSON_Delete(jsonStatus);
1949             return SR_ERR_OPERATION_FAILED;
1950         }
1951         counter = (int)(severity->valuedouble);
1952         netconf_counter->major = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1953
1954         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-critical");
1955         if (!cJSON_IsNumber(severity))
1956         {
1957             printf("Status JSON is not as expected: severity-critical is not a string.");
1958             cJSON_Delete(jsonStatus);
1959             return SR_ERR_OPERATION_FAILED;
1960         }
1961         counter = (int)(severity->valuedouble);
1962         netconf_counter->critical = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1963     }
1964
1965     cJSON_Delete(jsonStatus);
1966
1967     return SR_ERR_OK;
1968 }
1969
1970 int writeSkeletonConfigFile()
1971 {
1972     cJSON *configObject = cJSON_CreateObject();
1973     if (configObject == NULL)
1974     {
1975         printf("Could not create JSON object: configObject\n");
1976         return SR_ERR_OPERATION_FAILED;
1977     }
1978
1979     cJSON *notificationConfig = cJSON_CreateObject();
1980     if (notificationConfig == NULL)
1981     {
1982         printf("Could not create JSON object: notificationConfig\n");
1983         cJSON_Delete(configObject);
1984         return SR_ERR_OPERATION_FAILED;
1985     }
1986     cJSON_AddItemToObject(configObject, "notification-config", notificationConfig);
1987
1988     if (cJSON_AddNumberToObject(notificationConfig, "ves-heartbeat-period", 0) == NULL)
1989     {
1990         printf("Could not create JSON object: ves-heartbeat-period\n");
1991         cJSON_Delete(configObject);
1992         return SR_ERR_OPERATION_FAILED;
1993     }
1994
1995     if (cJSON_AddTrueToObject(notificationConfig, "is-netconf-available") == NULL)
1996     {
1997         printf("Could not create JSON object: is-netconf-available\n");
1998         cJSON_Delete(configObject);
1999         return SR_ERR_OPERATION_FAILED;
2000     }
2001
2002     if (cJSON_AddTrueToObject(notificationConfig, "is-ves-available") == NULL)
2003     {
2004         printf("Could not create JSON object: is-ves-available\n");
2005         cJSON_Delete(configObject);
2006         return SR_ERR_OPERATION_FAILED;
2007     }
2008
2009     cJSON *faultNotificationDelayPeriod = cJSON_CreateArray();
2010     if (faultNotificationDelayPeriod == NULL)
2011     {
2012         printf("Could not create JSON object: faultNotificationDelayPeriod\n");
2013         cJSON_Delete(configObject);
2014         return SR_ERR_OPERATION_FAILED;
2015         }
2016     cJSON_AddItemToObject(notificationConfig, "fault-notification-delay-period", faultNotificationDelayPeriod);
2017
2018     cJSON *arrayItem = cJSON_CreateNumber(0);
2019     if (arrayItem == NULL)
2020     {
2021         printf("Could not create JSON object: arrayItem\n");
2022         cJSON_Delete(configObject);
2023         return SR_ERR_OPERATION_FAILED;
2024         }
2025     cJSON_AddItemToArray(faultNotificationDelayPeriod, arrayItem);
2026
2027     cJSON *vesEndPointDetails = cJSON_CreateObject();
2028     if (vesEndPointDetails == NULL)
2029     {
2030         printf("Could not create JSON object: vesEndPointDetails\n");
2031         cJSON_Delete(configObject);
2032         return SR_ERR_OPERATION_FAILED;
2033     }
2034     cJSON_AddItemToObject(configObject, "ves-endpoint-details", vesEndPointDetails);
2035
2036     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-ip", "172.17.0.1") == NULL)
2037     {
2038         printf("Could not create JSON object: ves-endpoint-ip\n");
2039         cJSON_Delete(configObject);
2040         return SR_ERR_OPERATION_FAILED;
2041     }
2042
2043     if (cJSON_AddNumberToObject(vesEndPointDetails, "ves-endpoint-port", 30007) == NULL)
2044     {
2045         printf("Could not create JSON object: ves-endpoint-port\n");
2046         cJSON_Delete(configObject);
2047         return SR_ERR_OPERATION_FAILED;
2048     }
2049
2050     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-auth-method", "no-auth") == NULL)
2051     {
2052         printf("Could not create JSON object: ves-endpoint-auth-method\n");
2053         cJSON_Delete(configObject);
2054         return SR_ERR_OPERATION_FAILED;
2055     }
2056
2057     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-username", "") == NULL)
2058     {
2059         printf("Could not create JSON object: ves-endpoint-username\n");
2060         cJSON_Delete(configObject);
2061         return SR_ERR_OPERATION_FAILED;
2062     }
2063
2064     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-password", "") == NULL)
2065     {
2066         printf("Could not create JSON object: ves-endpoint-password\n");
2067         cJSON_Delete(configObject);
2068         return SR_ERR_OPERATION_FAILED;
2069     }
2070
2071     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-certificate", "") == NULL)
2072     {
2073         printf("Could not create JSON object: ves-endpoint-certificate\n");
2074         cJSON_Delete(configObject);
2075         return SR_ERR_OPERATION_FAILED;
2076     }
2077
2078     if (cJSON_AddFalseToObject(vesEndPointDetails, "ves-registration") == NULL)
2079     {
2080         printf("Could not create JSON object: ves-registration\n");
2081         cJSON_Delete(configObject);
2082         return SR_ERR_OPERATION_FAILED;
2083     }
2084
2085     cJSON *controllerDetails = cJSON_CreateObject();
2086     if (controllerDetails == NULL)
2087     {
2088         printf("Could not create JSON object: controllerDetails\n");
2089         cJSON_Delete(configObject);
2090         return SR_ERR_OPERATION_FAILED;
2091     }
2092     cJSON_AddItemToObject(configObject, "controller-details", controllerDetails);
2093
2094     if (cJSON_AddStringToObject(controllerDetails, "controller-ip", "172.17.0.1") == NULL)
2095     {
2096         printf("Could not create JSON object: controller-ip\n");
2097         cJSON_Delete(configObject);
2098         return SR_ERR_OPERATION_FAILED;
2099     }
2100
2101     if (cJSON_AddNumberToObject(controllerDetails, "controller-port", 8181) == NULL)
2102     {
2103         printf("Could not create JSON object: controller-port\n");
2104         cJSON_Delete(configObject);
2105         return SR_ERR_OPERATION_FAILED;
2106     }
2107
2108     if (cJSON_AddNumberToObject(controllerDetails, "netconf-call-home-port", 6666) == NULL)
2109     {
2110         printf("Could not create JSON object: netconf-call-home-port\n");
2111         cJSON_Delete(configObject);
2112         return SR_ERR_OPERATION_FAILED;
2113     }
2114
2115     if (cJSON_AddStringToObject(controllerDetails, "controller-username", "admin") == NULL)
2116     {
2117         printf("Could not create JSON object: controller-username\n");
2118         cJSON_Delete(configObject);
2119         return SR_ERR_OPERATION_FAILED;
2120     }
2121
2122     if (cJSON_AddStringToObject(controllerDetails, "controller-password", "admin") == NULL)
2123     {
2124         printf("Could not create JSON object: controller-password\n");
2125         cJSON_Delete(configObject);
2126         return SR_ERR_OPERATION_FAILED;
2127     }
2128
2129     if (cJSON_AddNumberToObject(configObject, "ssh-connections", 1) == NULL)
2130     {
2131         printf("Could not create JSON object: ssh-connections\n");
2132         cJSON_Delete(configObject);
2133         return SR_ERR_OPERATION_FAILED;
2134     }
2135
2136     if (cJSON_AddNumberToObject(configObject, "tls-connections", 0) == NULL)
2137     {
2138         printf("Could not create JSON object: tls-connections\n");
2139         cJSON_Delete(configObject);
2140         return SR_ERR_OPERATION_FAILED;
2141     }
2142
2143     if (cJSON_AddFalseToObject(configObject, "netconf-call-home") == NULL)
2144     {
2145         printf("Could not create JSON object: netconf-call-home\n");
2146         cJSON_Delete(configObject);
2147         return SR_ERR_OPERATION_FAILED;
2148     }
2149
2150     char *config_string = NULL;
2151
2152     config_string = cJSON_PrintUnformatted(configObject);
2153
2154     writeConfigFile(config_string);
2155
2156     if (config_string != NULL)
2157     {
2158         free(config_string);
2159         config_string = NULL;
2160     }
2161
2162     if (configObject != NULL)
2163     {
2164         cJSON_Delete(configObject);
2165     }
2166
2167     return SR_ERR_OK;
2168 }
2169
2170 int getIntFromString(char *string, int def_value)
2171 {
2172     int rc, value = def_value;
2173     if (string != NULL)
2174     {
2175         rc = sscanf(string, "%d", &value);
2176         if (rc != 1)
2177         {
2178             printf("Could not get the %s! Using the default 0...\n", string);
2179             value = def_value;
2180         }
2181     }
2182     return value;
2183 }
2184
2185 int     getSshConnectionsFromConfigJson(void)
2186 {
2187     char *stringConfig = readConfigFileInString();
2188
2189     if (stringConfig == NULL)
2190     {
2191         printf("Could not read JSON configuration file in string.");
2192         return 0;
2193     }
2194
2195     cJSON *jsonConfig = cJSON_Parse(stringConfig);
2196     if (jsonConfig == NULL)
2197     {
2198         free(stringConfig);
2199         const char *error_ptr = cJSON_GetErrorPtr();
2200         if (error_ptr != NULL)
2201         {
2202             fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2203         }
2204         return SR_ERR_OPERATION_FAILED;
2205     }
2206     //we don't need the string anymore
2207     free(stringConfig);
2208     stringConfig = NULL;
2209
2210     cJSON *sshConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ssh-connections");
2211     if (!cJSON_IsNumber(sshConnections))
2212     {
2213         printf("Configuration JSON is not as expected: ssh-connections is not an object");
2214         cJSON_Delete(jsonConfig);
2215         return SR_ERR_OPERATION_FAILED;
2216     }
2217
2218     int num_of_ssh = (int)(sshConnections->valuedouble);
2219
2220     cJSON_Delete(jsonConfig);
2221
2222     return num_of_ssh;
2223 }
2224
2225 int     getTlsConnectionsFromConfigJson(void)
2226 {
2227     char *stringConfig = readConfigFileInString();
2228
2229     if (stringConfig == NULL)
2230     {
2231         printf("Could not read JSON configuration file in string.");
2232         return 0;
2233     }
2234
2235     cJSON *jsonConfig = cJSON_Parse(stringConfig);
2236     if (jsonConfig == NULL)
2237     {
2238         free(stringConfig);
2239         const char *error_ptr = cJSON_GetErrorPtr();
2240         if (error_ptr != NULL)
2241         {
2242             fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2243         }
2244         return SR_ERR_OPERATION_FAILED;
2245     }
2246     //we don't need the string anymore
2247     free(stringConfig);
2248     stringConfig = NULL;
2249
2250     cJSON *tlsConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "tls-connections");
2251     if (!cJSON_IsNumber(tlsConnections))
2252     {
2253         printf("Configuration JSON is not as expected: ssh-connections is not an object");
2254         cJSON_Delete(jsonConfig);
2255         return SR_ERR_OPERATION_FAILED;
2256     }
2257
2258     int num_of_tls = (int)(tlsConnections->valuedouble);
2259
2260     cJSON_Delete(jsonConfig);
2261
2262     return num_of_tls;
2263 }