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