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