SIM-117: E2-interface fails trying to connect ricplt/e2 termintor
[sim/e2-interface.git] / e2sim / src / messagerouting / e2ap_message_handler.cpp
1 \r
2 \r
3 /*****************************************************************************\r
4 #                                                                            *\r
5 # Copyright 2020 AT&T Intellectual Property                                  *\r
6 # Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.      *\r
7 #                                                                            *\r
8 # Licensed under the Apache License, Version 2.0 (the "License");            *\r
9 # you may not use this file except in compliance with the License.           *\r
10 # You may obtain a copy of the License at                                    *\r
11 #                                                                            *\r
12 #      http://www.apache.org/licenses/LICENSE-2.0                            *\r
13 #                                                                            *\r
14 # Unless required by applicable law or agreed to in writing, software        *\r
15 # distributed under the License is distributed on an "AS IS" BASIS,          *\r
16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *\r
17 # See the License for the specific language governing permissions and        *\r
18 # limitations under the License.                                             *\r
19 #                                                                            *\r
20 ******************************************************************************/\r
21 #include "e2ap_message_handler.hpp"\r
22 \r
23 //#include <iostream>\r
24 //#include <vector>\r
25 #include <stdexcept>\r
26 #include <unistd.h>\r
27 \r
28 #include "encode_e2apv1.hpp"\r
29 \r
30 void e2ap_handle_sctp_data(int& socket_fd, sctp_buffer_t& data, bool xmlenc, E2Sim* e2sim) {\r
31   E2AP_PDU_t* pdu = (E2AP_PDU_t*)calloc(1, sizeof(E2AP_PDU));\r
32   ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, pdu);\r
33 \r
34   asn_transfer_syntax syntax;\r
35 \r
36   syntax = ATS_ALIGNED_BASIC_PER;\r
37   auto rval = asn_decode(nullptr, syntax, &asn_DEF_E2AP_PDU, (void**)&pdu, data.buffer, data.len);\r
38 \r
39   switch (rval.code) {\r
40     case RC_WMORE:\r
41     case RC_FAIL:\r
42       LOG_E("Failed to decode E2AP data from SCTP connection");\r
43       ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);\r
44       exit(1);\r
45     default:\r
46       break;\r
47   }\r
48 \r
49   int procedureCode = e2ap_asn1c_get_procedureCode(pdu);\r
50   int index = (int)pdu->present;\r
51 \r
52   LOG_D("Unpacked E2AP-PDU: index = %d, procedureCode = %d\n", index, procedureCode);\r
53 \r
54   switch (procedureCode) {\r
55     case ProcedureCode_id_E2setup:\r
56       LOG_I("Received a message of E2 setup procedure");\r
57       switch (index) {\r
58         case E2AP_PDU_PR_initiatingMessage:\r
59           e2ap_handle_E2SetupRequest(pdu, socket_fd);\r
60           LOG_I("Received SETUP-REQUEST");\r
61           break;\r
62 \r
63         case E2AP_PDU_PR_successfulOutcome:\r
64           LOG_I("Received SETUP-RESPONSE-SUCCESS");\r
65           break;\r
66 \r
67         case E2AP_PDU_PR_unsuccessfulOutcome:\r
68           LOG_I("Received SETUP-RESPONSE-FAILURE");\r
69           break;\r
70 \r
71         default:\r
72           LOG_E("Invalid message index=%d in E2AP-PDU", index);\r
73           break;\r
74       }\r
75       break;\r
76 \r
77     case ProcedureCode_id_Reset:  // reset = 7\r
78       LOG_I("Received a message of Reset procedure");\r
79       switch (index) {\r
80         case E2AP_PDU_PR_initiatingMessage:\r
81           LOG_I("Received RESET-REQUEST");\r
82           break;\r
83 \r
84         case E2AP_PDU_PR_successfulOutcome:\r
85           break;\r
86 \r
87         case E2AP_PDU_PR_unsuccessfulOutcome:\r
88           break;\r
89 \r
90         default:\r
91           LOG_E("Invalid message index=%d in E2AP-PDU", index);\r
92           break;\r
93       }\r
94       break;\r
95 \r
96     case ProcedureCode_id_RICsubscription:  // RIC SUBSCRIPTION = 201\r
97       LOG_I("Received a message of RIC subscription procedure");\r
98       switch (index) {\r
99         case E2AP_PDU_PR_initiatingMessage: {  // initiatingMessage\r
100           LOG_I("Received RIC-SUBSCRIPTION-REQUEST");\r
101           //          e2ap_handle_RICSubscriptionRequest(pdu, socket_fd);\r
102           long func_id = encoding::get_function_id_from_subscription(pdu);\r
103           fprintf(stderr, "Function Id of message is %d\n", func_id);\r
104           SubscriptionCallback cb;\r
105 \r
106           bool func_exists = true;\r
107 \r
108           try {\r
109             cb = e2sim->get_subscription_callback(func_id);\r
110           } catch (const std::out_of_range& e) {\r
111             func_exists = false;\r
112           }\r
113 \r
114           if (func_exists) {\r
115             fprintf(stderr, "Calling callback function\n");\r
116             cb(pdu);\r
117           } else {\r
118             fprintf(stderr, "Error: No RAN Function with this ID exists\n");\r
119           }\r
120           //      callback_kpm_subscription_request(pdu, socket_fd);\r
121 \r
122         } break;\r
123 \r
124         case E2AP_PDU_PR_successfulOutcome:\r
125           LOG_I("Received RIC-SUBSCRIPTION-RESPONSE");\r
126           break;\r
127 \r
128         case E2AP_PDU_PR_unsuccessfulOutcome:\r
129           LOG_I("Received RIC-SUBSCRIPTION-FAILURE");\r
130           break;\r
131 \r
132         default:\r
133           LOG_E("Invalid message index=%d in E2AP-PDU", index);\r
134           break;\r
135       }\r
136       break;\r
137 \r
138     case ProcedureCode_id_RICindication:  // 205\r
139       LOG_I("Received a message of RIC indication procedure");\r
140       switch (index) {\r
141         case E2AP_PDU_PR_initiatingMessage:  // initiatingMessage\r
142           LOG_I("Received RIC-INDICATION-REQUEST");\r
143           // e2ap_handle_RICSubscriptionRequest(pdu, socket_fd);\r
144           break;\r
145         case E2AP_PDU_PR_successfulOutcome:\r
146           LOG_I("Received RIC-INDICATION-RESPONSE");\r
147           break;\r
148 \r
149         case E2AP_PDU_PR_unsuccessfulOutcome:\r
150           LOG_I("Received RIC-INDICATION-FAILURE");\r
151           break;\r
152 \r
153         default:\r
154           LOG_E("Invalid message index=%d in E2AP-PDU %d", index, (int)ProcedureCode_id_RICindication);\r
155           break;\r
156       }\r
157       break;\r
158 \r
159     case ProcedureCode_id_RICserviceQuery:\r
160       LOG_I("Received a message of RIC service query procedure");\r
161       switch (index) {\r
162         case E2AP_PDU_PR_initiatingMessage:\r
163           LOG_I("Received RIC-Service-Query")\r
164           e2ap_handle_E2SeviceRequest(pdu, socket_fd, e2sim);\r
165           break;\r
166 \r
167         default:\r
168           LOG_E("Invalid message index=%d in E2AP-PDU %d", index, (int)ProcedureCode_id_RICserviceQuery);\r
169           break;\r
170       }\r
171       break;\r
172 \r
173     case ProcedureCode_id_E2nodeConfigurationUpdate:\r
174       LOG_I("Received a message of E2 node configuration update procedure");\r
175       switch (index) {\r
176         case E2AP_PDU_PR_successfulOutcome:\r
177           LOG_I("Received E2nodeConfigurationUpdate")\r
178           break;\r
179 \r
180         default:\r
181           LOG_E("Invalid message index=%d in E2AP-PDU %d", index, (int)ProcedureCode_id_E2nodeConfigurationUpdate);\r
182           break;\r
183       }\r
184       break;\r
185 \r
186     case ProcedureCode_id_RICserviceUpdate:\r
187       LOG_I("Received a message of RIC service update procedure");\r
188       switch (index) {\r
189         case E2AP_PDU_PR_successfulOutcome:\r
190           LOG_I("Received RIC-SERVICE-UPDATE-SUCCESS")\r
191           break;\r
192 \r
193         case E2AP_PDU_PR_unsuccessfulOutcome:\r
194           LOG_I("Received RIC-SERVICE-UPDATE-FAILURE")\r
195           break;\r
196 \r
197         default:\r
198           LOG_E("Invalid message index=%d in E2AP-PDU %d", index, (int)ProcedureCode_id_RICserviceUpdate);\r
199           break;\r
200       }\r
201       break;\r
202 \r
203     default:\r
204       LOG_E("No available handler for procedureCode=%d", procedureCode);\r
205       break;\r
206   }\r
207   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);\r
208 }\r
209 \r
210 void e2ap_handle_E2SeviceRequest(E2AP_PDU_t* pdu, int& socket_fd, E2Sim* e2sim) {\r
211   auto buffer_size = MAX_SCTP_BUFFER;\r
212   unsigned char buffer[MAX_SCTP_BUFFER];\r
213   E2AP_PDU_t* res_pdu = (E2AP_PDU_t*)calloc(1, sizeof(E2AP_PDU));\r
214 \r
215   // prepare ran function defination\r
216   std::vector<encoding::ran_func_info> all_funcs;\r
217 \r
218   // Loop through RAN function definitions that are registered\r
219 \r
220   for (std::pair<long, OCTET_STRING_t*> elem : e2sim->getRegistered_ran_functions()) {\r
221     printf("looping through ran func\n");\r
222     encoding::ran_func_info next_func;\r
223 \r
224     next_func.ranFunctionId = elem.first;\r
225     next_func.ranFunctionDesc = elem.second;\r
226     next_func.ranFunctionRev = (long)3;\r
227     all_funcs.push_back(next_func);\r
228   }\r
229 \r
230   printf("about to call service update encode\n");\r
231 \r
232   encoding::generate_e2apv1_service_update(res_pdu, all_funcs);\r
233 \r
234   LOG_D("Created E2-SERVICE-UPDATE");\r
235 \r
236   e2ap_asn1c_print_pdu(res_pdu);\r
237 \r
238   sctp_buffer_t data;\r
239 \r
240   char error_buf[300] = {\r
241       0,\r
242   };\r
243   size_t errlen = 0;\r
244 \r
245   asn_check_constraints(&asn_DEF_E2AP_PDU, res_pdu, error_buf, &errlen);\r
246   printf("error length %d\n", errlen);\r
247   printf("error buf %s\n", error_buf);\r
248 \r
249   auto er = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, res_pdu, buffer, buffer_size);\r
250   \r
251   if (er.encoded == -1) {\r
252     LOG_E("Failed to serialize message. Detail: %s.\n", asn_DEF_E2AP_PDU.name);\r
253     exit(1);\r
254   } else if (er.encoded > buffer_size) {\r
255     LOG_E("Buffer of size %zu is too small for %s, need %zu\n", buffer_size, asn_DEF_E2AP_PDU.name, er.encoded);\r
256     exit(1);\r
257   }\r
258 \r
259   data.len = er.encoded;\r
260 \r
261   memcpy(data.buffer, buffer, er.encoded);\r
262 \r
263   // send response data over sctp\r
264   if (sctp_send_data(socket_fd, data) > 0) {\r
265     LOG_I("Sent E2-SERVICE-UPDATE");\r
266   } else {\r
267     LOG_E("Unable to send E2-SERVICE-UPDATE to peer");\r
268   }\r
269 }\r
270 \r
271 void e2ap_send_e2nodeConfigUpdate(int& socket_fd) {\r
272   auto buffer_size = MAX_SCTP_BUFFER;\r
273   unsigned char buffer[MAX_SCTP_BUFFER];\r
274   E2AP_PDU_t* pdu = (E2AP_PDU_t*)calloc(1, sizeof(E2AP_PDU));\r
275 \r
276   LOG_I("Generating E2 node configure update");\r
277 \r
278   encoding::generate_e2apv2_config_update(pdu);\r
279 \r
280   e2ap_asn1c_print_pdu(pdu);\r
281 \r
282   sctp_buffer_t data;\r
283 \r
284   char error_buf[300] = {\r
285       0,\r
286   };\r
287   size_t errlen = 0;\r
288 \r
289   asn_check_constraints(&asn_DEF_E2AP_PDU, pdu, error_buf, &errlen);\r
290 \r
291   auto er = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, pdu, buffer, buffer_size);\r
292 \r
293   if (er.encoded == -1) {\r
294     LOG_E("Failed to serialize message. Detail: %s.\n", asn_DEF_E2AP_PDU.name);\r
295     exit(1);\r
296   } else if (er.encoded > buffer_size) {\r
297     LOG_E("Buffer of size %zu is too small for %s, need %zu\n", buffer_size, asn_DEF_E2AP_PDU.name, er.encoded);\r
298     exit(1);\r
299   }\r
300 \r
301   data.len = er.encoded;\r
302 \r
303   memcpy(data.buffer, buffer, er.encoded);\r
304 \r
305   // send response data over sctp\r
306   if (sctp_send_data(socket_fd, data) > 0) {\r
307     LOG_I("Sent E2nodeConfigUpdate");\r
308   } else {\r
309     LOG_E("[SCTP] Unable to send E2nodeConfigUpdate to peer");\r
310   }\r
311 }\r
312 \r
313 void e2ap_handle_E2SetupRequest(E2AP_PDU_t* pdu, int& socket_fd) {\r
314   E2AP_PDU_t* res_pdu = (E2AP_PDU_t*)calloc(1, sizeof(E2AP_PDU));\r
315   encoding::generate_e2apv1_setup_response(res_pdu);\r
316 \r
317   LOG_D("Created E2-SETUP-RESPONSE");\r
318 \r
319   e2ap_asn1c_print_pdu(res_pdu);\r
320 \r
321   auto buffer_size = MAX_SCTP_BUFFER;\r
322   unsigned char buffer[MAX_SCTP_BUFFER];\r
323 \r
324   sctp_buffer_t data;\r
325   auto er = asn_encode_to_buffer(nullptr, ATS_BASIC_XER, &asn_DEF_E2AP_PDU, res_pdu, buffer, buffer_size);\r
326 \r
327   if (er.encoded == -1) {\r
328     LOG_E("Failed to serialize message. Detail: %s.\n", asn_DEF_E2AP_PDU.name);\r
329     exit(1);\r
330   } else if (er.encoded > buffer_size) {\r
331     LOG_E("Buffer of size %zu is too small for %s, need %zu\n", buffer_size, asn_DEF_E2AP_PDU.name, er.encoded);\r
332     exit(1);\r
333   }\r
334 \r
335   data.len = er.encoded;\r
336   \r
337   memcpy(data.buffer, buffer, er.encoded);\r
338 \r
339   // send response data over sctp\r
340   if (sctp_send_data(socket_fd, data) > 0) {\r
341     LOG_I("Sent E2-SETUP-RESPONSE");\r
342   } else {\r
343     LOG_E("[SCTP] Unable to send E2-SETUP-RESPONSE to peer");\r
344   }\r
345 \r
346   sleep(5);\r
347 \r
348   // Sending Subscription Request\r
349 \r
350   E2AP_PDU_t* pdu_sub = (E2AP_PDU_t*)calloc(1, sizeof(E2AP_PDU));\r
351 \r
352   encoding::generate_e2apv1_subscription_request(pdu_sub);\r
353 \r
354   xer_fprint(stderr, &asn_DEF_E2AP_PDU, pdu_sub);\r
355 \r
356   auto buffer_size2 = MAX_SCTP_BUFFER;\r
357   unsigned char buffer2[MAX_SCTP_BUFFER];\r
358 \r
359   sctp_buffer_t data2;\r
360 \r
361   auto er2 = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, pdu_sub, buffer2, buffer_size2);\r
362 \r
363   if (er2.encoded == -1) {\r
364     LOG_E("Failed to serialize message. Detail: %s.\n", asn_DEF_E2AP_PDU.name);\r
365     exit(1);\r
366   } else if (er2.encoded > buffer_size2) {\r
367     LOG_E("Buffer of size %zu is too small for %s, need %zu\n", buffer_size2, asn_DEF_E2AP_PDU.name, er2.encoded);\r
368     exit(1);\r
369   }\r
370 \r
371   data2.len = er2.encoded;\r
372   memcpy(data2.buffer, buffer2, er2.encoded);\r
373 \r
374   if (sctp_send_data(socket_fd, data2) > 0) {\r
375     LOG_I("Sent E2-SUBSCRIPTION-REQUEST");\r
376   } else {\r
377     LOG_E("[SCTP] Unable to send E2-SUBSCRIPTION-REQUEST to peer");\r
378   }\r
379 }\r
380 \r
381 /*\r
382 void e2ap_handle_RICSubscriptionRequest(E2AP_PDU_t* pdu, int &socket_fd)\r
383 {\r
384 \r
385   //Send back Subscription Success Response\r
386 \r
387   E2AP_PDU_t* pdu_resp = (E2AP_PDU_t*)calloc(1,sizeof(E2AP_PDU));\r
388 \r
389   generate_e2apv1_subscription_response(pdu_resp, pdu);\r
390 \r
391   fprintf(stderr, "Subscription Response\n");\r
392 \r
393   xer_fprint(stderr, &asn_DEF_E2AP_PDU, pdu_resp);\r
394 \r
395   auto buffer_size2 = MAX_SCTP_BUFFER;\r
396   unsigned char buffer2[MAX_SCTP_BUFFER];\r
397 \r
398   sctp_buffer_t data2;\r
399 \r
400   auto er2 = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, pdu_resp, buffer2, buffer_size2);\r
401   data2.len = er2.encoded;\r
402 \r
403   fprintf(stderr, "er encded is %d\n", er2.encoded);\r
404 \r
405   memcpy(data2.buffer, buffer2, er2.encoded);\r
406 \r
407   if(sctp_send_data(socket_fd, data2) > 0) {\r
408     LOG_I("Sent RIC-SUBSCRIPTION-RESPONSE");\r
409   } else {\r
410     LOG_E("[SCTP] Unable to send RIC-SUBSCRIPTION-RESPONSE to peer");\r
411   }\r
412 \r
413 \r
414   //Send back an Indication\r
415 \r
416   E2AP_PDU_t* pdu_ind = (E2AP_PDU_t*)calloc(1,sizeof(E2AP_PDU));\r
417 \r
418   generate_e2apv1_indication_request(pdu_ind);\r
419 \r
420   xer_fprint(stderr, &asn_DEF_E2AP_PDU, pdu_ind);\r
421 \r
422   auto buffer_size = MAX_SCTP_BUFFER;\r
423   unsigned char buffer[MAX_SCTP_BUFFER];\r
424 \r
425   sctp_buffer_t data;\r
426 \r
427   auto er = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, pdu_ind, buffer, buffer_size);\r
428   data.len = er.encoded;\r
429 \r
430   fprintf(stderr, "er encded is %d\n", er.encoded);\r
431 \r
432   memcpy(data.buffer, buffer, er.encoded);\r
433 \r
434   if(sctp_send_data(socket_fd, data) > 0) {\r
435     LOG_I("Sent RIC-INDICATION-REQUEST");\r
436   } else {\r
437     LOG_E("[SCTP] Unable to send RIC-INDICATION-REQUEST to peer");\r
438   }\r
439 \r
440 }\r
441 */\r