Control Message Encode/Decode
[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         xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
106
107         int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) _e2ap_pdu_obj, _errbuf, &_errbuf_len);
108         if(ret_constr){
109                 _error_string.assign(_errbuf, _errbuf_len);
110                 _error_string = "Constraints failed for encoding control response. Reason = " + _error_string;
111                 return false;
112         }
113
114         asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj, buf, *size);
115
116         if(retval.encoded == -1){
117                 _error_string.assign(strerror(errno));
118                 return false;
119         }
120         else {
121                 if(*size < retval.encoded){
122                         std::stringstream ss;
123                         ss  <<"Error encoding E2AP Control response . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
124                         _error_string = ss.str();
125                         return false;
126                 }
127         }
128
129         *size = retval.encoded;
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 = 1;
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 = 2;
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                 std::cout <<"Error ! Illegal cause enum" << this->getIEs().get_ricCause() << std::endl;
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           xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
238
239           _unsuccessMsg = _e2ap_pdu_obj->choice.unsuccessfulOutcome;
240           //write the decoding code.
241
242
243         if (_unsuccessMsg == 0){
244                 _error_string = "Invalid reference for E2AP Control Failure message in get_fields";
245                 return false;
246         }
247
248
249         for(int edx = 0; edx < _unsuccessMsg->value.choice.RICcontrolFailure.protocolIEs.list.count; edx++) {
250                 RICcontrolFailure_IEs_t *memb_ptr = _unsuccessMsg->value.choice.RICcontrolFailure.protocolIEs.list.array[edx];
251
252                 switch(memb_ptr->id)
253                 {
254
255                 case (ProtocolIE_ID_id_RICcallProcessID):
256                 _cntrlIEs->set_ricCallProcessID(memb_ptr->value.choice.RICcallProcessID.buf, memb_ptr->value.choice.RICcallProcessID.size);
257                 break;
258
259                 case (ProtocolIE_ID_id_RICrequestID):
260                 _cntrlIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID);
261                 _cntrlIEs->set_ricInstanceID(memb_ptr->value.choice.RICrequestID.ricInstanceID);
262                 break;
263
264                 case (ProtocolIE_ID_id_RANfunctionID):
265                 _cntrlIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID);
266                 break;
267
268                 case (ProtocolIE_ID_id_Cause):
269
270                 _cntrlIEs->set_ricCause(memb_ptr->value.choice.Cause.present);
271                                 switch(memb_ptr->value.choice.Cause.present){
272                                 case  Cause_PR_ricService :
273                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.ricService);
274                                         break;
275
276                                 case Cause_PR_transport :
277                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.transport);
278                                         break;
279
280                                 case  Cause_PR_protocol :
281                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.protocol);
282                                         break;
283
284                                 case Cause_PR_misc :
285                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.misc);
286                                         break;
287
288                                 case Cause_PR_ricRequest :
289                                         _cntrlIEs->set_ricSubCause(memb_ptr->value.choice.Cause.choice.ricRequest);
290                                         break;
291
292                                 default:
293                                         _cntrlIEs->set_ricSubCause(-1);
294                                         break;
295                                 }
296
297
298                 break;
299
300                 case (ProtocolIE_ID_id_RICcontrolOutcome):
301                 _cntrlIEs->set_ricControlOutcome(memb_ptr->value.choice.RICcontrolOutcome.buf, memb_ptr->value.choice.RICcontrolOutcome.size);
302                 break;
303
304                 }
305
306         }
307
308         return true;
309
310 }
311
312
313