E2AP Wrapper Implementation
[ric-app/hw.git] / src / xapp-asn / e2ap / e2ap_control_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_control_failure.cc
21  *
22  * Author: SJana, Ashwin Sridharan
23  */
24
25 #include "e2ap_control_failure.hpp"
26
27
28 E2APControlFailure::E2APControlFailure(ControlFailureIEs &cntrlObj){
29         _cntrlIEs = std::make_unique<ControlFailureIEs>();
30         *_cntrlIEs = cntrlObj;
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         _unsuccessMsg->procedureCode = ProcedureCode_id_RICcontrol;
41         _unsuccessMsg->criticality = Criticality_reject;
42         _unsuccessMsg->value.present = UnsuccessfulOutcome__value_PR_RICcontrolFailure;
43
44
45         IE_array = 0;
46         IE_array = (RICcontrolFailure_IEs_t *)calloc(RIC_CONTROL_FAILURE_IES_COUNT, sizeof(RICcontrolFailure_IEs_t));
47         assert(IE_array != 0);
48
49         RICcontrolFailure_t * ric_failure = &(_unsuccessMsg->value.choice.RICcontrolFailure);
50         for(int i = 0; i < RIC_CONTROL_FAILURE_IES_COUNT; i++){
51                 ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), &(IE_array[i]));
52         }
53
54 };
55
56 E2APControlFailure::E2APControlFailure(unsigned char *buf, size_t *size){
57           _e2ap_pdu_obj = 0;
58           _unsuccessMsg = 0;
59           IE_array = 0;
60
61           _cntrlIEs = std::make_unique<ControlFailureIEs>();
62            bool status =  this->decode(buf, size);
63            if(!status)
64                    throw "E2AP Control Failure Decode Failed: "+this->get_error();
65 }
66
67
68 // Clear assigned protocolIE list from RIC control_request IE container
69 E2APControlFailure::~E2APControlFailure(void){
70
71         mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Response object memory");
72
73         RICcontrolFailure_t * ric_failure = &(_unsuccessMsg->value.choice.RICcontrolFailure);
74         for(int i  = 0; i < ric_failure->protocolIEs.list.size; i++){
75                 ric_failure->protocolIEs.list.array[i] = 0;
76         }
77         if (ric_failure->protocolIEs.list.size > 0){
78                 free(ric_failure->protocolIEs.list.array);
79                 ric_failure->protocolIEs.list.array = 0;
80                 ric_failure->protocolIEs.list.count = 0;
81         }
82
83
84         free(IE_array);
85         free(_unsuccessMsg);
86
87         _e2ap_pdu_obj->choice.unsuccessfulOutcome = 0;
88         _e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome;
89
90         ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
91         mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Response object memory");
92 }
93
94
95 bool E2APControlFailure::encode(unsigned char *buf, size_t *size){
96
97         bool res;
98         res = setfields(_unsuccessMsg);
99         if (!res){
100                 return false;
101         }
102         _e2ap_pdu_obj->choice.unsuccessfulOutcome = _unsuccessMsg;
103         _e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome ;
104
105         int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) _e2ap_pdu_obj, _errbuf, &_errbuf_len);
106         if(ret_constr){
107                 _error_string.assign(_errbuf, _errbuf_len);
108                 _error_string = "Constraints failed for encoding control response. Reason = " + _error_string;
109                 return false;
110         }
111
112         asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj, buf, *size);
113
114         if(retval.encoded == -1){
115                 _error_string.assign(strerror(errno));
116                 return false;
117         }
118         else {
119                 if(*size < retval.encoded){
120                         std::stringstream ss;
121                         ss  <<"Error encoding E2AP Control response . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
122                         _error_string = ss.str();
123                         return false;
124                 }
125         }
126
127         *size = retval.encoded;
128         xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
129
130         return true;
131
132 }
133
134 bool E2APControlFailure::setfields(UnsuccessfulOutcome_t *successMsg){
135         unsigned int ie_index;
136
137         if (successMsg == 0){
138                 _error_string = "Invalid reference for E2AP Control Failure in set_fields";
139                 return false;
140         }
141
142         RICcontrolFailure_t * ric_failure = &(successMsg->value.choice.RICcontrolFailure);
143         ric_failure->protocolIEs.list.count = 0;
144
145         ie_index = 0;
146         RICcontrolFailure_IEs_t *ies_ricreq = &IE_array[ie_index];
147         ies_ricreq->criticality = Criticality_reject;
148         ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
149         ies_ricreq->value.present = RICcontrolFailure_IEs__value_PR_RICrequestID;
150
151         RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
152         ricrequest_ie->ricRequestorID = this->getIEs().get_ricRequestorID();
153         ricrequest_ie->ricInstanceID = this->getIEs().get_ricInstanceID();
154         ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ricreq);
155
156         ie_index++;
157         RICcontrolFailure_IEs_t *ies_ranfunc = &IE_array[ie_index];
158         ies_ranfunc->criticality = Criticality_reject;
159         ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
160         ies_ranfunc->value.present = RICcontrolFailure_IEs__value_PR_RANfunctionID;
161
162         RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
163         *ranfunction_ie = this->getIEs().get_ranFunctionID();
164         ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ranfunc);
165
166         ie_index++;
167         RICcontrolFailure_IEs_t *ies_ric_cause = &IE_array[ie_index];
168         ies_ric_cause->criticality = Criticality_ignore;
169         ies_ric_cause->id = ProtocolIE_ID_id_Cause;
170         ies_ric_cause->value.present = RICcontrolFailure_IEs__value_PR_Cause;
171         Cause_t * ric_cause = &(ies_ric_cause->value.choice.Cause);
172         ric_cause->present = (Cause_PR)this->getIEs().get_ricCause();
173         switch(this->getIEs().get_ricCause()){
174         case Cause_PR_ricService:
175                 ric_cause->choice.ricService = this->getIEs().get_ricSubCause();
176                 break;
177         case Cause_PR_transport:
178                 ric_cause->choice.transport = this->getIEs().get_ricSubCause();
179                 break;
180         case Cause_PR_protocol:
181                 ric_cause->choice.protocol= this->getIEs().get_ricSubCause();
182                 break;
183         case Cause_PR_misc:
184                 ric_cause->choice.misc = this->getIEs().get_ricSubCause();
185                 break;
186         case Cause_PR_ricRequest:
187                 ric_cause->choice.ricRequest = this->getIEs().get_ricSubCause();
188                 break;
189         default:
190                  mdclog_write(MDCLOG_INFO, "Error ! Illegal cause enum %ld",this->getIEs().get_ricCause());
191                  return false;
192         }
193         ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ric_cause);
194
195     if(this->getIEs().get_is_ricCallProcessId()){
196         ie_index++;
197         RICcontrolFailure_IEs_t *ies_riccallprocessid = &IE_array[ie_index];
198         ies_riccallprocessid->criticality = Criticality_reject;
199         ies_riccallprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
200         ies_riccallprocessid->value.present = RICcontrolFailure_IEs__value_PR_RICcallProcessID;
201         RICcallProcessID_t *riccallprocessid_ie = &ies_riccallprocessid->value.choice.RICcallProcessID;
202         riccallprocessid_ie->buf = (uint8_t*)this->getIEs().get_ricCallProcessId();
203         riccallprocessid_ie->size = this->getIEs().get_ricCallProcessId_size();
204         ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_riccallprocessid);
205
206     }
207     if(this->getIEs().get_is_ricControlOutcome()){
208                 ie_index++;
209                 RICcontrolFailure_IEs_t *ies_ricControlOutcome = &IE_array[ie_index];
210                 ies_ricControlOutcome->criticality = Criticality_reject;
211                 ies_ricControlOutcome->id = ProtocolIE_ID_id_RICcallProcessID;
212                 ies_ricControlOutcome->value.present = RICcontrolFailure_IEs__value_PR_RICcontrolOutcome;
213                 RICcontrolOutcome_t *ricControlOutcome_ie = &ies_ricControlOutcome->value.choice.RICcallProcessID;
214                 ricControlOutcome_ie->buf = (uint8_t*)this->getIEs().get_ricControlOutcome();
215                 ricControlOutcome_ie->size = this->getIEs().get_ricControlOutcome_size();
216                 ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ricControlOutcome);
217
218         }
219
220
221
222         return true;
223
224 };
225
226
227 bool E2APControlFailure::decode(unsigned char *buf, size_t *size)
228 {
229         asn_dec_rval_t dec_res  = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&(_e2ap_pdu_obj), buf, *size);
230         if(dec_res.code != RC_OK){
231                                  mdclog_write(MDCLOG_ERR, "Failed to decode: %s","RIC Control Ack Message");
232                                  return false;
233         } else {
234                                  mdclog_write(MDCLOG_INFO, "Successfully decoded: %s","RIC Control Ack Message");
235         }
236
237
238           _unsuccessMsg = _e2ap_pdu_obj->choice.unsuccessfulOutcome;
239           //write the decoding code.
240
241
242         if (_unsuccessMsg == 0){
243                 _error_string = "Invalid reference for E2AP Control Failure message in get_fields";
244                 return false;
245         }
246
247
248         for(int edx = 0; edx < _unsuccessMsg->value.choice.RICcontrolFailure.protocolIEs.list.count; edx++) {
249                 RICcontrolFailure_IEs_t *memb_ptr = _unsuccessMsg->value.choice.RICcontrolFailure.protocolIEs.list.array[edx];
250
251                 switch(memb_ptr->id)
252                 {
253
254                 case (ProtocolIE_ID_id_RICcallProcessID):
255                 _cntrlIEs->set_ricCallProcessID(memb_ptr->value.choice.RICcallProcessID.buf, memb_ptr->value.choice.RICcallProcessID.size);
256                 break;
257
258                 case (ProtocolIE_ID_id_RICrequestID):
259                 _cntrlIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID);
260                 _cntrlIEs->set_ricInstanceID(memb_ptr->value.choice.RICrequestID.ricInstanceID);
261                 break;
262
263                 case (ProtocolIE_ID_id_RANfunctionID):
264                 _cntrlIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID);
265                 break;
266
267                 case (ProtocolIE_ID_id_Cause):
268
269                 _cntrlIEs->set_ricCause(memb_ptr->value.choice.Cause.present);
270                                 switch(memb_ptr->value.choice.Cause.present){
271                                 case  Cause_PR_ricService :
272                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.ricService);
273                                         break;
274
275                                 case Cause_PR_transport :
276                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.transport);
277                                         break;
278
279                                 case  Cause_PR_protocol :
280                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.protocol);
281                                         break;
282
283                                 case Cause_PR_misc :
284                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.misc);
285                                         break;
286
287                                 case Cause_PR_ricRequest :
288                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.ricRequest);
289                                         break;
290
291                                 default:
292                                         _cntrlIEs->set_ricSubCause(-1);
293                                         break;
294                                 }
295
296
297                 break;
298
299                 case (ProtocolIE_ID_id_RICcontrolOutcome):
300                 _cntrlIEs->set_ricControlOutcome(memb_ptr->value.choice.RICcontrolOutcome.buf, memb_ptr->value.choice.RICcontrolOutcome.size);
301                 break;
302
303                 }
304
305         }
306         //xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
307
308         return true;
309
310 }
311
312
313