62ccd47fc0dcaed77383ad5073c072518d4d8e07
[sim/o1-interface.git] / ntsimulator / ntsim-ng / features / ves_pnf_registration / ves_pnf_registration.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 "ves_pnf_registration.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
23 #include "utils/rand_utils.h"
24 #include "utils/http_client.h"
25 #include "utils/nts_utils.h"
26 #include <stdio.h>
27 #include <assert.h>
28
29 #include "core/session.h"
30 #include "core/framework.h"
31
32 #define PNF_REGISTRATION_SCHEMA_XPATH               "/nts-network-function:simulation/network-function/ves/pnf-registration"
33
34 static int ves_pnf_sequence_number = 0;
35
36 static int ves_pnf_registration_send(sr_session_ctx_t *current_session, const char *nf_ip_address, int nf_port, bool is_tls);
37 static cJSON* ves_create_pnf_registration_fields(const char *nf_ip_address, int nf_port, bool is_tls);
38
39 int ves_pnf_registration_feature_start(sr_session_ctx_t *current_session) {
40     assert(current_session);
41
42     ves_pnf_sequence_number = 0;
43
44     sr_val_t *value = 0;
45     int rc = NTS_ERR_OK;
46     bool pnf_registration_enabled = false;
47     rc = sr_get_item(current_session, PNF_REGISTRATION_SCHEMA_XPATH, 0, &value);
48     if(rc == SR_ERR_OK) {
49         pnf_registration_enabled = value->data.bool_val;
50         sr_free_val(value);
51     }
52     else if(rc != SR_ERR_NOT_FOUND) {
53         log_error("sr_get_item failed");
54         return NTS_ERR_FAILED;
55     }
56
57     if(pnf_registration_enabled == false) {
58         log_message(2, "PNF registration is disabled\n");
59         return NTS_ERR_OK;
60     }
61
62     bool host_addressing_enabled = (nts_mount_point_addressing_method_get(current_session) == HOST_MAPPING);
63
64     char nf_ip_address[128];
65     int nf_port;
66
67     if(host_addressing_enabled) {
68         strcpy(nf_ip_address, framework_environment.host_ip);
69         nf_port = framework_environment.host_base_port;
70     }
71     else {
72         if(framework_environment.ip_v6_enabled) {
73             strcpy(nf_ip_address, framework_environment.ip_v6);
74         }
75         else {
76             strcpy(nf_ip_address, framework_environment.ip_v4);
77         } 
78         
79         nf_port = STANDARD_NETCONF_PORT;
80     }
81
82     int port = 0;
83     for(int i = 0; i < framework_environment.ssh_connections; ++port, ++i) {
84         rc = ves_pnf_registration_send(current_session, nf_ip_address, nf_port + port, false);
85         if(rc != NTS_ERR_OK) {
86             log_error("could not send pnfRegistration message for IP=%s and port=%d and protocol SSH", nf_ip_address, nf_port + port);
87             continue;
88         }
89     }
90
91     for(int i = 0; i < framework_environment.tls_connections; ++port, ++i) {
92         rc = ves_pnf_registration_send(current_session, nf_ip_address, nf_port + port, true);
93         if(rc != NTS_ERR_OK) {
94             log_error("could not send pnfRegistration message for IP=%s and port=%d and protocol TLS", nf_ip_address, nf_port + port);
95             continue;
96         }
97     }
98
99     return NTS_ERR_OK;
100 }
101
102
103 static int ves_pnf_registration_send(sr_session_ctx_t *current_session, const char *nf_ip_address, int nf_port, bool is_tls) {
104     assert(current_session);
105     assert(nf_ip_address);
106
107     cJSON *post_data_json = cJSON_CreateObject();
108     if(post_data_json == 0) {
109         log_error("could not create cJSON object");
110         return NTS_ERR_FAILED;
111     }
112
113     cJSON *event = cJSON_CreateObject();
114     if(event == 0) {
115         log_error("could not create cJSON object");
116         cJSON_Delete(post_data_json);
117         return NTS_ERR_FAILED;
118     }
119     
120     if(cJSON_AddItemToObject(post_data_json, "event", event) == 0) {
121         log_error("cJSON_AddItemToObject failed");
122         cJSON_Delete(post_data_json);
123         return NTS_ERR_FAILED;
124     }
125
126     char *hostname_string = framework_environment.hostname;
127     char source_name[100];
128         sprintf(source_name, "%s_%d", hostname_string, nf_port);
129
130     cJSON *common_event_header = ves_create_common_event_header("pnfRegistration", "EventType5G", source_name, "Normal", ves_pnf_sequence_number++);
131     if(common_event_header == 0) {
132         log_error("could not create cJSON object");
133         cJSON_Delete(post_data_json);
134         return NTS_ERR_FAILED;
135     }
136     
137     if(cJSON_AddItemToObject(event, "commonEventHeader", common_event_header) == 0) {
138         log_error("cJSON_AddItemToObject failed");
139         cJSON_Delete(post_data_json);
140         return NTS_ERR_FAILED;
141     }
142
143         cJSON *pnf_registration_fields = ves_create_pnf_registration_fields(nf_ip_address, nf_port, is_tls);
144     if(pnf_registration_fields == 0) {
145         log_error("could not create cJSON object");
146         cJSON_Delete(post_data_json);
147         return NTS_ERR_FAILED;
148     }
149     
150     if(cJSON_AddItemToObject(event, "pnfRegistrationFields", pnf_registration_fields) == 0) {
151         log_error("cJSON_AddItemToObject failed");
152         cJSON_Delete(post_data_json);
153         return NTS_ERR_FAILED;
154     }
155
156     char *post_data = cJSON_PrintUnformatted(post_data_json);
157     cJSON_Delete(post_data_json);
158     if(post_data == 0) {
159         log_error("cJSON_PrintUnformatted failed");
160         return NTS_ERR_FAILED;
161     }
162
163
164     ves_details_t *ves_details = ves_endpoint_details_get(current_session);
165     if(!ves_details) {
166         log_error("ves_endpoint_details_get failed");
167         free(post_data);
168         return NTS_ERR_FAILED;
169     }
170     
171     int rc = http_request(ves_details->url, ves_details->username, ves_details->password, "POST", post_data, 0, 0);
172     ves_details_free(ves_details);
173     free(post_data);
174     
175     if(rc != NTS_ERR_OK) {
176         log_error("http_request failed");
177         return NTS_ERR_FAILED;
178     }
179
180     return NTS_ERR_OK;
181 }
182
183 static cJSON* ves_create_pnf_registration_fields(const char *nf_ip_address, int nf_port, bool is_tls) {
184     assert(nf_ip_address);
185
186     //checkAL aici n-ar trebui niste valori "adevarate" ?
187
188     cJSON *pnf_registration_fields = cJSON_CreateObject();
189     if(pnf_registration_fields == 0) {
190         log_error("could not create JSON object");
191         return 0;
192     }
193
194     if(cJSON_AddStringToObject(pnf_registration_fields, "pnfRegistrationFieldsVersion", "2.0") == 0) {
195         log_error("cJSON_AddItemToObject failed");
196         cJSON_Delete(pnf_registration_fields);
197         return 0;
198     }
199
200     if(cJSON_AddStringToObject(pnf_registration_fields, "lastServiceDate", "2019-08-16") == 0) {
201         log_error("cJSON_AddItemToObject failed");
202         cJSON_Delete(pnf_registration_fields);
203         return 0;
204     }
205
206     char *mac_addr = rand_mac_address();
207     if(mac_addr == 0) {
208         log_error("rand_mac_address failed")
209         cJSON_Delete(pnf_registration_fields);
210         return 0;
211     }
212
213     if(cJSON_AddStringToObject(pnf_registration_fields, "macAddress", mac_addr) == 0) {
214         log_error("cJSON_AddItemToObject failed");
215         cJSON_Delete(pnf_registration_fields);
216         free(mac_addr);
217         return 0;
218     }
219     free(mac_addr);
220
221     if(cJSON_AddStringToObject(pnf_registration_fields, "manufactureDate", "2019-08-16") == 0) {
222         log_error("cJSON_AddItemToObject failed");
223         cJSON_Delete(pnf_registration_fields);
224         return 0;
225     }
226
227     if(cJSON_AddStringToObject(pnf_registration_fields, "modelNumber", "Simulated Device Melacon") == 0) {
228         log_error("cJSON_AddItemToObject failed");
229         cJSON_Delete(pnf_registration_fields);
230         return 0;
231     }
232
233     if(cJSON_AddStringToObject(pnf_registration_fields, "oamV4IpAddress", nf_ip_address) == 0) {
234         log_error("cJSON_AddItemToObject failed");
235         cJSON_Delete(pnf_registration_fields);
236         return 0;
237     }
238
239     if(cJSON_AddStringToObject(pnf_registration_fields, "oamV6IpAddress", "0:0:0:0:0:ffff:a0a:011") == 0) {
240         log_error("cJSON_AddItemToObject failed");
241         cJSON_Delete(pnf_registration_fields);
242         return 0;
243     }
244
245     char serial_number[512];
246     sprintf(serial_number, "%s-%s-%d-Simulated Device Melacon", framework_environment.hostname, nf_ip_address, nf_port);
247
248     if(cJSON_AddStringToObject(pnf_registration_fields, "serialNumber", serial_number) == 0) {
249         log_error("cJSON_AddItemToObject failed");
250         cJSON_Delete(pnf_registration_fields);
251         return 0;
252     }
253
254     if(cJSON_AddStringToObject(pnf_registration_fields, "softwareVersion", "2.3.5") == 0) {
255         log_error("cJSON_AddItemToObject failed");
256         cJSON_Delete(pnf_registration_fields);
257         return 0;
258     }
259
260     if(cJSON_AddStringToObject(pnf_registration_fields, "unitFamily", "Simulated Device") == 0) {
261         log_error("cJSON_AddItemToObject failed");
262         cJSON_Delete(pnf_registration_fields);
263         return 0;
264     }
265
266     if(cJSON_AddStringToObject(pnf_registration_fields, "unitType", "O-RAN-sim") == 0) {
267         log_error("cJSON_AddItemToObject failed");
268         cJSON_Delete(pnf_registration_fields);
269         return 0;
270     }
271
272     if(cJSON_AddStringToObject(pnf_registration_fields, "vendorName", "Melacon") == 0) {
273         log_error("cJSON_AddItemToObject failed");
274         cJSON_Delete(pnf_registration_fields);
275         return 0;
276     }
277
278     cJSON *additional_fields = cJSON_CreateObject();
279     if(additional_fields == 0) {
280         log_error("could not create JSON object");
281         cJSON_Delete(pnf_registration_fields);
282         return 0;
283     }
284     cJSON_AddItemToObject(pnf_registration_fields, "additionalFields", additional_fields);
285
286     char port_string[10];
287     sprintf(port_string, "%d", nf_port);
288
289     if(cJSON_AddStringToObject(additional_fields, "oamPort", port_string) == 0) {
290         log_error("cJSON_AddItemToObject failed");
291         cJSON_Delete(pnf_registration_fields);
292         return 0;
293     }
294
295     if(is_tls) {
296         //TLS specific configuration
297         if(cJSON_AddStringToObject(additional_fields, "protocol", "TLS") == 0) {
298             log_error("cJSON_AddItemToObject failed");
299             cJSON_Delete(pnf_registration_fields);
300             return 0;
301         }
302
303         if(cJSON_AddStringToObject(additional_fields, "username", "netconf") == 0) {
304             log_error("cJSON_AddItemToObject failed");
305             cJSON_Delete(pnf_registration_fields);
306             return 0;
307         }
308
309         if(cJSON_AddStringToObject(additional_fields, "keyId", KS_KEY_NAME) == 0) {
310             log_error("cJSON_AddItemToObject failed");
311             cJSON_Delete(pnf_registration_fields);
312             return 0;
313         }
314     }
315     else {
316         //SSH specific configuration
317         if(cJSON_AddStringToObject(additional_fields, "protocol", "SSH") == 0) {
318             log_error("cJSON_AddItemToObject failed");
319             cJSON_Delete(pnf_registration_fields);
320             return 0;
321         }
322
323         if(cJSON_AddStringToObject(additional_fields, "username", "netconf") == 0) {
324             log_error("cJSON_AddItemToObject failed");
325             cJSON_Delete(pnf_registration_fields);
326             return 0;
327         }
328
329         if(cJSON_AddStringToObject(additional_fields, "password", "netconf") == 0) {
330             log_error("cJSON_AddItemToObject failed");
331             cJSON_Delete(pnf_registration_fields);
332             return 0;
333         }
334     }
335
336     if(cJSON_AddStringToObject(additional_fields, "reconnectOnChangedSchema", "false") == 0) {
337         log_error("cJSON_AddItemToObject failed");
338         cJSON_Delete(pnf_registration_fields);
339         return 0;
340     }
341
342     if(cJSON_AddStringToObject(additional_fields, "sleep-factor", "1.5") == 0) {
343         log_error("cJSON_AddItemToObject failed");
344         cJSON_Delete(pnf_registration_fields);
345         return 0;
346     }
347
348     if(cJSON_AddStringToObject(additional_fields, "tcpOnly", "false") == 0) {
349         log_error("cJSON_AddItemToObject failed");
350         cJSON_Delete(pnf_registration_fields);
351         return 0;
352     }
353
354     if(cJSON_AddStringToObject(additional_fields, "connectionTimeout", "20000") == 0) {
355         log_error("cJSON_AddItemToObject failed");
356         cJSON_Delete(pnf_registration_fields);
357         return 0;
358     }
359
360     if(cJSON_AddStringToObject(additional_fields, "maxConnectionAttempts", "100") == 0) {
361         log_error("cJSON_AddItemToObject failed");
362         cJSON_Delete(pnf_registration_fields);
363         return 0;
364     }
365
366     if(cJSON_AddStringToObject(additional_fields, "betweenAttemptsTimeout", "2000") == 0) {
367         log_error("cJSON_AddItemToObject failed");
368         cJSON_Delete(pnf_registration_fields);
369         return 0;
370     }
371
372     if(cJSON_AddStringToObject(additional_fields, "keepaliveDelay", "120") == 0) {
373         log_error("cJSON_AddItemToObject failed");
374         cJSON_Delete(pnf_registration_fields);
375         return 0;
376     }
377
378     return pnf_registration_fields;
379 }