Add simulator improvements.
[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         sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
414         FILE * f = fopen (config_file, "rb");
415
416         if (f)
417         {
418           fseek (f, 0, SEEK_END);
419           length = ftell (f);
420           fseek (f, 0, SEEK_SET);
421           buffer = malloc (length + 1);
422           if (buffer)
423           {
424             fread (buffer, 1, length, f);
425           }
426           fclose (f);
427           buffer[length] = '\0';
428         }
429
430         if (buffer)
431         {
432           return buffer;
433         }
434
435         return NULL;
436 }
437
438 void    writeConfigFile(char *config)
439 {
440         char config_file[200];
441         sprintf(config_file, "%s/configuration.json", getenv("SCRIPTS_DIR"));
442         FILE * f = fopen (config_file, "w");
443
444         if (f)
445         {
446                 fputs(config, f);
447                 fclose(f);
448         }
449         else
450         {
451                 printf("Could not write configuration file");
452         }
453 }
454
455 int getFaultNotificationDelayPeriodFromConfigJson(int *period_array, int *count)
456 {
457         char *stringConfig = readConfigFileInString();
458
459         if (stringConfig == NULL)
460         {
461                 printf("Could not read JSON configuration file in string.");
462                 return 0;
463         }
464
465         cJSON *jsonConfig = cJSON_Parse(stringConfig);
466         if (jsonConfig == NULL)
467         {
468                 free(stringConfig);
469                 const char *error_ptr = cJSON_GetErrorPtr();
470                 if (error_ptr != NULL)
471                 {
472                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
473                 }
474                 return SR_ERR_OPERATION_FAILED;
475         }
476         //we don't need the string anymore
477         free(stringConfig);
478         stringConfig = NULL;
479
480         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
481         if (!cJSON_IsObject(notifConfig))
482         {
483                 printf("Configuration JSON is not as expected: notification-config is not an object");
484                 cJSON_Delete(jsonConfig);
485                 return SR_ERR_OPERATION_FAILED;
486         }
487
488         cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
489         if (!cJSON_IsArray(faultNotifDelay))
490         {
491                 printf("Configuration JSON is not as expected: fault-notification-delay-period is not an array.");
492                 cJSON_Delete(jsonConfig);
493                 return SR_ERR_OPERATION_FAILED;
494         }
495
496     cJSON *iterator = NULL;
497     *count = 0;
498     int i = 0;
499
500     cJSON_ArrayForEach(iterator, faultNotifDelay) 
501     {
502         if (cJSON_IsNumber(iterator)) 
503         {
504             period_array[i++] = iterator->valueint;
505         } 
506         else 
507         {
508             printf("Invalid number in array!");
509         }
510     }
511
512     *count = i;
513
514         cJSON_Delete(jsonConfig);
515
516         return SR_ERR_OK;
517 }
518
519 int     getVesHeartbeatPeriodFromConfigJson(void)
520 {
521         char *stringConfig = readConfigFileInString();
522         int vesHeartbeat = 0;
523
524         if (stringConfig == NULL)
525         {
526                 printf("Could not read JSON configuration file in string.");
527                 return 0;
528         }
529
530         cJSON *jsonConfig = cJSON_Parse(stringConfig);
531         if (jsonConfig == NULL)
532         {
533                 free(stringConfig);
534                 const char *error_ptr = cJSON_GetErrorPtr();
535                 if (error_ptr != NULL)
536                 {
537                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
538                 }
539                 return SR_ERR_OPERATION_FAILED;
540         }
541         //we don't need the string anymore
542         free(stringConfig);
543         stringConfig = NULL;
544
545         cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
546         if (!cJSON_IsObject(notifConfig))
547         {
548                 printf("Configuration JSON is not as expected: notification-config is not an object");
549                 cJSON_Delete(jsonConfig);
550                 return SR_ERR_OPERATION_FAILED;
551         }
552
553         cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
554         if (!cJSON_IsNumber(vesHeartbeatPeriod))
555         {
556                 printf("Configuration JSON is not as expected: ves-heartbeat-period is not a number");
557                 cJSON_Delete(jsonConfig);
558                 return SR_ERR_OPERATION_FAILED;
559         }
560
561         vesHeartbeat = (int)(vesHeartbeatPeriod->valuedouble);
562
563         cJSON_Delete(jsonConfig);
564
565         return vesHeartbeat;
566 }
567
568
569 /*
570  * Dynamically allocated memory;
571  * Caller needs to free the memory after it uses the value.
572  *
573 */
574 char*   getVesAuthMethodFromConfigJson(void)
575 {
576         char *stringConfig = readConfigFileInString();
577
578         if (stringConfig == NULL)
579         {
580                 printf("Could not read JSON configuration file in string.");
581                 return 0;
582         }
583
584         cJSON *jsonConfig = cJSON_Parse(stringConfig);
585         if (jsonConfig == NULL)
586         {
587                 free(stringConfig);
588                 const char *error_ptr = cJSON_GetErrorPtr();
589                 if (error_ptr != NULL)
590                 {
591                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
592                 }
593                 return NULL;
594         }
595         //we don't need the string anymore
596         free(stringConfig);
597         stringConfig = NULL;
598
599         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
600         if (!cJSON_IsObject(vesDetails))
601         {
602                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
603                 cJSON_Delete(jsonConfig);
604                 return NULL;
605         }
606
607         cJSON *vesAuthMethod = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-auth-method");
608         if (!cJSON_IsString(vesAuthMethod))
609         {
610                 printf("Configuration JSON is not as expected: ves-endpoint-auth-method is not an object");
611                 cJSON_Delete(jsonConfig);
612                 return NULL;
613         }
614
615         char *auth_method_string = strdup(cJSON_GetStringValue(vesAuthMethod));
616
617         cJSON_Delete(jsonConfig);
618
619         return auth_method_string;
620 }
621
622 /*
623  * Dynamically allocated memory;
624  * Caller needs to free the memory after it uses the value.
625  *
626 */
627 char*   getVesIpFromConfigJson(void)
628 {
629         char *stringConfig = readConfigFileInString();
630
631         if (stringConfig == NULL)
632         {
633                 printf("Could not read JSON configuration file in string.");
634                 return 0;
635         }
636
637         cJSON *jsonConfig = cJSON_Parse(stringConfig);
638         if (jsonConfig == NULL)
639         {
640                 free(stringConfig);
641                 const char *error_ptr = cJSON_GetErrorPtr();
642                 if (error_ptr != NULL)
643                 {
644                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
645                 }
646                 return NULL;
647         }
648         //we don't need the string anymore
649         free(stringConfig);
650         stringConfig = NULL;
651
652         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
653         if (!cJSON_IsObject(vesDetails))
654         {
655                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
656                 cJSON_Delete(jsonConfig);
657                 return NULL;
658         }
659
660         cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
661         if (!cJSON_IsString(vesIp))
662         {
663                 printf("Configuration JSON is not as expected: ves-endpoint-ip is not an object");
664                 cJSON_Delete(jsonConfig);
665                 return NULL;
666         }
667
668         char *ves_ip = strdup(cJSON_GetStringValue(vesIp));
669
670         cJSON_Delete(jsonConfig);
671
672         return ves_ip;
673 }
674
675 int     getVesPortFromConfigJson(void)
676 {
677         char *stringConfig = readConfigFileInString();
678
679         if (stringConfig == NULL)
680         {
681                 printf("Could not read JSON configuration file in string.");
682                 return 0;
683         }
684
685         cJSON *jsonConfig = cJSON_Parse(stringConfig);
686         if (jsonConfig == NULL)
687         {
688                 free(stringConfig);
689                 const char *error_ptr = cJSON_GetErrorPtr();
690                 if (error_ptr != NULL)
691                 {
692                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
693                 }
694                 return SR_ERR_OPERATION_FAILED;
695         }
696         //we don't need the string anymore
697         free(stringConfig);
698         stringConfig = NULL;
699
700         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
701         if (!cJSON_IsObject(vesDetails))
702         {
703                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
704                 cJSON_Delete(jsonConfig);
705                 return SR_ERR_OPERATION_FAILED;
706         }
707
708         cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
709         if (!cJSON_IsNumber(vesPort))
710         {
711                 printf("Configuration JSON is not as expected: ves-endpoint-port is not an object");
712                 cJSON_Delete(jsonConfig);
713                 return SR_ERR_OPERATION_FAILED;
714         }
715
716         int port = (int)(vesPort->valuedouble);
717
718         cJSON_Delete(jsonConfig);
719
720         return port;
721 }
722
723 int     getVesRegistrationFromConfigJson(void)
724 {
725         char *stringConfig = readConfigFileInString();
726
727         if (stringConfig == NULL)
728         {
729                 printf("Could not read JSON configuration file in string.");
730                 return 0;
731         }
732
733         cJSON *jsonConfig = cJSON_Parse(stringConfig);
734         if (jsonConfig == NULL)
735         {
736                 free(stringConfig);
737                 const char *error_ptr = cJSON_GetErrorPtr();
738                 if (error_ptr != NULL)
739                 {
740                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
741                 }
742                 return SR_ERR_OPERATION_FAILED;
743         }
744         //we don't need the string anymore
745         free(stringConfig);
746         stringConfig = NULL;
747
748         cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
749         if (!cJSON_IsObject(vesDetails))
750         {
751                 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
752                 cJSON_Delete(jsonConfig);
753                 return SR_ERR_OPERATION_FAILED;
754         }
755
756         cJSON *vesReg = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
757         if (!cJSON_IsBool(vesReg))
758         {
759                 printf("Configuration JSON is not as expected: ves-registration is not an object");
760                 cJSON_Delete(jsonConfig);
761                 return SR_ERR_OPERATION_FAILED;
762         }
763
764         int is_ves_reg = (cJSON_IsTrue(vesReg)) ? TRUE : FALSE;
765
766         cJSON_Delete(jsonConfig);
767
768         return is_ves_reg;
769 }
770
771 /*
772  * Dynamically allocated memory;
773  * Caller needs to free the memory after it uses the value.
774  *
775 */
776 cJSON*  vesCreatePnfRegistrationFields(int port, bool is_tls)
777 {
778         cJSON *pnfRegistrationFields = cJSON_CreateObject();
779         if (pnfRegistrationFields == NULL)
780         {
781                 printf("Could not create JSON object: pnfRegistrationFields\n");
782                 return NULL;
783         }
784
785         if (cJSON_AddStringToObject(pnfRegistrationFields, "pnfRegistrationFieldsVersion", "2.0") == NULL)
786         {
787                 printf("Could not create JSON object: pnfRegistrationFieldsVersion\n");
788                 cJSON_Delete(pnfRegistrationFields);
789                 return NULL;
790         }
791
792         if (cJSON_AddStringToObject(pnfRegistrationFields, "lastServiceDate", "2019-08-16") == NULL)
793         {
794                 printf("Could not create JSON object: lastServiceDate\n");
795                 cJSON_Delete(pnfRegistrationFields);
796                 return NULL;
797         }
798
799         char mac_addr[40];
800         generateRandomMacAddress(mac_addr);
801
802         if (cJSON_AddStringToObject(pnfRegistrationFields, "macAddress", mac_addr) == NULL)
803         {
804                 printf("Could not create JSON object: macAddress\n");
805                 cJSON_Delete(pnfRegistrationFields);
806                 return NULL;
807         }
808
809         if (cJSON_AddStringToObject(pnfRegistrationFields, "manufactureDate", "2019-08-16") == NULL)
810         {
811                 printf("Could not create JSON object: manufactureDate\n");
812                 cJSON_Delete(pnfRegistrationFields);
813                 return NULL;
814         }
815
816         if (cJSON_AddStringToObject(pnfRegistrationFields, "modelNumber", "Simulated Device Melacon") == NULL)
817         {
818                 printf("Could not create JSON object: manufactureDate\n");
819                 cJSON_Delete(pnfRegistrationFields);
820                 return NULL;
821         }
822
823         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV4IpAddress", getenv("NTS_IP")) == NULL)
824         {
825                 printf("Could not create JSON object: oamV4IpAddress\n");
826                 cJSON_Delete(pnfRegistrationFields);
827                 return NULL;
828         }
829
830         if (cJSON_AddStringToObject(pnfRegistrationFields, "oamV6IpAddress", "0:0:0:0:0:ffff:a0a:011") == NULL)
831         {
832                 printf("Could not create JSON object: oamV6IpAddress\n");
833                 cJSON_Delete(pnfRegistrationFields);
834                 return NULL;
835         }
836
837         char serial_number[100];
838         sprintf(serial_number, "%s-%s-%d-Simulated Device Melacon", getenv("HOSTNAME"), getenv("NTS_IP"), port);
839
840         if (cJSON_AddStringToObject(pnfRegistrationFields, "serialNumber", serial_number) == NULL)
841         {
842                 printf("Could not create JSON object: serialNumber\n");
843                 cJSON_Delete(pnfRegistrationFields);
844                 return NULL;
845         }
846
847         if (cJSON_AddStringToObject(pnfRegistrationFields, "softwareVersion", "2.3.5") == NULL)
848         {
849                 printf("Could not create JSON object: softwareVersion\n");
850                 cJSON_Delete(pnfRegistrationFields);
851                 return NULL;
852         }
853
854         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitFamily", "Simulated Device") == NULL)
855         {
856                 printf("Could not create JSON object: unitFamily\n");
857                 cJSON_Delete(pnfRegistrationFields);
858                 return NULL;
859         }
860
861         if (cJSON_AddStringToObject(pnfRegistrationFields, "unitType", "O-RAN-sim") == NULL)
862         {
863                 printf("Could not create JSON object: unitType\n");
864                 cJSON_Delete(pnfRegistrationFields);
865                 return NULL;
866         }
867
868         if (cJSON_AddStringToObject(pnfRegistrationFields, "vendorName", "Melacon") == NULL)
869         {
870                 printf("Could not create JSON object: vendorName\n");
871                 cJSON_Delete(pnfRegistrationFields);
872                 return NULL;
873         }
874
875         cJSON *additionalFields = cJSON_CreateObject();
876         if (additionalFields == NULL)
877         {
878                 printf("Could not create JSON object: additionalFields\n");
879                 cJSON_Delete(pnfRegistrationFields);
880                 return NULL;
881         }
882         cJSON_AddItemToObject(pnfRegistrationFields, "additionalFields", additionalFields);
883
884         char portString[10];
885         sprintf(portString, "%d", port);
886
887         if (cJSON_AddStringToObject(additionalFields, "oamPort", portString) == NULL)
888         {
889                 printf("Could not create JSON object: oamPort\n");
890                 cJSON_Delete(pnfRegistrationFields);
891                 return NULL;
892         }
893
894         if (is_tls)
895         {
896                 //TLS specific configuration
897                 if (cJSON_AddStringToObject(additionalFields, "protocol", "TLS") == NULL)
898                 {
899                         printf("Could not create JSON object: protocol\n");
900                         cJSON_Delete(pnfRegistrationFields);
901                         return NULL;
902                 }
903
904                 //TODO here we have the username from the docker container hardcoded: netconf
905                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
906                 {
907                         printf("Could not create JSON object: username\n");
908                         cJSON_Delete(pnfRegistrationFields);
909                         return NULL;
910                 }
911
912                 if (cJSON_AddStringToObject(additionalFields, "keyId", "device-key") == NULL)
913                 {
914                         printf("Could not create JSON object: keyId\n");
915                         cJSON_Delete(pnfRegistrationFields);
916                         return NULL;
917                 }
918         }
919         else
920         {
921                 //SSH specific configuration
922                 if (cJSON_AddStringToObject(additionalFields, "protocol", "SSH") == NULL)
923                 {
924                         printf("Could not create JSON object: protocol\n");
925                         cJSON_Delete(pnfRegistrationFields);
926                         return NULL;
927                 }
928
929                 //TODO here we have the username from the docker container hardcoded: netconf
930                 if (cJSON_AddStringToObject(additionalFields, "username", "netconf") == NULL)
931                 {
932                         printf("Could not create JSON object: username\n");
933                         cJSON_Delete(pnfRegistrationFields);
934                         return NULL;
935                 }
936
937                 //TODO here we have the password from the docker container hardcoded: netconf
938                 if (cJSON_AddStringToObject(additionalFields, "password", "netconf") == NULL)
939                 {
940                         printf("Could not create JSON object: password\n");
941                         cJSON_Delete(pnfRegistrationFields);
942                         return NULL;
943                 }
944         }
945
946         if (cJSON_AddStringToObject(additionalFields, "reconnectOnChangedSchema", "false") == NULL)
947         {
948                 printf("Could not create JSON object: reconnectOnChangedSchema\n");
949                 cJSON_Delete(pnfRegistrationFields);
950                 return NULL;
951         }
952
953         if (cJSON_AddStringToObject(additionalFields, "sleep-factor", "1.5") == NULL)
954         {
955                 printf("Could not create JSON object: sleep-factor\n");
956                 cJSON_Delete(pnfRegistrationFields);
957                 return NULL;
958         }
959
960         if (cJSON_AddStringToObject(additionalFields, "tcpOnly", "false") == NULL)
961         {
962                 printf("Could not create JSON object: tcpOnly\n");
963                 cJSON_Delete(pnfRegistrationFields);
964                 return NULL;
965         }
966
967         if (cJSON_AddStringToObject(additionalFields, "connectionTimeout", "20000") == NULL)
968         {
969                 printf("Could not create JSON object: connectionTimeout\n");
970                 cJSON_Delete(pnfRegistrationFields);
971                 return NULL;
972         }
973
974         if (cJSON_AddStringToObject(additionalFields, "maxConnectionAttempts", "100") == NULL)
975         {
976                 printf("Could not create JSON object: maxConnectionAttempts\n");
977                 cJSON_Delete(pnfRegistrationFields);
978                 return NULL;
979         }
980
981         if (cJSON_AddStringToObject(additionalFields, "betweenAttemptsTimeout", "2000") == NULL)
982         {
983                 printf("Could not create JSON object: betweenAttemptsTimeout\n");
984                 cJSON_Delete(pnfRegistrationFields);
985                 return NULL;
986         }
987
988         if (cJSON_AddStringToObject(additionalFields, "keepaliveDelay", "120") == NULL)
989         {
990                 printf("Could not create JSON object: keepaliveDelay\n");
991                 cJSON_Delete(pnfRegistrationFields);
992                 return NULL;
993         }
994
995         return pnfRegistrationFields;
996 }
997
998 int     getNetconfAvailableFromConfigJson(void)
999 {
1000         char *stringConfig = readConfigFileInString();
1001
1002         if (stringConfig == NULL)
1003         {
1004                 printf("Could not read JSON configuration file in string.");
1005                 return 0;
1006         }
1007
1008         cJSON *jsonConfig = cJSON_Parse(stringConfig);
1009         if (jsonConfig == NULL)
1010         {
1011                 free(stringConfig);
1012                 const char *error_ptr = cJSON_GetErrorPtr();
1013                 if (error_ptr != NULL)
1014                 {
1015                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1016                 }
1017                 return SR_ERR_OPERATION_FAILED;
1018         }
1019         //we don't need the string anymore
1020         free(stringConfig);
1021         stringConfig = NULL;
1022
1023         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1024         if (!cJSON_IsObject(notifDetails))
1025         {
1026                 printf("Configuration JSON is not as expected: notification-config is not an object");
1027                 cJSON_Delete(jsonConfig);
1028                 return SR_ERR_OPERATION_FAILED;
1029         }
1030
1031         cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-netconf-available");
1032         if (!cJSON_IsBool(isNetconfAvailable))
1033         {
1034                 printf("Configuration JSON is not as expected: is-netconf-available is not an object");
1035                 cJSON_Delete(jsonConfig);
1036                 return SR_ERR_OPERATION_FAILED;
1037         }
1038
1039         int is_netconf_available = (cJSON_IsTrue(isNetconfAvailable)) ? TRUE : FALSE;
1040
1041         cJSON_Delete(jsonConfig);
1042
1043         return is_netconf_available;
1044 }
1045
1046 int     getVesAvailableFromConfigJson(void)
1047 {
1048         char *stringConfig = readConfigFileInString();
1049
1050         if (stringConfig == NULL)
1051         {
1052                 printf("Could not read JSON configuration file in string.");
1053                 return 0;
1054         }
1055
1056         cJSON *jsonConfig = cJSON_Parse(stringConfig);
1057         if (jsonConfig == NULL)
1058         {
1059                 free(stringConfig);
1060                 const char *error_ptr = cJSON_GetErrorPtr();
1061                 if (error_ptr != NULL)
1062                 {
1063                         fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1064                 }
1065                 return SR_ERR_OPERATION_FAILED;
1066         }
1067         //we don't need the string anymore
1068         free(stringConfig);
1069         stringConfig = NULL;
1070
1071         cJSON *notifDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1072         if (!cJSON_IsObject(notifDetails))
1073         {
1074                 printf("Configuration JSON is not as expected: notification-config is not an object");
1075                 cJSON_Delete(jsonConfig);
1076                 return SR_ERR_OPERATION_FAILED;
1077         }
1078
1079         cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifDetails, "is-ves-available");
1080         if (!cJSON_IsBool(isVesAvailable))
1081         {
1082                 printf("Configuration JSON is not as expected: is-ves-available is not an object");
1083                 cJSON_Delete(jsonConfig);
1084                 return SR_ERR_OPERATION_FAILED;
1085         }
1086
1087         int is_netconf_available = (cJSON_IsTrue(isVesAvailable)) ? TRUE : FALSE;
1088
1089         cJSON_Delete(jsonConfig);
1090
1091         return is_netconf_available;
1092 }
1093
1094 /*
1095  * Dynamically allocated memory;
1096  * Caller needs to free the memory after it uses the value.
1097  *
1098 */
1099 cJSON*  vesCreateFaultFields(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem)
1100 {
1101         cJSON *faultFields = cJSON_CreateObject();
1102         if (faultFields == NULL)
1103         {
1104                 printf("Could not create JSON object: faultFields\n");
1105                 return NULL;
1106         }
1107
1108         if (cJSON_AddStringToObject(faultFields, "faultFieldsVersion", "4.0") == NULL)
1109         {
1110                 printf("Could not create JSON object: faultFieldsVersion\n");
1111                 cJSON_Delete(faultFields);
1112                 return NULL;
1113         }
1114
1115         if (cJSON_AddStringToObject(faultFields, "alarmCondition", alarm_condition) == NULL)
1116         {
1117                 printf("Could not create JSON object: alarmCondition\n");
1118                 cJSON_Delete(faultFields);
1119                 return NULL;
1120         }
1121
1122         if (cJSON_AddStringToObject(faultFields, "alarmInterfaceA", alarm_object) == NULL)
1123         {
1124                 printf("Could not create JSON object: alarmInterfaceA\n");
1125                 cJSON_Delete(faultFields);
1126                 return NULL;
1127         }
1128
1129         if (cJSON_AddStringToObject(faultFields, "eventSourceType", "O_RAN_COMPONENT") == NULL)
1130         {
1131                 printf("Could not create JSON object: eventSourceType\n");
1132                 cJSON_Delete(faultFields);
1133                 return NULL;
1134         }
1135
1136         if (cJSON_AddStringToObject(faultFields, "specificProblem", specific_problem) == NULL)
1137         {
1138                 printf("Could not create JSON object: specificProblem\n");
1139                 cJSON_Delete(faultFields);
1140                 return NULL;
1141         }
1142
1143         if (cJSON_AddStringToObject(faultFields, "eventSeverity", severity) == NULL)
1144         {
1145                 printf("Could not create JSON object: eventSeverity\n");
1146                 cJSON_Delete(faultFields);
1147                 return NULL;
1148         }
1149
1150         if (cJSON_AddStringToObject(faultFields, "vfStatus", "Active") == NULL)
1151         {
1152                 printf("Could not create JSON object: vfStatus\n");
1153                 cJSON_Delete(faultFields);
1154                 return NULL;
1155         }
1156
1157         cJSON *alarmAdditionalInformation = cJSON_CreateObject();
1158         if (alarmAdditionalInformation == NULL)
1159         {
1160                 printf("Could not create JSON object: alarmAdditionalInformation\n");
1161                 cJSON_Delete(faultFields);
1162                 return NULL;
1163         }
1164         cJSON_AddItemToObject(faultFields, "alarmAdditionalInformation", alarmAdditionalInformation);
1165
1166         if (cJSON_AddStringToObject(alarmAdditionalInformation, "eventTime", date_time) == NULL)
1167         {
1168                 printf("Could not create JSON object: eventTime\n");
1169                 cJSON_Delete(faultFields);
1170                 return NULL;
1171         }
1172
1173         if (cJSON_AddStringToObject(alarmAdditionalInformation, "equipType", "O-RAN-sim") == NULL)
1174         {
1175                 printf("Could not create JSON object: equipType\n");
1176                 cJSON_Delete(faultFields);
1177                 return NULL;
1178         }
1179
1180         if (cJSON_AddStringToObject(alarmAdditionalInformation, "vendor", "Melacon") == NULL)
1181         {
1182                 printf("Could not create JSON object: vendor\n");
1183                 cJSON_Delete(faultFields);
1184                 return NULL;
1185         }
1186
1187         if (cJSON_AddStringToObject(alarmAdditionalInformation, "model", "Simulated Device") == NULL)
1188         {
1189                 printf("Could not create JSON object: model\n");
1190                 cJSON_Delete(faultFields);
1191                 return NULL;
1192         }
1193
1194         return faultFields;
1195 }
1196
1197 static cJSON* createSeverityCounters(counterAlarms count)
1198 {
1199     cJSON *severityCounters = cJSON_CreateObject();
1200     if (severityCounters == NULL)
1201     {
1202         printf("Could not create JSON object: severityCounters\n");
1203         return NULL;
1204     }
1205
1206     if (cJSON_AddNumberToObject(severityCounters, "severity-normal", count.normal) == NULL)
1207     {
1208         printf("Could not create JSON object: severity-normal\n");
1209         return NULL;
1210     }
1211
1212     if (cJSON_AddNumberToObject(severityCounters, "severity-warning", count.warning) == NULL)
1213     {
1214         printf("Could not create JSON object: severity-warning\n");
1215         return NULL;
1216     }
1217
1218     if (cJSON_AddNumberToObject(severityCounters, "severity-minor", count.minor) == NULL)
1219     {
1220         printf("Could not create JSON object: severity-minor\n");
1221         return NULL;
1222     }
1223
1224     if (cJSON_AddNumberToObject(severityCounters, "severity-major", count.major) == NULL)
1225     {
1226         printf("Could not create JSON object: severity-major\n");
1227         return NULL;
1228     }
1229
1230     if (cJSON_AddNumberToObject(severityCounters, "severity-critical", count.critical) == NULL)
1231     {
1232         printf("Could not create JSON object: severity-critical\n");
1233         return NULL;
1234     }
1235
1236     return severityCounters;
1237 }
1238
1239 void writeStatusFile(char *status)
1240 {
1241         char status_file[200];
1242         sprintf(status_file, "%s/status.json", getenv("SCRIPTS_DIR"));
1243         FILE * f = fopen (status_file, "w");
1244
1245         if (f)
1246         {
1247                 fputs(status, f);
1248                 fclose(f);
1249         }
1250         else
1251         {
1252                 printf("Could not write status file!\n");
1253         }
1254 }
1255
1256 int     writeSkeletonStatusFile()
1257 {
1258     cJSON *statusObject = cJSON_CreateObject();
1259     if (statusObject == NULL)
1260     {
1261         printf("Could not create JSON object: statusObject\n");
1262         return SR_ERR_OPERATION_FAILED;
1263     }
1264
1265     // counterAlarms counter = {
1266     //     .normal = 0,
1267     //     .warning = 0,
1268     //     .minor = 0,
1269     //     .major = 0,
1270     //     .critical = 0
1271     // };
1272
1273     // cJSON *totalVesNotifications = createSeverityCounters(counter);
1274     // if (totalVesNotifications == NULL)
1275     // {
1276     //     printf("Could not create JSON object: totalVesNotifications\n");
1277     //     cJSON_Delete(statusObject);
1278     //     return SR_ERR_OPERATION_FAILED;
1279     // }
1280     // cJSON_AddItemToObject(statusObject, "total-ves-notifications-sent", totalVesNotifications);
1281
1282     // cJSON *totalNetconfNotifications = createSeverityCounters(counter);
1283     // if (totalNetconfNotifications == NULL)
1284     // {
1285     //     printf("Could not create JSON object: totalNetconfNotifications\n");
1286     //     cJSON_Delete(statusObject);
1287     //     return SR_ERR_OPERATION_FAILED;
1288     // }
1289     // cJSON_AddItemToObject(statusObject, "total-netconf-notifications-sent", totalNetconfNotifications);
1290
1291     cJSON *deviceList = cJSON_CreateArray();
1292     if (deviceList == NULL)
1293     {
1294         printf("Could not create JSON object: deviceList\n");
1295         cJSON_Delete(statusObject);
1296         return SR_ERR_OPERATION_FAILED;
1297         }
1298     cJSON_AddItemToObject(statusObject, "device-list", deviceList);
1299
1300     char *status_string = NULL;
1301
1302     status_string = cJSON_PrintUnformatted(statusObject);
1303
1304     writeStatusFile(status_string);
1305
1306     if (status_string != NULL)
1307     {
1308         free(status_string);
1309         status_string = NULL;
1310     }
1311
1312     if (statusObject != NULL)
1313     {
1314             cJSON_Delete(statusObject);
1315     }
1316
1317     return SR_ERR_OK;
1318 }
1319
1320 /*
1321  * Dynamically allocated memory;
1322  * Caller needs to free the memory after it uses the value.
1323  *
1324 */
1325 char*   readStatusFileInString(void)
1326 {
1327         char * buffer = 0;
1328         long length;
1329         char config_file[200];
1330         sprintf(config_file, "%s/status.json", getenv("SCRIPTS_DIR"));
1331         FILE * f = fopen (config_file, "rb");
1332
1333         if (f)
1334         {
1335           fseek (f, 0, SEEK_END);
1336           length = ftell (f);
1337           fseek (f, 0, SEEK_SET);
1338           buffer = malloc (length + 1);
1339           if (buffer)
1340           {
1341             fread (buffer, 1, length, f);
1342           }
1343           fclose (f);
1344           buffer[length] = '\0';
1345         }
1346
1347         if (buffer)
1348         {
1349           return buffer;
1350         }
1351
1352         return NULL;
1353 }
1354
1355 /*
1356  * Dynamically allocated memory;
1357  * Caller needs to free the memory after it uses the value.
1358  *
1359 */
1360 cJSON*  getDeviceListFromStatusFile(void)
1361 {
1362     char *stringStatus = readStatusFileInString();
1363
1364         if (stringStatus == NULL)
1365         {
1366                 printf("Could not read status file!\n");
1367                 return NULL;
1368         }
1369
1370         cJSON *jsonStatus = cJSON_Parse(stringStatus);
1371         if (jsonStatus == NULL)
1372         {
1373                 free(stringStatus);
1374                 const char *error_ptr = cJSON_GetErrorPtr();
1375                 if (error_ptr != NULL)
1376                 {
1377                         fprintf(stderr, "Could not parse JSON status! Error before: %s\n", error_ptr);
1378                 }
1379                 return NULL;
1380         }
1381         //we don't need the string anymore
1382         free(stringStatus);
1383         stringStatus = NULL;
1384
1385     return jsonStatus;
1386 }
1387
1388 cJSON* createDeviceListEntry(counterAlarms ves_counter, counterAlarms netconf_counter)
1389 {
1390     cJSON *deviceListEntry = cJSON_CreateObject();
1391     if (deviceListEntry == NULL)
1392     {
1393         printf("Could not create JSON object: deviceListEntry\n");
1394         return NULL;
1395     }
1396
1397     char hostname[100];
1398     sprintf(hostname, "%s", getenv("HOSTNAME"));
1399
1400     if (cJSON_AddStringToObject(deviceListEntry, "device-name", hostname) == NULL)
1401     {
1402         printf("Could not create JSON object: device-name\n");
1403         cJSON_Delete(deviceListEntry);
1404         return NULL;
1405     }
1406
1407     cJSON *vesNotificationsSent = createSeverityCounters(ves_counter);
1408     if (vesNotificationsSent == NULL)
1409     {
1410         printf("Could not create JSON object: vesNotificationsSent\n");
1411         cJSON_Delete(deviceListEntry);
1412         return NULL;
1413     }
1414     cJSON_AddItemToObject(deviceListEntry, "ves-notifications-sent", vesNotificationsSent);
1415
1416     cJSON *netconfNotificationsSent = createSeverityCounters(netconf_counter);
1417     if (netconfNotificationsSent == NULL)
1418     {
1419         printf("Could not create JSON object: netconfNotificationsSent\n");
1420         cJSON_Delete(deviceListEntry);
1421         return NULL;
1422     }
1423     cJSON_AddItemToObject(deviceListEntry, "netconf-notifications-sent", netconfNotificationsSent);
1424
1425     return deviceListEntry;
1426 }
1427
1428 static void modifySeverityCounters(cJSON **severityCounters, counterAlarms count)
1429 {
1430     cJSON *severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-normal");
1431     if (!cJSON_IsNumber(severity))
1432     {
1433         printf("Status JSON is not as expected: severity-normal is not an number");
1434         return;
1435     }
1436     //we set the value of the severity-normal object
1437     cJSON_SetNumberValue(severity, count.normal);
1438
1439     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-warning");
1440     if (!cJSON_IsNumber(severity))
1441     {
1442         printf("Status JSON is not as expected: severity-warning is not an number");
1443         return;
1444     }
1445     //we set the value of the severity-warning object
1446     cJSON_SetNumberValue(severity, count.warning);
1447
1448     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-minor");
1449     if (!cJSON_IsNumber(severity))
1450     {
1451         printf("Status JSON is not as expected: severity-minor is not an number");
1452         return;
1453     }
1454     //we set the value of the severity-minor object
1455     cJSON_SetNumberValue(severity, count.minor);
1456
1457     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-major");
1458     if (!cJSON_IsNumber(severity))
1459     {
1460         printf("Status JSON is not as expected: severity-major is not an number");
1461         return;
1462     }
1463     //we set the value of the severity-major object
1464         cJSON_SetNumberValue(severity, count.major);
1465
1466     severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-critical");
1467     if (!cJSON_IsNumber(severity))
1468     {
1469         printf("Status JSON is not as expected: severity-critical is not an number");
1470         return;
1471     }
1472     //we set the value of the severity-critical object
1473         cJSON_SetNumberValue(severity, count.critical);
1474
1475     return;
1476 }
1477
1478 static void modifyDeviceListEntry(cJSON **deviceListEntry, counterAlarms ves_counter, counterAlarms netconf_counter)
1479 {
1480     cJSON *vesNotificationsSent= cJSON_GetObjectItemCaseSensitive(*deviceListEntry, "ves-notifications-sent");
1481     if (!cJSON_IsObject(vesNotificationsSent))
1482     {
1483         printf("Status JSON is not as expected: ves-notifications-sent is not a object");
1484         return;
1485     }
1486
1487     modifySeverityCounters(&vesNotificationsSent, ves_counter);
1488
1489     cJSON *netconfNotificationsSent= cJSON_GetObjectItemCaseSensitive(*deviceListEntry, "netconf-notifications-sent");
1490     if (!cJSON_IsObject(netconfNotificationsSent))
1491     {
1492         printf("Status JSON is not as expected: netconf-notifications-sent is not a object");
1493         return;
1494     }
1495
1496     modifySeverityCounters(&netconfNotificationsSent, netconf_counter);
1497 }
1498
1499 int writeStatusNotificationCounters(counterAlarms ves_counter, counterAlarms netconf_counter)
1500 {
1501         cJSON *jsonStatus = getDeviceListFromStatusFile();
1502
1503         cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1504         if (!cJSON_IsArray(deviceList))
1505         {
1506                 printf("Status JSON is not as expected: device-list is not an object");
1507                 cJSON_Delete(jsonStatus);
1508                 return SR_ERR_OPERATION_FAILED;
1509         }
1510
1511     int array_size = cJSON_GetArraySize(deviceList);
1512
1513     int found = 0;
1514     for (int i=0; i<array_size; ++i)
1515     {
1516         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1517         char hostname[100];
1518         sprintf(hostname, "%s", getenv("HOSTNAME"));
1519
1520         cJSON *deviceName = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "device-name");
1521         if (!cJSON_IsString(deviceName))
1522         {
1523             printf("Status JSON is not as expected: device-name is not a string.");
1524             cJSON_Delete(jsonStatus);
1525             return SR_ERR_OPERATION_FAILED;
1526         }
1527         char *deviceNameString = cJSON_GetStringValue(deviceName);
1528
1529         if (strcmp(hostname, deviceNameString) == 0)
1530         {
1531             modifyDeviceListEntry(&deviceListEntry, ves_counter, netconf_counter);
1532             found = 1;
1533             break;
1534         }
1535     }
1536     if (found == 0)
1537     {
1538         cJSON* deviceListEntry = createDeviceListEntry(ves_counter, netconf_counter);
1539     
1540         cJSON_AddItemToArray(deviceList, deviceListEntry);  
1541     }
1542
1543         //writing the new JSON to the configuration file
1544         char *stringStatus = cJSON_PrintUnformatted(jsonStatus);
1545         writeStatusFile(stringStatus);
1546
1547     if (stringStatus != NULL)
1548     {
1549         free(stringStatus);
1550         stringStatus = NULL;
1551     }
1552
1553     if (jsonStatus != NULL)
1554     {
1555             cJSON_Delete(jsonStatus);
1556     }
1557
1558         return SR_ERR_OK;
1559 }
1560
1561
1562 int removeDeviceEntryFromStatusFile(char *containerId)
1563 {
1564     cJSON *jsonStatus = getDeviceListFromStatusFile();
1565
1566         cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1567         if (!cJSON_IsArray(deviceList))
1568         {
1569                 printf("Status JSON is not as expected: device-list is not an object");
1570                 cJSON_Delete(jsonStatus);
1571                 return SR_ERR_OPERATION_FAILED;
1572         }
1573
1574     int array_size = cJSON_GetArraySize(deviceList);
1575     int found = array_size;
1576
1577     for (int i=0; i<array_size; ++i)
1578     {
1579         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1580         char hostname[100];
1581         sprintf(hostname, "%s", getenv("HOSTNAME"));
1582
1583         cJSON *deviceName = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "device-name");
1584         if (!cJSON_IsString(deviceName))
1585         {
1586             printf("Status JSON is not as expected: device-name is not a string.");
1587             cJSON_Delete(jsonStatus);
1588             return SR_ERR_OPERATION_FAILED;
1589         }
1590         char *deviceNameString = cJSON_GetStringValue(deviceName);
1591
1592         if (strcmp(containerId, deviceNameString) == 0)
1593         {
1594             found = i;
1595             break;
1596         }
1597     }
1598
1599     if (found < array_size)
1600     {
1601         cJSON_DeleteItemFromArray(deviceList, found);
1602     }
1603     else
1604     {
1605         printf("Could not find status file entry for device with id=\"%s\"", containerId);
1606     }
1607
1608         //writing the new JSON to the configuration file
1609         char *stringStatus = cJSON_PrintUnformatted(jsonStatus);
1610         writeStatusFile(stringStatus);
1611
1612     if (stringStatus != NULL)
1613     {
1614         free(stringStatus);
1615         stringStatus = NULL;
1616     }
1617
1618     if (jsonStatus != NULL)
1619     {
1620         cJSON_Delete(jsonStatus);
1621     }
1622
1623         return SR_ERR_OK;
1624 }
1625
1626 int compute_notifications_count(counterAlarms *ves_counter, counterAlarms *netconf_counter)
1627 {
1628     ves_counter->normal = ves_counter->warning = \
1629             ves_counter->minor = ves_counter->major = \
1630             ves_counter->critical = 0;
1631     netconf_counter->normal = netconf_counter->warning = \
1632             netconf_counter->minor = netconf_counter->major = \
1633             netconf_counter->critical = 0;
1634
1635     cJSON *jsonStatus = getDeviceListFromStatusFile();
1636
1637     cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1638         if (!cJSON_IsArray(deviceList))
1639         {
1640                 printf("Status JSON is not as expected: device-list is not an object");
1641                 cJSON_Delete(jsonStatus);
1642                 return SR_ERR_OPERATION_FAILED;
1643         }
1644
1645     int array_size = cJSON_GetArraySize(deviceList);
1646
1647     for (int i=0; i<array_size; ++i)
1648     {
1649         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1650
1651         cJSON *vesNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "ves-notifications-sent");
1652         if (!cJSON_IsObject(vesNotifications))
1653         {
1654             printf("Status JSON is not as expected: ves-notifications-sent is not an object.");
1655             cJSON_Delete(jsonStatus);
1656             return SR_ERR_OPERATION_FAILED;
1657         }
1658
1659         cJSON *severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-normal");
1660         if (!cJSON_IsNumber(severity))
1661         {
1662             printf("Status JSON is not as expected: severity-normal is not a string.");
1663             cJSON_Delete(jsonStatus);
1664             return SR_ERR_OPERATION_FAILED;
1665         }
1666         int counter = (int)(severity->valuedouble);
1667         ves_counter->normal += counter;
1668
1669         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-warning");
1670         if (!cJSON_IsNumber(severity))
1671         {
1672             printf("Status JSON is not as expected: severity-warning is not a string.");
1673             cJSON_Delete(jsonStatus);
1674             return SR_ERR_OPERATION_FAILED;
1675         }
1676         counter = (int)(severity->valuedouble);
1677         ves_counter->warning += counter;
1678
1679         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-minor");
1680         if (!cJSON_IsNumber(severity))
1681         {
1682             printf("Status JSON is not as expected: severity-minor is not a string.");
1683             cJSON_Delete(jsonStatus);
1684             return SR_ERR_OPERATION_FAILED;
1685         }
1686         counter = (int)(severity->valuedouble);
1687         ves_counter->minor += counter;
1688
1689         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-major");
1690         if (!cJSON_IsNumber(severity))
1691         {
1692             printf("Status JSON is not as expected: severity-major is not a string.");
1693             cJSON_Delete(jsonStatus);
1694             return SR_ERR_OPERATION_FAILED;
1695         }
1696         counter = (int)(severity->valuedouble);
1697         ves_counter->major += counter;
1698
1699         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-critical");
1700         if (!cJSON_IsNumber(severity))
1701         {
1702             printf("Status JSON is not as expected: severity-critical is not a string.");
1703             cJSON_Delete(jsonStatus);
1704             return SR_ERR_OPERATION_FAILED;
1705         }
1706         counter = (int)(severity->valuedouble);
1707         ves_counter->critical += counter;
1708
1709         cJSON *netconfNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "netconf-notifications-sent");
1710         if (!cJSON_IsObject(netconfNotifications))
1711         {
1712             printf("Status JSON is not as expected: netconf-notifications-sent is not an object.");
1713             cJSON_Delete(jsonStatus);
1714             return SR_ERR_OPERATION_FAILED;
1715         }
1716
1717         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-normal");
1718         if (!cJSON_IsNumber(severity))
1719         {
1720             printf("Status JSON is not as expected: severity-normal is not a string.");
1721             cJSON_Delete(jsonStatus);
1722             return SR_ERR_OPERATION_FAILED;
1723         }
1724         
1725         counter = (int)(severity->valuedouble);
1726         netconf_counter->normal += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1727
1728         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-warning");
1729         if (!cJSON_IsNumber(severity))
1730         {
1731             printf("Status JSON is not as expected: severity-warning is not a string.");
1732             cJSON_Delete(jsonStatus);
1733             return SR_ERR_OPERATION_FAILED;
1734         }
1735         counter = (int)(severity->valuedouble);
1736         netconf_counter->warning += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1737
1738         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-minor");
1739         if (!cJSON_IsNumber(severity))
1740         {
1741             printf("Status JSON is not as expected: severity-minor is not a string.");
1742             cJSON_Delete(jsonStatus);
1743             return SR_ERR_OPERATION_FAILED;
1744         }
1745         counter = (int)(severity->valuedouble);
1746         netconf_counter->minor += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1747
1748         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-major");
1749         if (!cJSON_IsNumber(severity))
1750         {
1751             printf("Status JSON is not as expected: severity-major is not a string.");
1752             cJSON_Delete(jsonStatus);
1753             return SR_ERR_OPERATION_FAILED;
1754         }
1755         counter = (int)(severity->valuedouble);
1756         netconf_counter->major += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1757
1758         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-critical");
1759         if (!cJSON_IsNumber(severity))
1760         {
1761             printf("Status JSON is not as expected: severity-critical is not a string.");
1762             cJSON_Delete(jsonStatus);
1763             return SR_ERR_OPERATION_FAILED;
1764         }
1765         counter = (int)(severity->valuedouble);
1766         netconf_counter->critical += (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1767     }
1768
1769     cJSON_Delete(jsonStatus);
1770
1771     return SR_ERR_OK;
1772 }
1773
1774 int getDeviceCounters(char *containerId, counterAlarms *ves_counter, counterAlarms *netconf_counter)
1775 {
1776     cJSON *jsonStatus = getDeviceListFromStatusFile();
1777
1778     cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list");
1779         if (!cJSON_IsArray(deviceList))
1780         {
1781                 printf("Status JSON is not as expected: device-list is not an object");
1782                 cJSON_Delete(jsonStatus);
1783                 return SR_ERR_OPERATION_FAILED;
1784         }
1785
1786     int array_size = cJSON_GetArraySize(deviceList);
1787
1788     ves_counter->critical = ves_counter->major = ves_counter->minor = ves_counter->warning = ves_counter->normal = 0;
1789     netconf_counter->critical = netconf_counter->major = netconf_counter->minor = netconf_counter->warning = netconf_counter->normal = 0;
1790
1791     for (int i=0; i<array_size; ++i)
1792     {
1793         cJSON *deviceListEntry = cJSON_GetArrayItem(deviceList, i);
1794
1795         cJSON *deviceName = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "device-name");
1796         if (!cJSON_IsString(deviceName))
1797         {
1798             printf("Status JSON is not as expected: device-name is not a string.");
1799             cJSON_Delete(jsonStatus);
1800             return SR_ERR_OPERATION_FAILED;
1801         }
1802         char *deviceNameString = cJSON_GetStringValue(deviceName);
1803
1804         if (strcmp(deviceNameString, containerId) != 0)
1805         {
1806             continue;
1807         }
1808
1809         cJSON *vesNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "ves-notifications-sent");
1810         if (!cJSON_IsObject(vesNotifications))
1811         {
1812             printf("Status JSON is not as expected: ves-notifications-sent is not an object.");
1813             cJSON_Delete(jsonStatus);
1814             return SR_ERR_OPERATION_FAILED;
1815         }
1816
1817         cJSON *severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-normal");
1818         if (!cJSON_IsNumber(severity))
1819         {
1820             printf("Status JSON is not as expected: severity-normal is not a string.");
1821             cJSON_Delete(jsonStatus);
1822             return SR_ERR_OPERATION_FAILED;
1823         }
1824         int counter = (int)(severity->valuedouble);
1825         ves_counter->normal = counter;
1826
1827         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-warning");
1828         if (!cJSON_IsNumber(severity))
1829         {
1830             printf("Status JSON is not as expected: severity-warning is not a string.");
1831             cJSON_Delete(jsonStatus);
1832             return SR_ERR_OPERATION_FAILED;
1833         }
1834         counter = (int)(severity->valuedouble);
1835         ves_counter->warning = counter;
1836
1837         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-minor");
1838         if (!cJSON_IsNumber(severity))
1839         {
1840             printf("Status JSON is not as expected: severity-minor is not a string.");
1841             cJSON_Delete(jsonStatus);
1842             return SR_ERR_OPERATION_FAILED;
1843         }
1844         counter = (int)(severity->valuedouble);
1845         ves_counter->minor = counter;
1846
1847         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-major");
1848         if (!cJSON_IsNumber(severity))
1849         {
1850             printf("Status JSON is not as expected: severity-major is not a string.");
1851             cJSON_Delete(jsonStatus);
1852             return SR_ERR_OPERATION_FAILED;
1853         }
1854         counter = (int)(severity->valuedouble);
1855         ves_counter->major = counter;
1856
1857         severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-critical");
1858         if (!cJSON_IsNumber(severity))
1859         {
1860             printf("Status JSON is not as expected: severity-critical is not a string.");
1861             cJSON_Delete(jsonStatus);
1862             return SR_ERR_OPERATION_FAILED;
1863         }
1864         counter = (int)(severity->valuedouble);
1865         ves_counter->critical = counter;
1866
1867         cJSON *netconfNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "netconf-notifications-sent");
1868         if (!cJSON_IsObject(netconfNotifications))
1869         {
1870             printf("Status JSON is not as expected: netconf-notifications-sent is not an object.");
1871             cJSON_Delete(jsonStatus);
1872             return SR_ERR_OPERATION_FAILED;
1873         }
1874
1875         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-normal");
1876         if (!cJSON_IsNumber(severity))
1877         {
1878             printf("Status JSON is not as expected: severity-normal is not a string.");
1879             cJSON_Delete(jsonStatus);
1880             return SR_ERR_OPERATION_FAILED;
1881         }
1882         
1883         counter = (int)(severity->valuedouble);
1884         netconf_counter->normal = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1885
1886         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-warning");
1887         if (!cJSON_IsNumber(severity))
1888         {
1889             printf("Status JSON is not as expected: severity-warning is not a string.");
1890             cJSON_Delete(jsonStatus);
1891             return SR_ERR_OPERATION_FAILED;
1892         }
1893         counter = (int)(severity->valuedouble);
1894         netconf_counter->warning = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1895
1896         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-minor");
1897         if (!cJSON_IsNumber(severity))
1898         {
1899             printf("Status JSON is not as expected: severity-minor is not a string.");
1900             cJSON_Delete(jsonStatus);
1901             return SR_ERR_OPERATION_FAILED;
1902         }
1903         counter = (int)(severity->valuedouble);
1904         netconf_counter->minor = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1905
1906         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-major");
1907         if (!cJSON_IsNumber(severity))
1908         {
1909             printf("Status JSON is not as expected: severity-major is not a string.");
1910             cJSON_Delete(jsonStatus);
1911             return SR_ERR_OPERATION_FAILED;
1912         }
1913         counter = (int)(severity->valuedouble);
1914         netconf_counter->major = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1915
1916         severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-critical");
1917         if (!cJSON_IsNumber(severity))
1918         {
1919             printf("Status JSON is not as expected: severity-critical is not a string.");
1920             cJSON_Delete(jsonStatus);
1921             return SR_ERR_OPERATION_FAILED;
1922         }
1923         counter = (int)(severity->valuedouble);
1924         netconf_counter->critical = (counter * NETCONF_CONNECTIONS_PER_DEVICE);
1925     }
1926
1927     cJSON_Delete(jsonStatus);
1928
1929     return SR_ERR_OK;
1930 }
1931
1932 int writeSkeletonConfigFile()
1933 {
1934     cJSON *configObject = cJSON_CreateObject();
1935     if (configObject == NULL)
1936     {
1937         printf("Could not create JSON object: configObject\n");
1938         return SR_ERR_OPERATION_FAILED;
1939     }
1940
1941     cJSON *notificationConfig = cJSON_CreateObject();
1942     if (notificationConfig == NULL)
1943     {
1944         printf("Could not create JSON object: notificationConfig\n");
1945         cJSON_Delete(configObject);
1946         return SR_ERR_OPERATION_FAILED;
1947     }
1948     cJSON_AddItemToObject(configObject, "notification-config", notificationConfig);
1949
1950     if (cJSON_AddNumberToObject(notificationConfig, "ves-heartbeat-period", 0) == NULL)
1951     {
1952         printf("Could not create JSON object: ves-heartbeat-period\n");
1953         cJSON_Delete(configObject);
1954         return SR_ERR_OPERATION_FAILED;
1955     }
1956
1957     if (cJSON_AddTrueToObject(notificationConfig, "is-netconf-available") == NULL)
1958     {
1959         printf("Could not create JSON object: is-netconf-available\n");
1960         cJSON_Delete(configObject);
1961         return SR_ERR_OPERATION_FAILED;
1962     }
1963
1964     if (cJSON_AddTrueToObject(notificationConfig, "is-ves-available") == NULL)
1965     {
1966         printf("Could not create JSON object: is-ves-available\n");
1967         cJSON_Delete(configObject);
1968         return SR_ERR_OPERATION_FAILED;
1969     }
1970
1971     cJSON *faultNotificationDelayPeriod = cJSON_CreateArray();
1972     if (faultNotificationDelayPeriod == NULL)
1973     {
1974         printf("Could not create JSON object: faultNotificationDelayPeriod\n");
1975         cJSON_Delete(configObject);
1976         return SR_ERR_OPERATION_FAILED;
1977         }
1978     cJSON_AddItemToObject(notificationConfig, "fault-notification-delay-period", faultNotificationDelayPeriod);
1979
1980     cJSON *arrayItem = cJSON_CreateNumber(0);
1981     if (arrayItem == NULL)
1982     {
1983         printf("Could not create JSON object: arrayItem\n");
1984         cJSON_Delete(configObject);
1985         return SR_ERR_OPERATION_FAILED;
1986         }
1987     cJSON_AddItemToArray(faultNotificationDelayPeriod, arrayItem);
1988
1989     cJSON *vesEndPointDetails = cJSON_CreateObject();
1990     if (vesEndPointDetails == NULL)
1991     {
1992         printf("Could not create JSON object: vesEndPointDetails\n");
1993         cJSON_Delete(configObject);
1994         return SR_ERR_OPERATION_FAILED;
1995     }
1996     cJSON_AddItemToObject(configObject, "ves-endpoint-details", vesEndPointDetails);
1997
1998     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-ip", "172.17.0.1") == NULL)
1999     {
2000         printf("Could not create JSON object: ves-endpoint-ip\n");
2001         cJSON_Delete(configObject);
2002         return SR_ERR_OPERATION_FAILED;
2003     }
2004
2005     if (cJSON_AddNumberToObject(vesEndPointDetails, "ves-endpoint-port", 30007) == NULL)
2006     {
2007         printf("Could not create JSON object: ves-endpoint-port\n");
2008         cJSON_Delete(configObject);
2009         return SR_ERR_OPERATION_FAILED;
2010     }
2011
2012     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-auth-method", "no-auth") == NULL)
2013     {
2014         printf("Could not create JSON object: ves-endpoint-auth-method\n");
2015         cJSON_Delete(configObject);
2016         return SR_ERR_OPERATION_FAILED;
2017     }
2018
2019     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-username", "") == NULL)
2020     {
2021         printf("Could not create JSON object: ves-endpoint-username\n");
2022         cJSON_Delete(configObject);
2023         return SR_ERR_OPERATION_FAILED;
2024     }
2025
2026     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-password", "") == NULL)
2027     {
2028         printf("Could not create JSON object: ves-endpoint-password\n");
2029         cJSON_Delete(configObject);
2030         return SR_ERR_OPERATION_FAILED;
2031     }
2032
2033     if (cJSON_AddStringToObject(vesEndPointDetails, "ves-endpoint-certificate", "") == NULL)
2034     {
2035         printf("Could not create JSON object: ves-endpoint-certificate\n");
2036         cJSON_Delete(configObject);
2037         return SR_ERR_OPERATION_FAILED;
2038     }
2039
2040     if (cJSON_AddFalseToObject(vesEndPointDetails, "ves-registration") == NULL)
2041     {
2042         printf("Could not create JSON object: ves-registration\n");
2043         cJSON_Delete(configObject);
2044         return SR_ERR_OPERATION_FAILED;
2045     }
2046
2047     cJSON *controllerDetails = cJSON_CreateObject();
2048     if (controllerDetails == NULL)
2049     {
2050         printf("Could not create JSON object: controllerDetails\n");
2051         cJSON_Delete(configObject);
2052         return SR_ERR_OPERATION_FAILED;
2053     }
2054     cJSON_AddItemToObject(configObject, "controller-details", controllerDetails);
2055
2056     if (cJSON_AddStringToObject(controllerDetails, "controller-ip", "172.17.0.1") == NULL)
2057     {
2058         printf("Could not create JSON object: controller-ip\n");
2059         cJSON_Delete(configObject);
2060         return SR_ERR_OPERATION_FAILED;
2061     }
2062
2063     if (cJSON_AddNumberToObject(controllerDetails, "controller-port", 8181) == NULL)
2064     {
2065         printf("Could not create JSON object: controller-port\n");
2066         cJSON_Delete(configObject);
2067         return SR_ERR_OPERATION_FAILED;
2068     }
2069
2070     if (cJSON_AddNumberToObject(controllerDetails, "netconf-call-home-port", 6666) == NULL)
2071     {
2072         printf("Could not create JSON object: netconf-call-home-port\n");
2073         cJSON_Delete(configObject);
2074         return SR_ERR_OPERATION_FAILED;
2075     }
2076
2077     if (cJSON_AddStringToObject(controllerDetails, "controller-username", "admin") == NULL)
2078     {
2079         printf("Could not create JSON object: controller-username\n");
2080         cJSON_Delete(configObject);
2081         return SR_ERR_OPERATION_FAILED;
2082     }
2083
2084     if (cJSON_AddStringToObject(controllerDetails, "controller-password", "admin") == NULL)
2085     {
2086         printf("Could not create JSON object: controller-password\n");
2087         cJSON_Delete(configObject);
2088         return SR_ERR_OPERATION_FAILED;
2089     }
2090
2091     if (cJSON_AddNumberToObject(configObject, "ssh-connections", 1) == NULL)
2092     {
2093         printf("Could not create JSON object: ssh-connections\n");
2094         cJSON_Delete(configObject);
2095         return SR_ERR_OPERATION_FAILED;
2096     }
2097
2098     if (cJSON_AddNumberToObject(configObject, "tls-connections", 0) == NULL)
2099     {
2100         printf("Could not create JSON object: tls-connections\n");
2101         cJSON_Delete(configObject);
2102         return SR_ERR_OPERATION_FAILED;
2103     }
2104
2105     if (cJSON_AddFalseToObject(configObject, "netconf-call-home") == NULL)
2106     {
2107         printf("Could not create JSON object: netconf-call-home\n");
2108         cJSON_Delete(configObject);
2109         return SR_ERR_OPERATION_FAILED;
2110     }
2111
2112     char *config_string = NULL;
2113
2114     config_string = cJSON_PrintUnformatted(configObject);
2115
2116     writeConfigFile(config_string);
2117
2118     if (config_string != NULL)
2119     {
2120         free(config_string);
2121         config_string = NULL;
2122     }
2123
2124     if (configObject != NULL)
2125     {
2126         cJSON_Delete(configObject);
2127     }
2128
2129     return SR_ERR_OK;
2130 }
2131
2132 int getIntFromString(char *string, int def_value)
2133 {
2134     int rc, value = def_value;
2135     if (string != NULL)
2136     {
2137         rc = sscanf(string, "%d", &value);
2138         if (rc != 1)
2139         {
2140             printf("Could not get the %s! Using the default 0...\n", string);
2141             value = def_value;
2142         }
2143     }
2144     return value;
2145 }
2146
2147 int     getSshConnectionsFromConfigJson(void)
2148 {
2149     char *stringConfig = readConfigFileInString();
2150
2151     if (stringConfig == NULL)
2152     {
2153         printf("Could not read JSON configuration file in string.");
2154         return 0;
2155     }
2156
2157     cJSON *jsonConfig = cJSON_Parse(stringConfig);
2158     if (jsonConfig == NULL)
2159     {
2160         free(stringConfig);
2161         const char *error_ptr = cJSON_GetErrorPtr();
2162         if (error_ptr != NULL)
2163         {
2164             fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2165         }
2166         return SR_ERR_OPERATION_FAILED;
2167     }
2168     //we don't need the string anymore
2169     free(stringConfig);
2170     stringConfig = NULL;
2171
2172     cJSON *sshConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ssh-connections");
2173     if (!cJSON_IsNumber(sshConnections))
2174     {
2175         printf("Configuration JSON is not as expected: ssh-connections is not an object");
2176         cJSON_Delete(jsonConfig);
2177         return SR_ERR_OPERATION_FAILED;
2178     }
2179
2180     int num_of_ssh = (int)(sshConnections->valuedouble);
2181
2182     cJSON_Delete(jsonConfig);
2183
2184     return num_of_ssh;
2185 }
2186
2187 int     getTlsConnectionsFromConfigJson(void)
2188 {
2189     char *stringConfig = readConfigFileInString();
2190
2191     if (stringConfig == NULL)
2192     {
2193         printf("Could not read JSON configuration file in string.");
2194         return 0;
2195     }
2196
2197     cJSON *jsonConfig = cJSON_Parse(stringConfig);
2198     if (jsonConfig == NULL)
2199     {
2200         free(stringConfig);
2201         const char *error_ptr = cJSON_GetErrorPtr();
2202         if (error_ptr != NULL)
2203         {
2204             fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2205         }
2206         return SR_ERR_OPERATION_FAILED;
2207     }
2208     //we don't need the string anymore
2209     free(stringConfig);
2210     stringConfig = NULL;
2211
2212     cJSON *tlsConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "tls-connections");
2213     if (!cJSON_IsNumber(tlsConnections))
2214     {
2215         printf("Configuration JSON is not as expected: ssh-connections is not an object");
2216         cJSON_Delete(jsonConfig);
2217         return SR_ERR_OPERATION_FAILED;
2218     }
2219
2220     int num_of_tls = (int)(tlsConnections->valuedouble);
2221
2222     cJSON_Delete(jsonConfig);
2223
2224     return num_of_tls;
2225 }