Add VES stndDefined PM and subscription for O-DU.
[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.settings.ssh_connections + framework_environment.settings.tls_connections));
40     if(fault_ves_sequence_number == 0) {
41         log_error("malloc failed\n");
42         return NTS_ERR_FAILED; 
43     }
44
45     for(int i = 0; i < (framework_environment.settings.ssh_connections + framework_environment.settings.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     int sequence_index = 0;
65     int ssh_base_port = 0;
66     int tls_base_port = 0;
67     nts_mount_point_addressing_method_t mp = nts_mount_point_addressing_method_get(session);
68     if(mp == UNKNOWN_MAPPING) {
69         log_error("mount-point-addressing-method failed\n");
70         return NTS_ERR_FAILED;
71     }
72     else if(mp == DOCKER_MAPPING) {
73         ssh_base_port = STANDARD_NETCONF_PORT;
74         tls_base_port = ssh_base_port + framework_environment.settings.ssh_connections;
75     }
76     else {
77         ssh_base_port = framework_environment.host.ssh_base_port;
78         tls_base_port = framework_environment.host.tls_base_port;       
79     }
80
81     if((framework_environment.settings.ssh_connections + framework_environment.settings.tls_connections) > 1) {
82         for(int port = ssh_base_port; port < ssh_base_port + framework_environment.settings.ssh_connections; port++) {
83             uint32_t *seq_id = &fault_ves_sequence_number[sequence_index++];
84             int rc = ves_message_send_internal(session, condition, object, severity, date_time, specific_problem, port, seq_id);
85             if(rc != NTS_ERR_OK) {
86                 log_error("ves_message_send_internal failed\n");
87             }
88         }
89
90         for(int port = tls_base_port; port < tls_base_port + framework_environment.settings.tls_connections; port++) {
91             uint32_t *seq_id = &fault_ves_sequence_number[sequence_index++];
92             int rc = ves_message_send_internal(session, condition, object, severity, date_time, specific_problem, port, seq_id);
93             if(rc != NTS_ERR_OK) {
94                 log_error("ves_message_send_internal failed\n");
95             }
96         }
97     }
98     else {
99         uint32_t *seq_id = &fault_ves_sequence_number[sequence_index++];
100         int rc = ves_message_send_internal(session, condition, object, severity, date_time, specific_problem, 0, seq_id);
101         if(rc != NTS_ERR_OK) {
102             log_error("ves_message_send_internal failed\n");
103         }
104     }
105
106     return NTS_ERR_OK;
107 }
108
109 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) {
110     assert(alarm_condition);
111     assert(alarm_object);
112     assert(severity);
113     assert(date_time);
114     assert(specific_problem);
115     
116     cJSON *faultFields = cJSON_CreateObject();
117     if(faultFields == 0) {
118         log_error("could not create JSON object: faultFields\n");
119         return 0;
120     }
121
122     if(cJSON_AddStringToObject(faultFields, "faultFieldsVersion", "4.0") == 0) {
123         log_error("could not create JSON object: faultFieldsVersion\n");
124         cJSON_Delete(faultFields);
125         return 0;
126     }
127
128     if(cJSON_AddStringToObject(faultFields, "alarmCondition", alarm_condition) == 0) {
129         log_error("could not create JSON object: alarmCondition\n");
130         cJSON_Delete(faultFields);
131         return 0;
132     }
133
134     if(cJSON_AddStringToObject(faultFields, "alarmInterfaceA", alarm_object) == 0) {
135         log_error("could not create JSON object: alarmInterfaceA\n");
136         cJSON_Delete(faultFields);
137         return 0;
138     }
139
140     if(cJSON_AddStringToObject(faultFields, "eventSourceType", "O_RAN_COMPONENT") == 0) {
141         log_error("could not create JSON object: eventSourceType\n");
142         cJSON_Delete(faultFields);
143         return 0;
144     }
145
146     if(cJSON_AddStringToObject(faultFields, "specificProblem", specific_problem) == 0) {
147         log_error("could not create JSON object: specificProblem\n");
148         cJSON_Delete(faultFields);
149         return 0;
150     }
151
152     if(cJSON_AddStringToObject(faultFields, "eventSeverity", severity) == 0) {
153         log_error("could not create JSON object: eventSeverity\n");
154         cJSON_Delete(faultFields);
155         return 0;
156     }
157
158     if(cJSON_AddStringToObject(faultFields, "vfStatus", "Active") == 0) {
159         log_error("could not create JSON object: vfStatus\n");
160         cJSON_Delete(faultFields);
161         return 0;
162     }
163
164     cJSON *alarmAdditionalInformation = cJSON_CreateObject();
165     if(alarmAdditionalInformation == 0) {
166         log_error("could not create JSON object: alarmAdditionalInformation\n");
167         cJSON_Delete(faultFields);
168         return 0;
169     }
170     cJSON_AddItemToObject(faultFields, "alarmAdditionalInformation", alarmAdditionalInformation);
171
172     if(cJSON_AddStringToObject(alarmAdditionalInformation, "eventTime", date_time) == 0) {
173         log_error("could not create JSON object: eventTime\n");
174         cJSON_Delete(faultFields);
175         return 0;
176     }
177
178     if(cJSON_AddStringToObject(alarmAdditionalInformation, "equipType", "O-RAN-sim") == 0) {
179         log_error("could not create JSON object: equipType\n");
180         cJSON_Delete(faultFields);
181         return 0;
182     }
183
184     if(cJSON_AddStringToObject(alarmAdditionalInformation, "vendor", "Melacon") == 0) {
185         log_error("could not create JSON object: vendor\n");
186         cJSON_Delete(faultFields);
187         return 0;
188     }
189
190     if(cJSON_AddStringToObject(alarmAdditionalInformation, "model", "Simulated Device") == 0) {
191         log_error("could not create JSON object: model\n");
192         cJSON_Delete(faultFields);
193         return 0;
194     }
195
196     return faultFields;
197 }
198
199 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) {
200     assert(condition);
201     assert(object);
202     assert(severity);
203     assert(date_time);
204     assert(specific_problem);
205
206     char *hostname_string = framework_environment.settings.hostname;
207     cJSON *post_data_json = cJSON_CreateObject();
208     if(post_data_json == 0) {
209         log_error("cJSON_CreateObject failed\n");
210         return NTS_ERR_FAILED;
211     }
212
213     cJSON *event = cJSON_CreateObject();
214     if(event == 0) {
215         log_error("cJSON_CreateObject failed\n");
216         cJSON_Delete(post_data_json);
217         return NTS_ERR_FAILED;
218     }
219     cJSON_AddItemToObject(post_data_json, "event", event);
220
221     cJSON *common_event_header = ves_create_common_event_header("fault", "O_RAN_COMPONENT_Alarms", hostname_string, port, "Low", (*seq_id)++);
222     if(common_event_header == 0) {
223         log_error("ves_create_common_event_header failed\n");
224         cJSON_Delete(post_data_json);
225         return NTS_ERR_FAILED;
226     }
227     cJSON_AddItemToObject(event, "commonEventHeader", common_event_header);
228
229     cJSON *fault_fields = ves_create_fault_fields(condition, object, severity, date_time, specific_problem);
230     if(fault_fields == 0) {
231         log_error("ves_create_fault_fields failed\n");
232         cJSON_Delete(post_data_json);
233         return NTS_ERR_FAILED;
234     }
235     cJSON_AddItemToObject(event, "faultFields", fault_fields);
236
237     char *post_data = cJSON_PrintUnformatted(post_data_json);
238     ves_details_t *ves_details = ves_endpoint_details_get(session, 0);
239     if(!ves_details) {
240         log_error("ves_endpoint_details_get failed\n");
241         return NTS_ERR_FAILED;
242     }
243     
244     int rc = http_request(ves_details->url, ves_details->username, ves_details->password, "POST", post_data, 0, 0);
245     ves_details_free(ves_details);
246     cJSON_Delete(post_data_json);
247     free(post_data);
248     
249     if(rc != NTS_ERR_OK) {
250         log_error("http_request failed\n");
251         return NTS_ERR_FAILED;
252     }
253
254     return NTS_ERR_OK;
255 }