Adding Bouncer xapp and E2 Simulator code for RIC-Benchmarking
[it/test.git] / ric_benchmarking / e2-interface / e2sim / previous / src / E2AP / e2ap_message_handler.cpp
1 /*****************************************************************************
2 #                                                                            *
3 # Copyright 2019 AT&T Intellectual Property                                  *
4 # Copyright 2019 Nokia                                                       *
5 #                                                                            *
6 # Licensed under the Apache License, Version 2.0 (the "License");            *
7 # you may not use this file except in compliance with the License.           *
8 # You may obtain a copy of the License at                                    *
9 #                                                                            *
10 #      http://www.apache.org/licenses/LICENSE-2.0                            *
11 #                                                                            *
12 # Unless required by applicable law or agreed to in writing, software        *
13 # distributed under the License is distributed on an "AS IS" BASIS,          *
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
15 # See the License for the specific language governing permissions and        *
16 # limitations under the License.                                             *
17 #                                                                            *
18 ******************************************************************************/
19 #include "e2ap_message_handler.hpp"
20 #include <unistd.h>
21
22 void e2ap_handle_sctp_data(int &socket_fd, sctp_buffer_t &data)
23 {
24   //decode the data into E2AP-PDU
25   E2AP_PDU_t* pdu = new E2AP_PDU_t();
26
27   e2ap_asn1c_decode_pdu(pdu, data.buffer, data.len);
28
29   e2ap_asn1c_print_pdu(pdu);
30
31   int procedureCode = e2ap_asn1c_get_procedureCode(pdu);
32   int index = (int)pdu->present;
33
34   LOG_D("[E2AP] Unpacked E2AP-PDU: index = %d, procedureCode = %d\n",
35                             index, procedureCode);
36
37   switch(procedureCode)
38   {
39     case ProcedureCode_id_x2Setup: //X2Setup = 6
40       switch(index)
41       {
42         case E2AP_PDU_PR_initiatingMessage: //initiatingMessage
43           LOG_I("[E2AP] Received X2-SETUP-REQUEST");
44           e2ap_handle_X2SetupRequest(pdu, socket_fd);
45           break;
46
47         case E2AP_PDU_PR_successfulOutcome: //successfulOutcome
48           LOG_I("[E2AP] Received X2-SETUP-RESPONSE");
49           e2ap_handle_X2SetupResponse(pdu, socket_fd);
50           break;
51
52         case E2AP_PDU_PR_unsuccessfulOutcome:
53           break;
54
55         default:
56           LOG_E("[E2AP] Invalid message index=%d in E2AP-PDU", index);
57           break;
58       }
59       break;
60
61     case ProcedureCode_id_endcX2Setup: //ENDCX2Setup = 36
62       switch(index)
63       {
64         case E2AP_PDU_PR_initiatingMessage: //initiatingMessage
65           LOG_I("[E2AP] Received ENDC-X2-SETUP-REQUEST");
66           e2ap_handle_ENDCX2SetupRequest(pdu, socket_fd);
67           break;
68
69         case E2AP_PDU_PR_successfulOutcome: //successfulOutcome
70           LOG_I("[E2AP] Received ENDC-X2-SETUP-RESPONSE");
71           //no handler yet
72           break;
73
74         case E2AP_PDU_PR_unsuccessfulOutcome:
75           LOG_I("[E2AP] Received ENDC-X2-SETUP-FAILURE");
76           //no handler yet
77           break;
78
79         default:
80           LOG_E("[E2AP] Invalid message index=%d in E2AP-PDU", index);
81           break;
82       }
83       break;
84
85     case ProcedureCode_id_reset: //reset = 7
86       switch(index)
87       {
88         case E2AP_PDU_PR_initiatingMessage:
89           LOG_I("[E2AP] Received RESET-REQUEST");
90           break;
91
92         case E2AP_PDU_PR_successfulOutcome:
93           break;
94
95         case E2AP_PDU_PR_unsuccessfulOutcome:
96           break;
97
98         default:
99           LOG_E("[E2AP] Invalid message index=%d in E2AP-PDU", index);
100           break;
101       }
102       break;
103
104     case ProcedureCode_id_ricSubscription: //RIC SUBSCRIPTION = 201
105       switch(index)
106       {
107         case E2AP_PDU_PR_initiatingMessage: //initiatingMessage
108           LOG_I("[E2AP] Received RIC-SUBSCRIPTION-REQUEST");
109           //e2ap_handle_RICSubscriptionRequest(pdu, socket_fd);
110           e2ap_handle_RICSubscriptionRequest_securityDemo(pdu, socket_fd);
111           break;
112
113         case E2AP_PDU_PR_successfulOutcome:
114           LOG_I("[E2AP] Received RIC-SUBSCRIPTION-RESPONSE");
115           break;
116
117         case E2AP_PDU_PR_unsuccessfulOutcome:
118           LOG_I("[E2AP] Received RIC-SUBSCRIPTION-FAILURE");
119           break;
120
121         default:
122           LOG_E("[E2AP] Invalid message index=%d in E2AP-PDU", index);
123           break;
124       }
125       break;
126
127     case ProcedureCode_id_ricIndication: // 205
128       switch(index)
129       {
130         case E2AP_PDU_PR_initiatingMessage: //initiatingMessage
131           LOG_I("[E2AP] Received RIC-INDICATION");
132           // e2ap_handle_RICSubscriptionRequest(pdu, socket_fd);
133           break;
134
135         default:
136           LOG_E("[E2AP] Invalid message index=%d in E2AP-PDU %d", index,
137                                     (int)ProcedureCode_id_ricIndication);
138           break;
139       }
140       break;
141
142     case ProcedureCode_id_resourceStatusReportingInitiation: //9
143       switch(index)
144       {
145         case E2AP_PDU_PR_initiatingMessage: //initiatingMessage
146           LOG_I("[E2AP] Received RESOURCE-STATUS-REQUEST");
147           e2ap_handle_ResourceStatusRequest(pdu, socket_fd);
148           break;
149
150         case E2AP_PDU_PR_successfulOutcome: //successfulOutcome
151           LOG_I("[E2AP] Received RESOURCE-STATUS-RESPONSE");
152           break;
153
154         case E2AP_PDU_PR_unsuccessfulOutcome:
155           LOG_I("[E2AP] Received RESOURCE-STATUS-FAILURE");
156           break;
157
158         default:
159           LOG_E("[E2AP] Invalid message index=%d in E2AP-PDU %d", index,
160                     (int)ProcedureCode_id_resourceStatusReportingInitiation);
161           break;
162       }
163       break;
164
165     case ProcedureCode_id_resourceStatusReporting: // 10
166       switch(index)
167       {
168         case E2AP_PDU_PR_initiatingMessage: //initiatingMessage
169           LOG_I("[E2AP] Received RESOURCE-STATUS-UPDATE");
170           break;
171
172         default:
173           LOG_E("[E2AP] Unable to process message index=%d in E2AP-PDU %d", index,
174                     (int)ProcedureCode_id_resourceStatusReporting);
175           break;
176       }
177       break;
178
179     default:
180       LOG_E("[E2AP] No available handler for procedureCode=%d", procedureCode);
181       break;
182   }
183 }
184
185 /*
186 Simply send back X2SetupResponse
187 Todo: add more handling options (failure, duplicated request, etc.)
188 */
189 void e2ap_handle_X2SetupRequest(E2AP_PDU_t* pdu, int &socket_fd)
190 {
191   E2AP_PDU_t* res_pdu = e2ap_xml_to_pdu("E2AP_X2SetupResponse.xml");
192
193   LOG_D("[E2AP] Created X2-SETUP-RESPONSE");
194
195   e2ap_asn1c_print_pdu(res_pdu);
196
197   uint8_t       *buf;
198   sctp_buffer_t data;
199
200   data.len = e2ap_asn1c_encode_pdu(res_pdu, &buf);
201   memcpy(data.buffer, buf, min(data.len, MAX_SCTP_BUFFER));
202
203   //send response data over sctp
204   if(sctp_send_data(socket_fd, data) > 0) {
205     LOG_I("[SCTP] Sent X2-SETUP-RESPONSE");
206   } else {
207     LOG_E("[SCTP] Unable to send X2-SETUP-RESPONSE to peer");
208   }
209 }
210
211 void e2ap_handle_X2SetupResponse(E2AP_PDU_t* pdu, int &socket_fd)
212 {
213   E2AP_PDU_t* req_pdu = e2ap_xml_to_pdu("E2AP_ResourceStatusRequest.xml");
214   // E2AP_PDU_t* req_pdu = e2ap_xml_to_pdu("E2AP_ResourceStatusRequest_bad.xml");
215
216   LOG_D("[E2AP] Created RESOURCE-STATUS-REQUEST");
217
218   e2ap_asn1c_print_pdu(req_pdu);
219
220   uint8_t       *buf;
221   sctp_buffer_t data;
222
223   data.len = e2ap_asn1c_encode_pdu(req_pdu, &buf);
224   memcpy(data.buffer, buf, min(data.len, MAX_SCTP_BUFFER));
225
226   //send response data over sctp
227   if(sctp_send_data(socket_fd, data) > 0) {
228     LOG_I("[SCTP] Sent RESOURCE-STATUS-REQUEST");
229   } else {
230     LOG_E("[SCTP] Unable to send RESOURCE-STATUS-REQUEST to peer");
231   }
232
233 }
234
235 /*
236 Simply send back ENDCX2SetupResponse
237 Todo: add more handling options (failure, duplicated request, etc.)
238 */
239 void e2ap_handle_ENDCX2SetupRequest(E2AP_PDU_t* pdu, int &socket_fd)
240 {
241   E2AP_PDU_t* res_pdu = e2ap_xml_to_pdu("E2AP_ENDCX2SetupResponse.xml");
242
243   LOG_D("[E2AP] Created ENDC-X2-SETUP-RESPONSE");
244
245   e2ap_asn1c_print_pdu(res_pdu);
246
247   uint8_t       *buf;
248   sctp_buffer_t data;
249
250   data.len = e2ap_asn1c_encode_pdu(res_pdu, &buf);
251   memcpy(data.buffer, buf, min(data.len, MAX_SCTP_BUFFER));
252
253   //send response data over sctp
254   if(sctp_send_data(socket_fd, data) > 0) {
255     LOG_I("[SCTP] Sent ENDC-X2-SETUP-RESPONSE");
256   } else {
257     LOG_E("[SCTP] Unable to send ENDC-X2-SETUP-RESPONSE to peer");
258   }
259 }
260
261 /*
262 Simply send back hard-coded RICSubscriptionResponse
263 Todo: add more handling options (failure, duplicated request, etc.)
264 */
265 void e2ap_handle_RICSubscriptionRequest(E2AP_PDU_t* pdu, int &socket_fd)
266 {
267   E2AP_PDU_t* res_pdu = e2ap_xml_to_pdu("E2AP_RICsubscriptionResponse.xml");
268
269   LOG_D("[E2AP] Created RIC-SUBSCRIPTION-RESPONSE");
270
271   e2ap_asn1c_print_pdu(res_pdu);
272
273   uint8_t       *buf;
274   sctp_buffer_t data;
275
276   data.len = e2ap_asn1c_encode_pdu(res_pdu, &buf);
277   memcpy(data.buffer, buf, min(data.len, MAX_SCTP_BUFFER));
278
279   //send response data over sctp
280   if(sctp_send_data(socket_fd, data) > 0) {
281     LOG_I("[SCTP] Sent RIC-SUBSCRIPTION-RESPONSE");
282   } else {
283     LOG_E("[SCTP] Unable to send RIC-SUBSCRIPTION-RESPONSE to peer");
284   }
285 }
286
287 void e2ap_handle_RICSubscriptionRequest_securityDemo(E2AP_PDU_t* pdu, int &socket_fd)
288 {
289   E2AP_PDU_t* res_pdu = e2ap_xml_to_pdu("E2AP_RICsubscriptionResponse.xml");
290
291   LOG_D("[E2AP] Created RIC-SUBSCRIPTION-RESPONSE");
292
293   e2ap_asn1c_print_pdu(res_pdu);
294
295   uint8_t       *buf;
296   sctp_buffer_t data;
297
298   data.len = e2ap_asn1c_encode_pdu(res_pdu, &buf);
299   memcpy(data.buffer, buf, min(data.len, MAX_SCTP_BUFFER));
300
301   //send response data over sctp
302   if(sctp_send_data(socket_fd, data) > 0) {
303     LOG_I("[SCTP] Sent RIC-SUBSCRIPTION-RESPONSE");
304   } else {
305     LOG_E("[SCTP] Unable to send RIC-SUBSCRIPTION-RESPONSE to peer");
306   }
307
308   //Start sending RIC Indication
309   int count1 = 0, count2 = 0;
310
311   E2AP_PDU_t* indication_type1 = e2ap_xml_to_pdu("E2AP_RICindication_type1.xml");
312   E2AP_PDU_t* indication_type2 = e2ap_xml_to_pdu("E2AP_RICindication_type2.xml");
313
314   uint8_t *buf1, *buf2;
315   sctp_buffer_t data1, data2;
316   data1.len = e2ap_asn1c_encode_pdu(indication_type1, &buf1);
317   memcpy(data1.buffer, buf1, min(data1.len, MAX_SCTP_BUFFER));
318
319   data2.len = e2ap_asn1c_encode_pdu(indication_type2, &buf2);
320   memcpy(data2.buffer, buf2, min(data2.len, MAX_SCTP_BUFFER));
321
322   while(1){
323     sleep(1);
324     //type1
325     if(sctp_send_data(socket_fd, data1) > 0) {
326       count1++;
327       LOG_I("[SCTP] Sent RIC-INDICATION SgNBAdditionRequest Type 1, count1 = %d", count1);
328     } else {
329       LOG_E("[SCTP] Unable to send RIC-INDICATION to peer");
330     }
331
332     sleep(1);
333     //type2
334     if(sctp_send_data(socket_fd, data2) > 0) {
335       count2++;
336       LOG_I("[SCTP] Sent RIC-INDICATION SgNBAdditionRequest Type 2, count2 = %d", count2);
337     } else {
338       LOG_E("[SCTP] Unable to send RIC-INDICATION to peer");
339     }
340   } //end while
341
342 }
343
344 void e2ap_handle_ResourceStatusRequest(E2AP_PDU_t* pdu, int &socket_fd)
345 {
346   //send back ResourceStatusResponse, followed by resource status update
347   E2AP_PDU_t* res_pdu = e2ap_xml_to_pdu("E2AP_ResourceStatusResponse.xml");
348
349   LOG_D("[E2AP] Created RESOURCE-STATUS-RESPONSE");
350
351   e2ap_asn1c_print_pdu(res_pdu);
352
353   uint8_t       *buf;
354   sctp_buffer_t data;
355
356   data.len = e2ap_asn1c_encode_pdu(res_pdu, &buf);
357   memcpy(data.buffer, buf, min(data.len, MAX_SCTP_BUFFER));
358
359   //send response data over sctp
360   if(sctp_send_data(socket_fd, data) > 0) {
361     LOG_I("[SCTP] Sent RESOURCE-STATUS-RESPONSE");
362   } else {
363     LOG_E("[SCTP] Unable to send RESOURCE-STATUS-RESPONSE to peer");
364   }
365
366
367   //send ResourceStatusUpdate periodically
368   E2AP_PDU_t* update_pdu = e2ap_xml_to_pdu("E2AP_ResourceStatusUpdate.xml");
369
370   uint8_t       *update_buf;
371   sctp_buffer_t update_data;
372
373   update_data.len = e2ap_asn1c_encode_pdu(update_pdu, &update_buf);
374   memcpy(update_data.buffer, update_buf, min(update_data.len, MAX_SCTP_BUFFER));
375
376   while(1) {
377     // e2ap_asn1c_print_pdu(update_pdu);
378
379     if(sctp_send_data(socket_fd, update_data) > 0) {
380       LOG_I("[SCTP] Sent RESOURCE-STATUS-UPDATE");
381     } else {
382       LOG_E("[SCTP] Unable to send RESOURCE-STATUS-UPDATE to peer");
383     }
384
385     sleep(1);
386
387   }
388 }