e95deed353b18e6a18d791d8b2e4503abb529023
[sim/o1-interface.git] / ntsimulator / ntsim-ng / core / faults / faults_ves.c
1 /*************************************************************************
2 *
3 * Copyright 2020 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 #define _GNU_SOURCE
19
20 #include "faults.h"
21 #include "utils/log_utils.h"
22 #include "utils/rand_utils.h"
23 #include "utils/nts_utils.h"
24 #include "utils/sys_utils.h"
25 #include "utils/http_client.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <assert.h>
29
30 #include "core/framework.h"
31 #include <cjson/cJSON.h>
32
33 static uint32_t *fault_ves_sequence_number = 0;
34
35 static cJSON *ves_create_fault_fields(const char *alarm_condition, const char *alarm_object, const char *severity, const char *date_time, const char *specific_problem);
36 static int ves_message_send_internal(sr_session_ctx_t *session, const char *condition, const char *object, const char *severity, const char *date_time, const char *specific_problem, int port, uint32_t *seq_id);
37
38 int faults_ves_init(void) {
39     fault_ves_sequence_number = (uint32_t *)malloc(sizeof(uint32_t) * (framework_environment.ssh_connections + framework_environment.tls_connections));
40     if(fault_ves_sequence_number == 0) {
41         log_error("malloc failed"); 
42         return NTS_ERR_FAILED; 
43     }
44
45     for(int i = 0; i < (framework_environment.ssh_connections + framework_environment.tls_connections); i++) {
46         fault_ves_sequence_number[i] = 0;
47     }
48
49     return NTS_ERR_OK;
50 }
51
52 void faults_ves_free(void) {
53     free(fault_ves_sequence_number);
54     fault_ves_sequence_number = 0;
55 }
56
57 int faults_ves_message_send(sr_session_ctx_t *session, const char *condition, const char *object, const char *severity, const char *date_time, const char *specific_problem) {
58     assert(condition);
59     assert(object);
60     assert(severity);
61     assert(date_time);
62     assert(specific_problem);
63
64     nts_mount_point_addressing_method_t mp = nts_mount_point_addressing_method_get(session);
65     if(mp == UNKNOWN_MAPPING) {
66         log_error("mount-point-addressing-method failed");
67         return NTS_ERR_FAILED;
68     }
69
70     int base_port = STANDARD_NETCONF_PORT;
71     if(mp == HOST_MAPPING) {
72         base_port = framework_environment.host_base_port;
73     }
74
75     for(int port = base_port; port < base_port + (framework_environment.ssh_connections + framework_environment.tls_connections); port++) {
76         uint32_t *seq_id = &fault_ves_sequence_number[port - base_port];
77         int rc = ves_message_send_internal(session, condition, object, severity, date_time, specific_problem, port, seq_id);
78         if(rc != NTS_ERR_OK) {
79             log_error("ves_message_send_internal failed");
80         }
81     }
82
83     return NTS_ERR_OK;
84 }
85
86 static cJSON *ves_create_fault_fields(const char *alarm_condition, const char *alarm_object, const char *severity, const char *date_time, const char *specific_problem) {
87     assert(alarm_condition);
88     assert(alarm_object);
89     assert(severity);
90     assert(date_time);
91     assert(specific_problem);
92     
93     cJSON *faultFields = cJSON_CreateObject();
94     if(faultFields == 0) {
95         log_error("could not create JSON object: faultFields");
96         return 0;
97     }
98
99     if(cJSON_AddStringToObject(faultFields, "faultFieldsVersion", "4.0") == 0) {
100         log_error("could not create JSON object: faultFieldsVersion");
101         cJSON_Delete(faultFields);
102         return 0;
103     }
104
105     if(cJSON_AddStringToObject(faultFields, "alarmCondition", alarm_condition) == 0) {
106         log_error("could not create JSON object: alarmCondition");
107         cJSON_Delete(faultFields);
108         return 0;
109     }
110
111     if(cJSON_AddStringToObject(faultFields, "alarmInterfaceA", alarm_object) == 0) {
112         log_error("could not create JSON object: alarmInterfaceA");
113         cJSON_Delete(faultFields);
114         return 0;
115     }
116
117     if(cJSON_AddStringToObject(faultFields, "eventSourceType", "O_RAN_COMPONENT") == 0) {
118         log_error("could not create JSON object: eventSourceType");
119         cJSON_Delete(faultFields);
120         return 0;
121     }
122
123     if(cJSON_AddStringToObject(faultFields, "specificProblem", specific_problem) == 0) {
124         log_error("could not create JSON object: specificProblem");
125         cJSON_Delete(faultFields);
126         return 0;
127     }
128
129     if(cJSON_AddStringToObject(faultFields, "eventSeverity", severity) == 0) {
130         log_error("could not create JSON object: eventSeverity");
131         cJSON_Delete(faultFields);
132         return 0;
133     }
134
135     if(cJSON_AddStringToObject(faultFields, "vfStatus", "Active") == 0) {
136         log_error("could not create JSON object: vfStatus");
137         cJSON_Delete(faultFields);
138         return 0;
139     }
140
141     cJSON *alarmAdditionalInformation = cJSON_CreateObject();
142     if(alarmAdditionalInformation == 0) {
143         log_error("could not create JSON object: alarmAdditionalInformation");
144         cJSON_Delete(faultFields);
145         return 0;
146     }
147     cJSON_AddItemToObject(faultFields, "alarmAdditionalInformation", alarmAdditionalInformation);
148
149     if(cJSON_AddStringToObject(alarmAdditionalInformation, "eventTime", date_time) == 0) {
150         log_error("could not create JSON object: eventTime");
151         cJSON_Delete(faultFields);
152         return 0;
153     }
154
155     if(cJSON_AddStringToObject(alarmAdditionalInformation, "equipType", "O-RAN-sim") == 0) {
156         log_error("could not create JSON object: equipType");
157         cJSON_Delete(faultFields);
158         return 0;
159     }
160
161     if(cJSON_AddStringToObject(alarmAdditionalInformation, "vendor", "Melacon") == 0) {
162         log_error("could not create JSON object: vendor");
163         cJSON_Delete(faultFields);
164         return 0;
165     }
166
167     if(cJSON_AddStringToObject(alarmAdditionalInformation, "model", "Simulated Device") == 0) {
168         log_error("could not create JSON object: model");
169         cJSON_Delete(faultFields);
170         return 0;
171     }
172
173     return faultFields;
174 }
175
176 static int ves_message_send_internal(sr_session_ctx_t *session, const char *condition, const char *object, const char *severity, const char *date_time, const char *specific_problem, int port, uint32_t *seq_id) {
177     assert(condition);
178     assert(object);
179     assert(severity);
180     assert(date_time);
181     assert(specific_problem);
182
183     char *hostname_string = framework_environment.hostname;
184     cJSON *post_data_json = cJSON_CreateObject();
185     if(post_data_json == 0) {
186         log_error("cJSON_CreateObject failed");
187         return NTS_ERR_FAILED;
188     }
189
190     cJSON *event = cJSON_CreateObject();
191     if(event == 0) {
192         log_error("cJSON_CreateObject failed");
193         cJSON_Delete(post_data_json);
194         return NTS_ERR_FAILED;
195     }
196     cJSON_AddItemToObject(post_data_json, "event", event);
197
198     char *source_name = 0;
199     asprintf(&source_name, "%s-%d", hostname_string, port);
200     cJSON *common_event_header = ves_create_common_event_header("fault", "O_RAN_COMPONENT_Alarms", source_name, "Low", (*seq_id)++);
201     free(source_name);
202
203     if(common_event_header == 0) {
204         log_error("ves_create_common_event_header failed");
205         cJSON_Delete(post_data_json);
206         return NTS_ERR_FAILED;
207     }
208     cJSON_AddItemToObject(event, "commonEventHeader", common_event_header);
209
210     cJSON *fault_fields = ves_create_fault_fields(condition, object, severity, date_time, specific_problem);
211     if(fault_fields == 0) {
212         log_error("ves_create_fault_fields failed");
213         cJSON_Delete(post_data_json);
214         return NTS_ERR_FAILED;
215     }
216     cJSON_AddItemToObject(event, "faultFields", fault_fields);
217
218     char *post_data = cJSON_PrintUnformatted(post_data_json);
219     ves_details_t *ves_details = ves_endpoint_details_get(session);
220     if(!ves_details) {
221         log_error("ves_endpoint_details_get failed");
222         return NTS_ERR_FAILED;
223     }
224     
225     int rc = http_request(ves_details->url, ves_details->username, ves_details->password, "POST", post_data, 0, 0);
226     ves_details_free(ves_details);
227     cJSON_Delete(post_data_json);
228     free(post_data);
229     
230     if(rc != NTS_ERR_OK) {
231         log_error("http_request failed");
232         return NTS_ERR_FAILED;
233     }
234
235     return NTS_ERR_OK;
236 }