E2AP Wrapper Implementation
[ric-app/hw.git] / src / xapp-asn / e2ap / e2ap_subscription_response.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_E2APSubscriptionResponse.cc
21  *
22  *
23  *      Author: SJana, Ashwin Sridharan
24  */
25 #include<e2ap_subscription_response.hpp>
26
27 E2APSubscriptionResponse::E2APSubscriptionResponse(SubscriptionResponseIEs& subObj){
28
29   _responseIEs = std::make_unique<SubscriptionResponseIEs>();
30   *_responseIEs = 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   _successMsg = 0;
37   _successMsg = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
38   assert(_successMsg != 0);
39
40
41
42   IE_array = 0;
43   IE_array = (RICsubscriptionResponse_IEs_t *)calloc(RIC_SUB_RESPONSE_IES_COUNT, sizeof(RICsubscriptionResponse_IEs_t));
44   assert(IE_array != 0);
45
46   ie_admitted_list = 0;
47
48   ie_not_admitted_list = 0;
49
50
51 };
52
53 // Clear assigned protocolIE list from RIC indication IE container
54 E2APSubscriptionResponse::~E2APSubscriptionResponse(void){
55
56   RICsubscriptionResponse_t * ric_subscriptionResponse = &(_successMsg->value.choice.RICsubscriptionResponse);
57   for(int i = 0; i < ric_subscriptionResponse->protocolIEs.list.size ; i++){
58           ric_subscriptionResponse->protocolIEs.list.array[i] = 0;
59   }
60
61   if (ric_subscriptionResponse->protocolIEs.list.size > 0){
62     free(ric_subscriptionResponse->protocolIEs.list.array);
63     ric_subscriptionResponse->protocolIEs.list.array = 0;
64     ric_subscriptionResponse->protocolIEs.list.size = 0;
65     ric_subscriptionResponse->protocolIEs.list.count = 0;
66   }
67
68   free(ie_admitted_list);
69   free(ie_not_admitted_list);
70   free(IE_array);
71   free(_successMsg);
72   _e2ap_pdu_obj->choice.successfulOutcome = 0;
73
74   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
75   mdclog_write(MDCLOG_DEBUG, "Freed Subscription Response Object memory");
76
77
78 };
79
80
81 bool E2APSubscriptionResponse::encode(unsigned char *buf, size_t *size){
82
83     _e2ap_pdu_obj->present =  E2AP_PDU_PR_successfulOutcome;
84     _e2ap_pdu_obj->choice.successfulOutcome = _successMsg;
85
86     bool eres = setfields( _successMsg);
87       if(!eres)
88           return eres;
89
90     _successMsg->procedureCode = ProcedureCode_id_RICsubscription;
91     _successMsg->criticality = Criticality_reject;
92     _successMsg->value.present = SuccessfulOutcome__value_PR_RICsubscriptionResponse;
93
94   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) _e2ap_pdu_obj, _errbuf, &_errbuf_len);
95   if(ret_constr){
96     _error_string.assign(_errbuf, _errbuf_len);
97     _error_string = "Constraints failed for encoding subscription response. Reason = " + _error_string;
98     return false;
99   }
100
101   asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj, buf, *size);
102   if(res.encoded == -1){
103     mdclog_write(MDCLOG_DEBUG, "Error encoding PDU. Reason =%s",strerror(errno));
104
105     return false;
106   }
107   else {
108     if(*size < res.encoded){
109       fprintf(stderr,  "Buffer assigned too small to encode: %s",(char *)(asn_DEF_E2AP_PDU.name));
110       res.encoded = -1;
111       return false;
112     }
113   }
114
115   *size = res.encoded;
116   xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
117   return true;
118
119 }
120
121 bool E2APSubscriptionResponse::setfields(SuccessfulOutcome_t *_successMsg){
122
123   int ie_index;
124
125
126   RICsubscriptionResponse_t * subsResponse = &(_successMsg->value.choice.RICsubscriptionResponse);
127   //reset list count ..
128   subsResponse->protocolIEs.list.count = 0;
129
130   ie_index = 0;
131   RICsubscriptionResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
132
133   ies_ricreq->criticality = Criticality_reject;
134   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
135   ies_ricreq->value.present = RICsubscriptionResponse_IEs__value_PR_RICrequestID;
136   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
137   ricrequest_ie->ricRequestorID = this->getIEs().get_ricRequestorID();
138   ricrequest_ie->ricInstanceID = this->getIEs().get_ricInstanceID();
139   ASN_SEQUENCE_ADD(&subsResponse->protocolIEs, &(IE_array[ie_index]));
140
141
142   ie_index++;
143   RICsubscriptionResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
144   ies_ranfunc->criticality = Criticality_reject;
145   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
146   ies_ranfunc->value.present = RICsubscriptionResponse_IEs__value_PR_RANfunctionID;
147   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
148   *ranfunction_ie = this->getIEs().get_ranFunctionID();
149   ASN_SEQUENCE_ADD(&subsResponse->protocolIEs, &(IE_array[ie_index]));
150
151
152   int admit_lst_count = 0;
153   if(this->getIEs().get_is_ricActionAdmitlst()){
154           admit_lst_count = this->getIEs().get_actionsAdmitted_list().get_list_count();
155
156           ie_index++;
157           RICsubscriptionResponse_IEs_t *ies_admitted_actid = &IE_array[ie_index];
158           ies_admitted_actid->criticality = Criticality_reject;
159           ies_admitted_actid->id = ProtocolIE_ID_id_RICactions_Admitted;
160           RICaction_Admitted_List_t *ric_admitted_actions_ie = &ies_admitted_actid->value.choice.RICaction_Admitted_List;
161           ric_admitted_actions_ie->list.count = 0;
162
163           std::vector<RICactionAdmittedList::RICactionAdmittedItemIEs> * ref_admitted_action_array = this->getIEs().get_actionsAdmitted_list().get_list();
164           if(admit_lst_count ==  0){
165              ies_admitted_actid->value.present =  RICsubscriptionResponse_IEs__value_PR_NOTHING;
166            }
167            else{
168              ies_admitted_actid->value.present =  RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
169            }
170           ie_admitted_list = (RICaction_Admitted_ItemIEs_t *)calloc(admit_lst_count, sizeof(RICaction_Admitted_ItemIEs_t));
171
172           assert(ie_admitted_list != 0);
173           for(unsigned int i = 0; i < ref_admitted_action_array->size(); i ++){
174                 ie_admitted_list[i].criticality = Criticality_ignore;
175                 ie_admitted_list[i].id = ProtocolIE_ID_id_RICaction_Admitted_Item ;
176                 ie_admitted_list[i].value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
177                 ie_admitted_list[i].value.choice.RICaction_Admitted_Item.ricActionID = (*ref_admitted_action_array)[i].get_ricActionID();
178                 ASN_SEQUENCE_ADD(ric_admitted_actions_ie, &(ie_admitted_list[i]));
179               }
180             ASN_SEQUENCE_ADD(&subsResponse->protocolIEs, &(IE_array[ie_index]));
181
182   }
183
184   if(this->getIEs().get_is_ricActionNotAdmitlst()){
185           int notadmit_lst_count = this->getIEs().get_actionsNotAdmitted_list().get_list_count();
186
187         ie_index++;
188         std::vector<RICactionNotAdmittedList::RICactionNotAdmittedItemIEs> * ref_notadmitted_action_array = this->getIEs().get_actionsNotAdmitted_list().get_list();
189
190     RICsubscriptionResponse_IEs_t *ies_notadmitted_actid = &IE_array[ie_index];
191     ies_notadmitted_actid->criticality = Criticality_reject;
192     ies_notadmitted_actid->id = ProtocolIE_ID_id_RICactions_NotAdmitted;
193
194     RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
195     ric_not_admitted_actions_ie->list.count = 0;
196
197
198     ies_notadmitted_actid->value.present =  RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
199
200
201     ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(notadmit_lst_count, sizeof(RICaction_NotAdmitted_ItemIEs_t));
202     assert(ie_not_admitted_list != 0);
203
204
205     for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
206       ie_not_admitted_list[i].criticality = Criticality_ignore;
207       ie_not_admitted_list[i].id = ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
208       ie_not_admitted_list[i].value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
209       ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_ricActionID();
210
211       int cause = (*ref_notadmitted_action_array)[i].get_ricCause();
212       switch(cause){
213           case Cause_PR_ricService:
214                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService = (*ref_notadmitted_action_array)[i].get_ricSubCause();
215                   break;
216           case Cause_PR_transport:
217                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.transport = (*ref_notadmitted_action_array)[i].get_ricSubCause();
218                   break;
219           case Cause_PR_protocol:
220                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol= (*ref_notadmitted_action_array)[i].get_ricSubCause();
221                   break;
222           case Cause_PR_misc:
223                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.misc = (*ref_notadmitted_action_array)[i].get_ricSubCause();
224                   break;
225           case Cause_PR_ricRequest:
226                   ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest = (*ref_notadmitted_action_array)[i].get_ricSubCause();
227                   break;
228           default:
229                   mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
230                   break;
231       }
232
233       ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.present = (Cause_PR)cause;
234       ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
235     }
236     ASN_SEQUENCE_ADD(&subsResponse->protocolIEs, &(IE_array[ie_index]));
237
238   }
239
240   return true;
241 }
242
243 E2APSubscriptionResponse::E2APSubscriptionResponse(unsigned char *buf, size_t *size){
244           _e2ap_pdu_obj = 0;
245           _successMsg = 0;
246           IE_array = 0;
247           ie_admitted_list = 0;
248           ie_not_admitted_list = 0;
249
250           _responseIEs = std::make_unique<SubscriptionResponseIEs>();
251            bool status =  this->decode(buf, size);
252            if(!status)
253                    throw "E2AP Subscription Delete Response Decode Failed: "+this->get_error();
254 }
255 bool E2APSubscriptionResponse:: decode(unsigned char *buf, size_t *size)
256 {
257
258         asn_dec_rval_t dec_res  = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&(_e2ap_pdu_obj), buf, *size);
259         if(dec_res.code != RC_OK){
260                         mdclog_write(MDCLOG_ERR, "Failed to decode: %s","RIC Subscription Response");
261                         return false;
262         } else {
263
264                 mdclog_write(MDCLOG_INFO, "Successfully decoded: %s","RIC Subscription Response");
265         }
266
267          _successMsg = _e2ap_pdu_obj->choice.successfulOutcome;
268          //write the decoding code.
269
270          if (_successMsg == 0){
271                 _error_string = "Invalid reference to success message in get fields subscription response";
272                 return false;
273          }
274
275         RANfunctionID_t * ranfunctionid;
276         RICaction_Admitted_List_t  * ric_admitted_action_list;
277         RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
278
279
280         for(int edx = 0; edx < _successMsg->value.choice.RICsubscriptionResponse.protocolIEs.list.count; edx++) {
281                 RICsubscriptionResponse_IEs_t *memb_ptr = _successMsg->value.choice.RICsubscriptionResponse.protocolIEs.list.array[edx];
282
283                 switch(memb_ptr->id)
284                 {
285                 case (ProtocolIE_ID_id_RICrequestID):
286                           _responseIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID);
287                           _responseIEs->set_ricInstanceID(memb_ptr->value.choice.RICrequestID.ricInstanceID);
288                 break;
289                 case (ProtocolIE_ID_id_RANfunctionID):
290                           _responseIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID);
291                 break;
292
293                 case (ProtocolIE_ID_id_RICactions_Admitted):
294                         ric_admitted_action_list = &memb_ptr->value.choice.RICaction_Admitted_List;
295                         for(int index = 0; index < ric_admitted_action_list->list.count; index ++){
296                                 RICaction_Admitted_ItemIEs_t * item = (RICaction_Admitted_ItemIEs_t *)ric_admitted_action_list->list.array[index];
297                                 long int id = item->value.choice.RICaction_Admitted_Item.ricActionID;
298                                 RICactionAdmittedList::RICactionAdmittedItemIEs ricActID; ricActID.set_ricActionID(id);
299                                 _admitlst.add(ricActID);
300                         };
301                         this->getIEs().set_actionsAdmitted_list(_admitlst);
302                 break;
303
304                 case (ProtocolIE_ID_id_RICactions_NotAdmitted):
305                         ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
306
307                         for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
308                                 RICaction_NotAdmitted_ItemIEs_t * item = (RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
309                                 long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
310                                 int cause = item->value.choice.RICaction_NotAdmitted_Item.cause.present;
311                                 int sub_cause;
312                                 switch(cause){
313
314                                         case  Cause_PR_ricService :
315                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
316                                                 break;
317
318                                         case Cause_PR_transport :
319                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
320                                                 break;
321
322                                         case  Cause_PR_protocol :
323                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
324                                                 break;
325
326                                         case Cause_PR_misc :
327                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
328                                                 break;
329
330                                         case Cause_PR_ricRequest :
331                                                 sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
332                                                 break;
333
334                                         default:
335                                                 mdclog_write(MDCLOG_DEBUG, "Error ! Illegal cause enum %d", cause);
336                                                 return false;
337                         }
338                         _notadmitlst.add(RICactionNotAdmittedList::RICactionNotAdmittedItemIEs().set_ricActionID(id).set_ricCause(cause).set_ricSubCause(sub_cause));
339                         this->getIEs().set_actionsNotAdmitted_list(_notadmitlst);
340                  }
341                 break;
342         }
343
344    }
345
346         return true;
347 }
348
349
350
351
352
353