Initial commit of KPIMON xAPP for Bronze Release Enhancement.
[scp/ric-app/kpimon.git] / e2ap / wrapper.c
1 #include <errno.h>
2 #include "wrapper.h"
3
4 size_t encode_E2AP_PDU(E2AP_PDU_t* pdu, void* buffer, size_t buf_size)
5 {
6     asn_enc_rval_t encode_result;
7     encode_result = aper_encode_to_buffer(&asn_DEF_E2AP_PDU, NULL, pdu, buffer, buf_size);
8     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
9     if(encode_result.encoded == -1) {
10         fprintf(stderr, "Cannot encode %s: %s\n", encode_result.failed_type->name, strerror(errno));
11         return -1;
12     } else {
13         return encode_result.encoded;
14     }
15 }
16
17 E2AP_PDU_t* decode_E2AP_PDU(const void* buffer, size_t buf_size)
18 {
19     asn_dec_rval_t decode_result;
20     E2AP_PDU_t *pdu = 0;
21     decode_result = aper_decode_complete(NULL, &asn_DEF_E2AP_PDU, (void **)&pdu, buffer, buf_size);
22     if(decode_result.code == RC_OK) {
23         return pdu;
24     } else {
25         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
26         return 0;
27     }
28 }
29
30 /* RICsubscriptionRequest */
31 long e2ap_get_ric_subscription_request_sequence_number(void *buffer, size_t buf_size)
32 {
33     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
34     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_initiatingMessage)
35     {
36         InitiatingMessage_t* initiatingMessage = pdu->choice.initiatingMessage;
37         if ( initiatingMessage->procedureCode == ProcedureCode_id_RICsubscription
38             && initiatingMessage->value.present == InitiatingMessage__value_PR_RICsubscriptionRequest)
39         {
40             RICsubscriptionRequest_t *ric_subscription_request = &(initiatingMessage->value.choice.RICsubscriptionRequest);
41             for (int i = 0; i < ric_subscription_request->protocolIEs.list.count; ++i )
42             {
43                 if ( ric_subscription_request->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
44                 {
45                     long sequenceNumber = ric_subscription_request->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
46                     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
47                     return sequenceNumber;
48                 }
49             }
50         }
51     }
52
53     if(pdu != NULL) 
54         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
55     return -1;
56 }
57
58 ssize_t  e2ap_set_ric_subscription_request_sequence_number(void *buffer, size_t buf_size, long sequence_number)
59 {
60     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
61     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_initiatingMessage)
62     {
63         InitiatingMessage_t* initiatingMessage = pdu->choice.initiatingMessage;
64         if ( initiatingMessage->procedureCode == ProcedureCode_id_RICsubscription
65             && initiatingMessage->value.present == InitiatingMessage__value_PR_RICsubscriptionRequest)
66         {
67             RICsubscriptionRequest_t *ricSubscriptionRequest = &initiatingMessage->value.choice.RICsubscriptionRequest;
68             for (int i = 0; i < ricSubscriptionRequest->protocolIEs.list.count; ++i )
69             {
70                 if ( ricSubscriptionRequest->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
71                 {
72                     ricSubscriptionRequest->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID = sequence_number;
73                     return encode_E2AP_PDU(pdu, buffer, buf_size);
74                 }
75             }
76         }
77     }
78
79     if(pdu != NULL) 
80         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
81     return -1;
82 }
83
84 ssize_t e2ap_encode_ric_subscription_request_message(void *buffer, size_t buf_size, long ricRequestorID, long ricRequestSequenceNumber, long ranFunctionID, void *eventTriggerDefinition, size_t eventTriggerDefinitionSize, int actionCount, long *actionIds, long* actionTypes, RICactionDefinition *actionDefinitions, RICSubsequentAction *subsequentActionTypes) 
85 {
86     E2AP_PDU_t *init = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
87     if(!init) {
88         fprintf(stderr, "alloc E2AP_PDU failed\n");
89         return -1;
90     }
91     
92     InitiatingMessage_t *initiatingMsg = (InitiatingMessage_t *)calloc(1, sizeof(InitiatingMessage_t));
93     if(!initiatingMsg) {
94         fprintf(stderr, "alloc InitiatingMessage failed\n");
95         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
96         return -1;
97     }
98
99     init->choice.initiatingMessage = initiatingMsg;
100     init->present = E2AP_PDU_PR_initiatingMessage;
101
102     initiatingMsg->procedureCode = ProcedureCode_id_RICsubscription;
103     initiatingMsg->criticality = Criticality_reject;
104     initiatingMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
105
106     RICsubscriptionRequest_t *subscription_request = &initiatingMsg->value.choice.RICsubscriptionRequest;
107     
108     // request contains 5 IEs
109
110     // RICrequestID
111     RICsubscriptionRequest_IEs_t *ies_reqID = (RICsubscriptionRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionRequest_IEs_t));
112     if(!ies_reqID) {
113         fprintf(stderr, "alloc RICrequestID failed\n");
114         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
115         return -1;
116     }
117
118     ies_reqID->criticality = Criticality_reject;
119     ies_reqID->id = ProtocolIE_ID_id_RICrequestID;
120     ies_reqID->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
121     RICrequestID_t *ricrequest_ie = &ies_reqID->value.choice.RICrequestID;
122     ricrequest_ie->ricRequestorID = ricRequestorID;
123     ricrequest_ie->ricInstanceID = ricRequestSequenceNumber;
124     ASN_SEQUENCE_ADD(&subscription_request->protocolIEs.list, ies_reqID);
125
126     // RICfunctionID
127     RICsubscriptionRequest_IEs_t *ies_ranfunc = (RICsubscriptionRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionRequest_IEs_t));
128     if(!ies_ranfunc) {
129         fprintf(stderr, "alloc RICfunctionID failed\n");
130         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
131         return -1;
132     }
133
134     ies_ranfunc->criticality = Criticality_reject;
135     ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
136     ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
137     RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
138     *ranfunction_ie = ranFunctionID;
139     ASN_SEQUENCE_ADD(&subscription_request->protocolIEs.list, ies_ranfunc);
140
141     // RICsubscription
142     RICsubscriptionRequest_IEs_t *ies_subscription = (RICsubscriptionRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionRequest_IEs_t));
143     if(!ies_subscription) {
144         fprintf(stderr, "alloc RICsubscription failed\n");
145         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
146         return -1;
147     }
148
149     ies_subscription->criticality = Criticality_reject;
150     ies_subscription->id = ProtocolIE_ID_id_RICsubscriptionDetails;
151     ies_subscription->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
152     RICsubscriptionDetails_t *ricsubscription_ie = &ies_subscription->value.choice.RICsubscriptionDetails;
153
154     // RICeventTriggerDefinition
155     RICeventTriggerDefinition_t *eventTrigger = &ricsubscription_ie->ricEventTriggerDefinition;
156     eventTrigger->buf = (uint8_t *)calloc(1, eventTriggerDefinitionSize);
157     if(!eventTrigger->buf) {
158         fprintf(stderr, "alloc eventTrigger failed\n");
159         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
160         return -1;
161     }
162
163     memcpy(eventTrigger->buf, eventTriggerDefinition, eventTriggerDefinitionSize);
164     eventTrigger->size = eventTriggerDefinitionSize;
165     
166     // RICactions-ToBeSetup-List
167     RICactions_ToBeSetup_List_t *ricActions = &ricsubscription_ie->ricAction_ToBeSetup_List;
168     int index = 0;
169     while (index < actionCount) {
170         RICaction_ToBeSetup_ItemIEs_t *ies_action = (RICaction_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(RICaction_ToBeSetup_ItemIEs_t));
171         if(!ies_action) {
172             fprintf(stderr, "alloc RICaction failed\n");
173             ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
174             return -1;
175         }
176
177         ies_action->criticality = Criticality_reject;
178         ies_action->id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item;
179         ies_action->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
180         RICaction_ToBeSetup_Item_t *ricaction_ie = &ies_action->value.choice.RICaction_ToBeSetup_Item;
181         ricaction_ie->ricActionID = actionIds[index];
182         ricaction_ie->ricActionType = actionTypes[index];
183
184         int actionDefinitionSize = actionDefinitions[index].size;
185         if(actionDefinitionSize != 0) {
186             RICactionDefinition_t *actionDefinition = ricaction_ie->ricActionDefinition;
187             
188             actionDefinition->buf = (uint8_t *)calloc(1, actionDefinitionSize);
189             if(!actionDefinition->buf) {
190                 fprintf(stderr, "alloc actionDefinition[%d] failed\n", index);
191                 ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
192                 return -1;
193             }
194
195             memcpy(actionDefinition->buf, actionDefinitions[index].actionDefinition, actionDefinitionSize);
196             actionDefinition->size = actionDefinitionSize;
197         }
198
199         if(subsequentActionTypes[index].isValid != 0) {
200             RICsubsequentAction_t *subsequentAction = ricaction_ie->ricSubsequentAction;
201             subsequentAction->ricSubsequentActionType = subsequentActionTypes[index].subsequentActionType;
202             subsequentAction->ricTimeToWait = subsequentActionTypes[index].timeToWait;
203         }
204
205         ASN_SEQUENCE_ADD(&ricActions->list, ies_action);
206         index++;
207     }
208     ASN_SEQUENCE_ADD(&subscription_request->protocolIEs.list, ies_subscription);
209
210     return encode_E2AP_PDU(init, buffer, buf_size);
211 }
212
213 /* RICsubscriptionResponse */
214 long e2ap_get_ric_subscription_response_sequence_number(void *buffer, size_t buf_size)
215 {
216     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
217     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_successfulOutcome )
218     {
219         SuccessfulOutcome_t* successfulOutcome = pdu->choice.successfulOutcome;
220         if ( successfulOutcome->procedureCode == ProcedureCode_id_RICsubscription
221             && successfulOutcome->value.present == SuccessfulOutcome__value_PR_RICsubscriptionResponse)
222         {
223             RICsubscriptionResponse_t *ricSubscriptionResponse = &successfulOutcome->value.choice.RICsubscriptionResponse;
224             for (int i = 0; i < ricSubscriptionResponse->protocolIEs.list.count; ++i )
225             {
226                 if ( ricSubscriptionResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
227                 {
228                     long sequenceNumber = ricSubscriptionResponse->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
229                     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
230                     return sequenceNumber;
231                 }
232             }
233         }
234     }
235
236     if(pdu != NULL) 
237         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
238     return -1;
239 }
240
241 ssize_t  e2ap_set_ric_subscription_response_sequence_number(void *buffer, size_t buf_size, long sequence_number)
242 {
243     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
244     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_successfulOutcome )
245     {
246         SuccessfulOutcome_t* successfulOutcome = pdu->choice.successfulOutcome;
247         if ( successfulOutcome->procedureCode == ProcedureCode_id_RICsubscription
248             && successfulOutcome->value.present == SuccessfulOutcome__value_PR_RICsubscriptionResponse)
249         {
250             RICsubscriptionResponse_t *ricSubscriptionResponse = &successfulOutcome->value.choice.RICsubscriptionResponse;
251             for (int i = 0; i < ricSubscriptionResponse->protocolIEs.list.count; ++i )
252             {
253                 if ( ricSubscriptionResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
254                 {
255                     ricSubscriptionResponse->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID = sequence_number;
256                     return encode_E2AP_PDU(pdu, buffer, buf_size);
257                 }
258             }
259         }
260     }
261
262     if(pdu != NULL) 
263         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
264     return -1;
265 }
266
267 RICsubscriptionResponseMsg* e2ap_decode_ric_subscription_response_message(void *buffer, size_t buf_size)
268 {
269     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
270     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_successfulOutcome)
271     {
272         SuccessfulOutcome_t* successfulOutcome = pdu->choice.successfulOutcome;
273         if ( successfulOutcome->procedureCode == ProcedureCode_id_RICsubscription
274             && successfulOutcome->value.present == SuccessfulOutcome__value_PR_RICsubscriptionResponse)
275         {
276             RICsubscriptionResponse_t *subscriptionResponse = &(successfulOutcome->value.choice.RICsubscriptionResponse);
277             RICsubscriptionResponseMsg *msg = (RICsubscriptionResponseMsg *)calloc(1, sizeof(RICsubscriptionResponseMsg));
278             for (int i = 0; i < subscriptionResponse->protocolIEs.list.count; ++i )
279             {
280                 if (subscriptionResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID) {
281                     msg->requestorID = subscriptionResponse->protocolIEs.list.array[i]->value.choice.RICrequestID.ricRequestorID;
282                     msg->requestSequenceNumber = subscriptionResponse->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
283                 }
284                 else if (subscriptionResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RANfunctionID) {
285                     msg->ranfunctionID = subscriptionResponse->protocolIEs.list.array[i]->value.choice.RANfunctionID;
286                 }
287                 else if (subscriptionResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICactions_Admitted) {
288                     RICaction_Admitted_List_t *ricActionAdmittedList = &(subscriptionResponse->protocolIEs.list.array[i]->value.choice.RICaction_Admitted_List);
289                     int index = 0;
290                     while (index < ricActionAdmittedList->list.count) {
291                         RICaction_Admitted_ItemIEs_t *ricActionAdmittedItem = (RICaction_Admitted_ItemIEs_t *)ricActionAdmittedList->list.array[index];
292                         if (ricActionAdmittedItem->id == ProtocolIE_ID_id_RICaction_Admitted_Item) {
293                             msg->ricActionAdmittedList.ricActionID[index] = ricActionAdmittedItem->value.choice.RICaction_Admitted_Item.ricActionID;
294                         }
295                         index++;
296                     }
297                     msg->ricActionAdmittedList.count = index;
298                 }
299                 else if (subscriptionResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICactions_NotAdmitted) {
300                     RICaction_NotAdmitted_List_t *ricActionNotAdmittedList = &(subscriptionResponse->protocolIEs.list.array[i]->value.choice.RICaction_NotAdmitted_List);
301                     int index = 0;
302                     while (index < ricActionNotAdmittedList->list.count) {
303                         RICaction_NotAdmitted_ItemIEs_t *ricActionNotAdmittedItem = (RICaction_NotAdmitted_ItemIEs_t *)ricActionNotAdmittedList->list.array[index];
304                         if (ricActionNotAdmittedItem->id == ProtocolIE_ID_id_RICaction_NotAdmitted_Item) {
305                             msg->ricActionNotAdmittedList.ricActionID[index] = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.ricActionID;
306                             int RICcauseType = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.cause.present;
307                             switch(RICcauseType) {
308                                 case Cause_PR_ricRequest:
309                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseType = Cause_PR_ricRequest;
310                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseID = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
311                                     break;
312                                 case Cause_PR_ricService:
313                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseType = Cause_PR_ricService;
314                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseID = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
315                                     break;
316                                 case Cause_PR_transport:
317                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseType = Cause_PR_transport;
318                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseID = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
319                                     break;
320                                 case Cause_PR_protocol:
321                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseType = Cause_PR_protocol;
322                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseID = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
323                                     break;
324                                 case Cause_PR_misc:
325                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseType = Cause_PR_misc;
326                                     msg->ricActionNotAdmittedList.ricCause[index].ricCauseID = ricActionNotAdmittedItem->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
327                                     break;
328                             }
329                         }
330                         index++;
331                     }
332                     msg->ricActionNotAdmittedList.count = index;
333                 }
334             }
335             return msg;
336         }
337     }
338     return NULL;
339 }
340
341 /* RICsubscriptionFailure */
342 long e2ap_get_ric_subscription_failure_sequence_number(void *buffer, size_t buf_size)
343 {
344     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
345     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_unsuccessfulOutcome )
346     {
347         UnsuccessfulOutcome_t* unsuccessfulOutcome = pdu->choice.unsuccessfulOutcome;
348         if ( unsuccessfulOutcome->procedureCode == ProcedureCode_id_RICsubscription
349             && unsuccessfulOutcome->value.present == UnsuccessfulOutcome__value_PR_RICsubscriptionFailure)
350         {
351             RICsubscriptionFailure_t *ricSubscriptionFailure = &unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
352             for (int i = 0; i < ricSubscriptionFailure->protocolIEs.list.count; ++i )
353             {
354                 if ( ricSubscriptionFailure->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
355                 {
356                     long sequenceNumber = ricSubscriptionFailure->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
357                     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
358                     return sequenceNumber;
359                 }
360             }
361         }
362     }
363
364     if(pdu != NULL) 
365         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
366     return -1;
367 }
368
369 /* RICsubscriptionDeleteRequest */
370 long e2ap_get_ric_subscription_delete_request_sequence_number(void *buffer, size_t buf_size)
371 {
372     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
373     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_initiatingMessage )
374     {
375         InitiatingMessage_t* initiatingMessage = pdu->choice.initiatingMessage;
376         if ( initiatingMessage->procedureCode == ProcedureCode_id_RICsubscriptionDelete
377             && initiatingMessage->value.present == InitiatingMessage__value_PR_RICsubscriptionDeleteRequest )
378         {
379             RICsubscriptionDeleteRequest_t *subscriptionDeleteRequest = &initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
380             for (int i = 0; i < subscriptionDeleteRequest->protocolIEs.list.count; ++i )
381             {
382                 if ( subscriptionDeleteRequest->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
383                 {
384                     long sequenceNumber = subscriptionDeleteRequest->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
385                     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
386                     return sequenceNumber;
387                 }
388             }
389         }
390     }
391
392     if(pdu != NULL) 
393         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
394     return -1;
395 }
396
397 ssize_t  e2ap_set_ric_subscription_delete_request_sequence_number(void *buffer, size_t buf_size, long sequence_number)
398 {
399     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
400     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_initiatingMessage )
401     {
402         InitiatingMessage_t* initiatingMessage = pdu->choice.initiatingMessage;
403         if ( initiatingMessage->procedureCode == ProcedureCode_id_RICsubscriptionDelete
404             && initiatingMessage->value.present == InitiatingMessage__value_PR_RICsubscriptionDeleteRequest )
405         {
406             RICsubscriptionDeleteRequest_t* subscriptionDeleteRequest = &initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
407             for (int i = 0; i < subscriptionDeleteRequest->protocolIEs.list.count; ++i )
408             {
409                 if ( subscriptionDeleteRequest->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
410                 {
411                     subscriptionDeleteRequest->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID = sequence_number;
412                     return encode_E2AP_PDU(pdu, buffer, buf_size);
413                 }
414             }
415         }
416     }
417
418     if(pdu != NULL) 
419         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
420     return -1;
421 }
422
423 ssize_t e2ap_encode_ric_subscription_delete_request_message(void *buffer, size_t buf_size, long ricRequestorID, long ricRequestSequenceNumber, long ranFunctionID)
424 {
425     E2AP_PDU_t *init = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
426     if(!init) {
427         fprintf(stderr, "alloc E2AP_PDU failed\n");
428         return -1;
429     }
430
431     InitiatingMessage_t *initiatingMsg = (InitiatingMessage_t *)calloc(1, sizeof(InitiatingMessage_t));
432     if(!initiatingMsg) {
433         fprintf(stderr, "alloc InitiatingMessage failed\n");
434         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
435         return -1;
436     }
437
438     init->choice.initiatingMessage = initiatingMsg;
439     init->present = E2AP_PDU_PR_initiatingMessage;
440
441     initiatingMsg->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
442     initiatingMsg->criticality = Criticality_reject;
443     initiatingMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionDeleteRequest;
444
445     RICsubscriptionDeleteRequest_t *subscription_delete_request = &initiatingMsg->value.choice.RICsubscriptionDeleteRequest;
446     
447     // request contains 2 IEs
448
449     // RICrequestID
450     RICsubscriptionDeleteRequest_IEs_t *ies_reqID = (RICsubscriptionDeleteRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionDeleteRequest_IEs_t));
451     if(!ies_reqID) {
452         fprintf(stderr, "alloc RICrequestID failed\n");
453         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
454         return -1;
455     }
456
457     ies_reqID->criticality = Criticality_reject;
458     ies_reqID->id = ProtocolIE_ID_id_RICrequestID;
459     ies_reqID->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
460     RICrequestID_t *ricrequest_ie = &ies_reqID->value.choice.RICrequestID;
461     ricrequest_ie->ricRequestorID = ricRequestorID;
462     ricrequest_ie->ricInstanceID = ricRequestSequenceNumber;
463     ASN_SEQUENCE_ADD(&subscription_delete_request->protocolIEs.list, ies_reqID);
464
465     // RICfunctionID
466     RICsubscriptionDeleteRequest_IEs_t *ies_ranfunc = (RICsubscriptionDeleteRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionDeleteRequest_IEs_t));
467     if(!ies_ranfunc) {
468         fprintf(stderr, "alloc RICfunctionID failed\n");
469         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, init);
470         return -1;
471     }
472
473     ies_ranfunc->criticality = Criticality_reject;
474     ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
475     ies_ranfunc->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
476     RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
477     *ranfunction_ie = ranFunctionID;
478     ASN_SEQUENCE_ADD(&subscription_delete_request->protocolIEs.list, ies_ranfunc);
479
480     return encode_E2AP_PDU(init, buffer, buf_size);
481 }
482
483 /* RICsubscriptionDeleteResponse */
484 long e2ap_get_ric_subscription_delete_response_sequence_number(void *buffer, size_t buf_size)
485 {
486     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
487     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_successfulOutcome )
488     {
489         SuccessfulOutcome_t* successfulOutcome = pdu->choice.successfulOutcome;
490         if ( successfulOutcome->procedureCode == ProcedureCode_id_RICsubscriptionDelete
491             && successfulOutcome->value.present == SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse )
492         {
493             RICsubscriptionDeleteResponse_t* subscriptionDeleteResponse = &successfulOutcome->value.choice.RICsubscriptionDeleteResponse;
494             for (int i = 0; i < subscriptionDeleteResponse->protocolIEs.list.count; ++i )
495             {
496                 if ( subscriptionDeleteResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
497                 {
498                     long sequenceNumber = subscriptionDeleteResponse->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
499                     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
500                     return sequenceNumber;
501                 }
502             }
503         }
504     }
505
506     if(pdu != NULL) 
507         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
508     return -1;
509 }
510
511 ssize_t  e2ap_set_ric_subscription_delete_response_sequence_number(void *buffer, size_t buf_size, long sequence_number)
512 {
513     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
514     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_successfulOutcome )
515     {
516         SuccessfulOutcome_t* successfulOutcome = pdu->choice.successfulOutcome;
517         if ( successfulOutcome->procedureCode == ProcedureCode_id_RICsubscriptionDelete
518             && successfulOutcome->value.present == SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse )
519         {
520             RICsubscriptionDeleteResponse_t* subscriptionDeleteResponse = &successfulOutcome->value.choice.RICsubscriptionDeleteResponse;
521             for (int i = 0; i < subscriptionDeleteResponse->protocolIEs.list.count; ++i )
522             {
523                 if ( subscriptionDeleteResponse->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
524                 {
525                     subscriptionDeleteResponse->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID = sequence_number;
526                     return encode_E2AP_PDU(pdu, buffer, buf_size);
527                 }
528             }
529         }
530     }
531
532     if(pdu != NULL) 
533         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
534     return -1;
535 }
536
537 /* RICsubscriptionDeleteFailure */
538 long e2ap_get_ric_subscription_delete_failure_sequence_number(void *buffer, size_t buf_size)
539 {
540     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
541     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_unsuccessfulOutcome )
542     {
543         UnsuccessfulOutcome_t* unsuccessfulOutcome = pdu->choice.unsuccessfulOutcome;
544         if ( unsuccessfulOutcome->procedureCode == ProcedureCode_id_RICsubscriptionDelete
545             && unsuccessfulOutcome->value.present == UnsuccessfulOutcome__value_PR_RICsubscriptionDeleteFailure)
546         {
547             RICsubscriptionDeleteFailure_t *ricSubscriptionDeleteFailure = &unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure;
548             for (int i = 0; i < ricSubscriptionDeleteFailure->protocolIEs.list.count; ++i )
549             {
550                 if ( ricSubscriptionDeleteFailure->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID )
551                 {
552                     long sequenceNumber = ricSubscriptionDeleteFailure->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
553                     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
554                     return sequenceNumber;
555                 }
556             }
557         }
558     }
559
560     if(pdu != NULL) 
561         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
562     return -1;
563 }
564
565 /* RICindication */
566
567 RICindicationMsg* e2ap_decode_ric_indication_message(void *buffer, size_t buf_size)
568 {
569     E2AP_PDU_t *pdu = decode_E2AP_PDU(buffer, buf_size);
570     if ( pdu != NULL && pdu->present == E2AP_PDU_PR_initiatingMessage)
571     {
572         InitiatingMessage_t* initiatingMessage = pdu->choice.initiatingMessage;
573         if ( initiatingMessage->procedureCode == ProcedureCode_id_RICindication
574             && initiatingMessage->value.present == InitiatingMessage__value_PR_RICindication)
575         {
576             RICindication_t *indication = &(initiatingMessage->value.choice.RICindication);
577             RICindicationMsg *msg = (RICindicationMsg *)calloc(1, sizeof(RICindicationMsg));
578             for (int i = 0; i < indication->protocolIEs.list.count; ++i )
579             {
580                 if (indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICrequestID) {
581                     msg->requestorID = indication->protocolIEs.list.array[i]->value.choice.RICrequestID.ricRequestorID;
582                     msg->requestSequenceNumber = indication->protocolIEs.list.array[i]->value.choice.RICrequestID.ricInstanceID;
583                 }
584                 else if (indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RANfunctionID) {
585                     msg->ranfunctionID = indication->protocolIEs.list.array[i]->value.choice.RANfunctionID;
586                 }
587                 else if (indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICactionID) {
588                     msg->actionID = indication->protocolIEs.list.array[i]->value.choice.RICactionID;
589                 }
590                 else if(indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICindicationSN) {
591                     msg->indicationSN = indication->protocolIEs.list.array[i]->value.choice.RICindicationSN;
592                 }
593                 else if(indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICindicationType) {
594                     msg->indicationType = indication->protocolIEs.list.array[i]->value.choice.RICindicationType;
595                 }
596                 else if(indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICindicationHeader) {
597                     size_t headerSize = indication->protocolIEs.list.array[i]->value.choice.RICindicationHeader.size;
598                     msg->indicationHeader = calloc(1, headerSize);
599                     if (!msg->indicationHeader) {
600                         fprintf(stderr, "alloc RICindicationHeader failed\n");
601                         e2ap_free_decoded_ric_indication_message(msg);
602                         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
603                         return NULL;
604                     }
605
606                     memcpy(msg->indicationHeader, indication->protocolIEs.list.array[i]->value.choice.RICindicationHeader.buf, headerSize);
607                     msg->indicationHeaderSize = headerSize;
608                 }
609                 else if(indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICindicationMessage) {
610                     size_t messsageSize = indication->protocolIEs.list.array[i]->value.choice.RICindicationMessage.size;
611                     msg->indicationMessage = calloc(1, messsageSize);
612                     if (!msg->indicationMessage) {
613                         fprintf(stderr, "alloc RICindicationMessage failed\n");
614                         e2ap_free_decoded_ric_indication_message(msg);
615                         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
616                         return NULL;
617                     }
618
619                     memcpy(msg->indicationMessage, indication->protocolIEs.list.array[i]->value.choice.RICindicationMessage.buf, messsageSize);
620                     msg->indicationMessageSize = messsageSize;
621                 }
622                 else if(indication->protocolIEs.list.array[i]->id == ProtocolIE_ID_id_RICcallProcessID) {
623                     size_t callProcessIDSize = indication->protocolIEs.list.array[i]->value.choice.RICcallProcessID.size;
624                     msg->callProcessID = calloc(1, callProcessIDSize);
625                     if (!msg->callProcessID) {
626                         fprintf(stderr, "alloc RICcallProcessID failed\n");
627                         e2ap_free_decoded_ric_indication_message(msg);
628                         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
629                         return NULL;
630                     }
631
632                     memcpy(msg->callProcessID, indication->protocolIEs.list.array[i]->value.choice.RICcallProcessID.buf, callProcessIDSize);
633                     msg->callProcessIDSize = callProcessIDSize;
634                 }
635             }
636             return msg;
637         }
638     }
639
640     if(pdu != NULL) 
641         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
642     return NULL;
643 }
644
645 void e2ap_free_decoded_ric_indication_message(RICindicationMsg* msg) {
646     if(msg == NULL) {
647         return;
648     }
649
650     if(msg->indicationHeader != NULL) {
651         free(msg->indicationHeader);
652         msg->indicationHeader = NULL;
653     }
654     if(msg->indicationMessage != NULL) {
655         free(msg->indicationMessage);
656         msg->indicationMessage = NULL;
657     }
658     if(msg->callProcessID != NULL) {
659         free(msg->callProcessID);
660         msg->callProcessID = NULL;
661     }
662     free(msg);
663     msg = NULL;
664 }