E2AP Wrapper Implementation
[ric-app/hw.git] / src / xapp-asn / e2ap / e2ap_subscription_failure.cc
1 /*
2 ==================================================================================
3
4         Copyright (c) 2019-2020 AT&T Intellectual Property.
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 /*
20  * e2ap_E2APSubscriptionFailure.cc
21  *
22  *
23  *      Author: SJana, Ashwin Sridharan
24  */
25 #include<e2ap_subscription_failure.hpp>
26
27 E2APSubscriptionFailure::E2APSubscriptionFailure(SubscriptionFailureIEs& subObj){
28
29   _failureIEs = std::make_unique<SubscriptionFailureIEs>();
30   *_failureIEs = subObj;
31
32   _e2ap_pdu_obj = 0;
33   _e2ap_pdu_obj = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
34   assert(_e2ap_pdu_obj != 0);
35
36   _unsuccessMsg = 0;
37   _unsuccessMsg = (UnsuccessfulOutcome_t *)calloc(1, sizeof(UnsuccessfulOutcome_t));
38   assert(_unsuccessMsg != 0);
39
40
41
42   IE_array = 0;
43   IE_array = (RICsubscriptionFailure_IEs_t *)calloc(RIC_SUB_FAILURE_IES_COUNT, sizeof(RICsubscriptionFailure_IEs_t));
44   assert(IE_array != 0);
45
46
47   ie_not_admitted_list = 0;
48   CD_array = 0;
49
50 };
51
52 // Clear assigned protocolIE list from RIC indication IE container
53 E2APSubscriptionFailure::~E2APSubscriptionFailure(void){
54
55   RICsubscriptionFailure_t * ric_subscriptionFailure = &(_unsuccessMsg->value.choice.RICsubscriptionFailure);
56   for(int i = 0; i < ric_subscriptionFailure->protocolIEs.list.size ; i++){
57           ric_subscriptionFailure->protocolIEs.list.array[i] = 0;
58   }
59
60   if (ric_subscriptionFailure->protocolIEs.list.size > 0){
61     free(ric_subscriptionFailure->protocolIEs.list.array);
62     ric_subscriptionFailure->protocolIEs.list.array = 0;
63     ric_subscriptionFailure->protocolIEs.list.size = 0;
64     ric_subscriptionFailure->protocolIEs.list.count = 0;
65   }
66
67   free(ie_not_admitted_list);
68   free(IE_array);
69   free(_unsuccessMsg);
70   _e2ap_pdu_obj->choice.unsuccessfulOutcome = 0;
71
72   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
73   mdclog_write(MDCLOG_DEBUG, "Freed Subscription Failure Object memory");
74
75
76 };
77
78
79 bool E2APSubscriptionFailure::encode(unsigned char *buf, size_t *size){
80
81     _e2ap_pdu_obj->present =  E2AP_PDU_PR_unsuccessfulOutcome;
82     _e2ap_pdu_obj->choice.unsuccessfulOutcome = _unsuccessMsg;
83
84     bool eres = setfields( _unsuccessMsg);
85       if(!eres)
86           return eres;
87
88     _unsuccessMsg->procedureCode = ProcedureCode_id_RICsubscription;
89     _unsuccessMsg->criticality = Criticality_reject;
90     _unsuccessMsg->value.present = UnsuccessfulOutcome__value_PR_RICsubscriptionFailure;
91
92   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) _e2ap_pdu_obj, _errbuf, &_errbuf_len);
93   if(ret_constr){
94     _error_string.assign(_errbuf, _errbuf_len);
95     _error_string = "Constraints failed for encoding subscription failure. Reason = " + _error_string;
96     return false;
97   }
98
99   asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj, buf, *size);
100   if(res.encoded == -1){
101     mdclog_write(MDCLOG_DEBUG, "Error encoding PDU. Reason =%s",strerror(errno));
102
103     return false;
104   }
105   else {
106     if(*size < res.encoded){
107       fprintf(stderr,  "Buffer assigned too small to encode: %s",(char *)(asn_DEF_E2AP_PDU.name));
108       res.encoded = -1;
109       return false;
110     }
111   }
112
113   *size = res.encoded;
114   xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
115   return true;
116
117 }
118
119 bool E2APSubscriptionFailure::setfields(UnsuccessfulOutcome_t *_unsuccessMsg){
120
121   int ie_index;
122
123
124   RICsubscriptionFailure_t * subsFailure = &(_unsuccessMsg->value.choice.RICsubscriptionFailure);
125   //reset list count ..
126   subsFailure->protocolIEs.list.count = 0;
127
128   ie_index = 0;
129   RICsubscriptionFailure_IEs_t *ies_ricreq = &IE_array[ie_index];
130
131   ies_ricreq->criticality = Criticality_reject;
132   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
133   ies_ricreq->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
134   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
135   ricrequest_ie->ricRequestorID = this->getIEs().get_ricRequestorID();
136   ricrequest_ie->ricInstanceID = this->getIEs().get_ricInstanceID();
137   ASN_SEQUENCE_ADD(&subsFailure->protocolIEs, &(IE_array[ie_index]));
138
139
140   ie_index++;
141   RICsubscriptionFailure_IEs_t *ies_ranfunc = &IE_array[ie_index];
142   ies_ranfunc->criticality = Criticality_reject;
143   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
144   ies_ranfunc->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
145   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
146   *ranfunction_ie = this->getIEs().get_ranFunctionID();
147   ASN_SEQUENCE_ADD(&subsFailure->protocolIEs, &(IE_array[ie_index]));
148
149
150   if(this->getIEs().get_is_ricActionNotAdmitlst()){
151           int notadmit_lst_count = this->getIEs().get_actionsNotAdmitted_list().get_list_count();
152
153         ie_index++;
154         std::vector<RICactionNotAdmittedList::RICactionNotAdmittedItemIEs> * ref_notadmitted_action_array = this->getIEs().get_actionsNotAdmitted_list().get_list();
155
156     RICsubscriptionFailure_IEs_t *ies_notadmitted_actid = &IE_array[ie_index];
157     ies_notadmitted_actid->criticality = Criticality_reject;
158     ies_notadmitted_actid->id = ProtocolIE_ID_id_RICactions_NotAdmitted;
159
160     RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
161     ric_not_admitted_actions_ie->list.count = 0;
162
163
164     ies_notadmitted_actid->value.present =  RICsubscriptionFailure_IEs__value_PR_RICaction_NotAdmitted_List;
165
166
167     ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(notadmit_lst_count, sizeof(RICaction_NotAdmitted_ItemIEs_t));
168     assert(ie_not_admitted_list != 0);
169
170
171     for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
172       ie_not_admitted_list[i].criticality = Criticality_ignore;
173       ie_not_admitted_list[i].id = ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
174       ie_not_admitted_list[i].value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
175       ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_ricActionID();
176
177       int cause = (*ref_notadmitted_action_array)[i].get_ricCause();
178       switch(cause){
179           case Cause_PR_ricService:
180                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService = (*ref_notadmitted_action_array)[i].get_ricSubCause();
181                   break;
182           case Cause_PR_transport:
183                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.transport = (*ref_notadmitted_action_array)[i].get_ricSubCause();
184                   break;
185           case Cause_PR_protocol:
186                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol= (*ref_notadmitted_action_array)[i].get_ricSubCause();
187                   break;
188           case Cause_PR_misc:
189                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.misc = (*ref_notadmitted_action_array)[i].get_ricSubCause();
190                   break;
191           case Cause_PR_ricRequest:
192                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest = (*ref_notadmitted_action_array)[i].get_ricSubCause();
193                   break;
194           default:
195                   mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
196                   break;
197       }
198
199       ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.present = (Cause_PR)cause;
200       ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
201     }
202     ASN_SEQUENCE_ADD(&subsFailure->protocolIEs, &(IE_array[ie_index]));
203
204   }
205   if(this->getIEs().get_is_criticality_diagnostic()) {
206    ie_index++;
207    RICsubscriptionFailure_IEs_t *ies_criticdiag = &IE_array[ie_index];
208    ies_criticdiag->criticality =  Criticality_ignore;
209    ies_criticdiag->id = ProtocolIE_ID_id_CriticalityDiagnostics;
210    ies_criticdiag->value.present = RICsubscriptionFailure_IEs__value_PR_CriticalityDiagnostics;
211    CriticalityDiagnostics_t *critic_diag = &ies_criticdiag->value.choice.CriticalityDiagnostics;
212
213    TriggeringMessage_t *tmsg = (TriggeringMessage_t*) calloc(1, sizeof(TriggeringMessage_t));
214    *tmsg = this->getIEs().get_critical_diagnostic()->get_triggeringMessage();
215    critic_diag->triggeringMessage= tmsg;
216
217    RICrequestID_t *ricreq = (RICrequestID_t *)calloc(1, sizeof(RICrequestID_t));
218    ricrequest_ie->ricRequestorID = this->getIEs().get_critical_diagnostic()->get_ricRequestorID();
219    ricrequest_ie->ricInstanceID = this->getIEs().get_critical_diagnostic()->get_ricInstanceID();
220    critic_diag->ricRequestorID = ricreq;
221
222    ProcedureCode_t *pcode = (ProcedureCode_t*)calloc(1, sizeof(ProcedureCode_t));
223    *pcode = this->getIEs().get_critical_diagnostic()->get_procedureCode();
224    critic_diag->procedureCode =pcode;
225
226    Criticality_t *pcritical = (Criticality_t*)calloc(1, sizeof(Criticality_t));
227    *pcritical = this->getIEs().get_critical_diagnostic()->get_procedureCriticality();
228    critic_diag->procedureCriticality = pcritical;
229
230
231    if(this->getIEs().get_critical_diagnostic()->get_is_criticalityDiagnostics_list()){
232
233           critic_diag->iEsCriticalityDiagnostics = (CriticalityDiagnostics_IE_List_t*)calloc(1, sizeof(CriticalityDiagnostics_IE_List_t));
234           critic_diag->iEsCriticalityDiagnostics->list.count=0;
235
236           int lst_count = this->getIEs().get_critical_diagnostic()->get_list_count();
237           auto *lst = this->getIEs().get_critical_diagnostic()->get_list();
238           CD_array = (CriticalityDiagnostics_IE_Item_t*)calloc(lst_count, sizeof(CriticalityDiagnostics_IE_Item_t));
239           int i = 0;
240           for(auto l:*lst){
241                   CD_array[i].iE_ID =  l.get_typeOferror();
242                   CD_array[i].typeOfError = l.get_ieID();
243                   CD_array[i].iECriticality = l.get_iEcriticality();
244                  int result = ASN_SEQUENCE_ADD(&(critic_diag->iEsCriticalityDiagnostics->list.array), &(CD_array[i]));
245                  if (result == -1){
246                        _error_string = "Error : Unable to assign memory to add CriticalityDiagnostics_IE item to set up list";
247                        return false;
248                          }
249                      i++;
250                   }
251
252           }
253    ASN_SEQUENCE_ADD(&subsFailure->protocolIEs, &(IE_array[ie_index]));
254
255    }
256
257
258   return true;
259 }
260
261 E2APSubscriptionFailure::E2APSubscriptionFailure(unsigned char *buf, size_t *size){
262           _e2ap_pdu_obj = 0;
263           _unsuccessMsg = 0;
264           IE_array = 0;
265           ie_not_admitted_list = 0;
266
267           _failureIEs = std::make_unique<SubscriptionFailureIEs>();
268            bool status =  this->decode(buf, size);
269            if(!status)
270                    throw "E2AP Subscription  Failure Decode Failed: "+this->get_error();
271 }
272 bool E2APSubscriptionFailure::decode(unsigned char *buf, size_t *size)
273 {
274
275         asn_dec_rval_t dec_res  = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&(_e2ap_pdu_obj), buf, *size);
276         if(dec_res.code != RC_OK){
277                         mdclog_write(MDCLOG_ERR, "Failed to decode: %s","RIC Subscription Failure");
278                         return false;
279         } else {
280
281                 mdclog_write(MDCLOG_INFO, "Successfully decoded: %s","RIC Subscription Failure");
282         }
283
284          _unsuccessMsg = _e2ap_pdu_obj->choice.unsuccessfulOutcome;
285          //write the decoding code.
286
287          if (_unsuccessMsg == 0){
288                 _error_string = "Invalid reference to unsuccess message in get fields subscription failure";
289                 return false;
290          }
291
292         RANfunctionID_t * ranfunctionid;
293         RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
294         RICrequestID_t* ricReq;
295
296         for(int edx = 0; edx < _unsuccessMsg->value.choice.RICsubscriptionFailure.protocolIEs.list.count; edx++) {
297                 RICsubscriptionFailure_IEs_t *memb_ptr = _unsuccessMsg->value.choice.RICsubscriptionFailure.protocolIEs.list.array[edx];
298
299                 switch(memb_ptr->id)
300                 {
301                 case (ProtocolIE_ID_id_RICrequestID):
302                           _failureIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID);
303                           _failureIEs->set_ricInstanceID(memb_ptr->value.choice.RICrequestID.ricInstanceID);
304                 break;
305                 case (ProtocolIE_ID_id_RANfunctionID):
306                           _failureIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID);
307                 break;
308
309
310                 case (ProtocolIE_ID_id_RICactions_NotAdmitted):
311                         ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
312
313                         for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
314                                 RICaction_NotAdmitted_ItemIEs_t * item = (RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
315                                 long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
316                                 int cause = item->value.choice.RICaction_NotAdmitted_Item.cause.present;
317                                 int sub_cause;
318                                 switch(cause){
319
320                                         case  Cause_PR_ricService :
321                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
322                                                 break;
323
324                                         case Cause_PR_transport :
325                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
326                                                 break;
327
328                                         case  Cause_PR_protocol :
329                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
330                                                 break;
331
332                                         case Cause_PR_misc :
333                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
334                                                 break;
335
336                                         case Cause_PR_ricRequest :
337                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
338                                                 break;
339
340                                         default:
341                                                 mdclog_write(MDCLOG_DEBUG, "Error ! Illegal cause enum %d", cause);
342                                                 return false;
343                         }
344                         _notadmitlst.add(RICactionNotAdmittedList::RICactionNotAdmittedItemIEs().set_ricActionID(id).set_ricCause(cause).set_ricSubCause(sub_cause));
345                         this->getIEs().set_actionsNotAdmitted_list(_notadmitlst);
346                  }
347                 break;
348
349                 case (ProtocolIE_ID_id_CriticalityDiagnostics):
350
351                         _cdWrapperIEs.set_procedureCode(*(memb_ptr->value.choice.CriticalityDiagnostics.procedureCode));
352                         _cdWrapperIEs.set_procedureCriticality(*(memb_ptr->value.choice.CriticalityDiagnostics.procedureCriticality));
353                         _cdWrapperIEs.set_triggeringMessage(*(memb_ptr->value.choice.CriticalityDiagnostics.triggeringMessage));
354
355
356                         ricReq =  (RICrequestID_t*)memb_ptr->value.choice.CriticalityDiagnostics.ricRequestorID;
357                         _cdWrapperIEs.set_ricRequestorID(ricReq->ricRequestorID);
358                         _cdWrapperIEs.set_ricInstanceID(ricReq->ricInstanceID);
359
360                         int lstcount = memb_ptr->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list.count;
361                         auto *lst = _failureIEs->get_critical_diagnostic()->get_list();
362                         for(int i=0; i < lstcount; i++){
363                                 CriticalityDiagnosticsIEs tmpObj;
364                                 tmpObj.set_iEcriticality(memb_ptr->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list.array[i]->iECriticality);
365                                 tmpObj.set_ieID(memb_ptr->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list.array[i]->iE_ID);
366                                 tmpObj.set_typeOferror(memb_ptr->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list.array[i]->typeOfError);
367                                 _cdWrapperIEs.add(tmpObj);
368                          }
369                         _failureIEs->set_critical_diagnostic(_cdWrapperIEs);
370                         break;
371
372         }
373
374    }
375
376         return true;
377 }
378
379
380
381
382
383