Incorporating A1 HealthCheck functionality
[ric-app/hw.git] / src / xapp-formats / e2ap / e2ap_control_response.cc
1 /*
2 ==================================================================================
3
4         Copyright (c) 2018-2019 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  * ric_control_response.c
21  *
22  *  Created on: Jul 11, 2019
23  *      Author: sjana, Ashwin Sridharan
24  */
25
26 #include "e2ap_control_response.hpp"
27
28 // Set up the initiating message and also allocate protocolIEs in container
29 // Note : this bypasses requirement to use ASN_SEQUENCE_ADD. We can directly
30 // assign pointers to the array in ProtocolIE. However, this also leaves us on the
31 // hook to manually clear the memory
32
33 ric_control_response::ric_control_response(void){
34
35   e2ap_pdu_obj = 0;
36   e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
37   assert(e2ap_pdu_obj != 0);
38
39   successMsg = 0;
40   successMsg = (E2N_SuccessfulOutcome_t * )calloc(1, sizeof(E2N_SuccessfulOutcome_t));
41   assert(successMsg != 0);
42
43   successMsg->procedureCode = E2N_ProcedureCode_id_ricControl;
44   successMsg->criticality = E2N_Criticality_reject;
45   successMsg->value.present = E2N_SuccessfulOutcome__value_PR_RICcontrolAcknowledge;
46  
47   
48   unsuccessMsg = 0;
49   unsuccessMsg = (E2N_UnsuccessfulOutcome_t * )calloc(1, sizeof(E2N_UnsuccessfulOutcome_t));
50   assert(unsuccessMsg != 0);
51
52   
53   unsuccessMsg->procedureCode = E2N_ProcedureCode_id_ricControl;
54   unsuccessMsg->criticality = E2N_Criticality_reject;
55   unsuccessMsg->value.present = E2N_UnsuccessfulOutcome__value_PR_RICcontrolFailure;
56
57   IE_array = 0;
58   IE_array = (E2N_RICcontrolAcknowledge_IEs_t *)calloc(NUM_CONTROL_ACKNOWLEDGE_IES, sizeof(E2N_RICcontrolAcknowledge_IEs_t));
59   assert(IE_array != 0);
60
61   E2N_RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
62   for(int i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES; i++){
63     ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), &(IE_array[i]));
64   }
65   
66
67   IE_failure_array = 0;
68   IE_failure_array = (E2N_RICcontrolFailure_IEs_t *)calloc(NUM_CONTROL_FAILURE_IES, sizeof(E2N_RICcontrolFailure_IEs_t));
69   assert(IE_failure_array != 0);
70
71   E2N_RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
72   for(int i = 0; i < NUM_CONTROL_FAILURE_IES; i++){
73     ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), &(IE_failure_array[i]));
74   }
75   
76 };
77
78
79 // Clear assigned protocolIE list from RIC control_request IE container
80 ric_control_response::~ric_control_response(void){
81
82   mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Response object memory");
83   
84   E2N_RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
85   for(int i  = 0; i < ric_acknowledge->protocolIEs.list.size; i++){
86     ric_acknowledge->protocolIEs.list.array[i] = 0;
87   }
88   if (ric_acknowledge->protocolIEs.list.size > 0){
89     free(ric_acknowledge->protocolIEs.list.array);
90     ric_acknowledge->protocolIEs.list.array = 0;
91     ric_acknowledge->protocolIEs.list.count = 0;
92   }
93
94   E2N_RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
95   for(int i  = 0; i < ric_failure->protocolIEs.list.size; i++){
96     ric_failure->protocolIEs.list.array[i] = 0;
97   }
98   if (ric_failure->protocolIEs.list.size > 0){
99     free(ric_failure->protocolIEs.list.array);
100     ric_failure->protocolIEs.list.array = 0;
101     ric_failure->protocolIEs.list.count = 0;
102   }
103   
104   free(IE_array);
105   free(IE_failure_array);
106   free(successMsg);
107   free(unsuccessMsg);
108
109   e2ap_pdu_obj->choice.initiatingMessage = 0;
110   e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
111   
112   ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
113   mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Response object mempory");
114 }
115
116
117 bool ric_control_response::encode_e2ap_control_response(unsigned char *buf, size_t *size, ric_control_helper & dinput, bool is_success){
118
119   bool res;
120   if (is_success){
121     res = set_fields(successMsg, dinput);
122   }
123   else{
124     res = set_fields(unsuccessMsg, dinput);
125   }
126   
127   if (!res){
128     return false;
129   }
130
131   
132   if (is_success){
133     e2ap_pdu_obj->choice.successfulOutcome = successMsg;
134     e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_successfulOutcome ;
135   }
136   else{
137     e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
138     e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_unsuccessfulOutcome ;
139
140   }
141
142   //xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
143   
144   int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
145   if(ret_constr){
146     error_string.assign(errbuf, errbuf_len);
147     error_string = "Constraints failed for encoding control response. Reason = " + error_string;
148     return false;
149   }
150   
151   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
152   
153   if(retval.encoded == -1){
154     error_string.assign(strerror(errno));
155     return false;
156   }
157   else {
158     if(*size < retval.encoded){
159       std::stringstream ss;
160       ss  <<"Error encoding E2AP Control response . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
161       error_string = ss.str();
162       return false;
163     }
164   }
165
166   *size = retval.encoded;
167   return true;
168   
169 }
170
171 bool ric_control_response::set_fields(E2N_SuccessfulOutcome_t *successMsg, ric_control_helper &dinput){
172   unsigned int ie_index;
173
174   if (successMsg == 0){
175     error_string = "Invalid reference for E2AP Control Acknowledge in set_fields";
176     return false;
177   }
178
179   // for(i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES;i++){
180   //   memset(&(IE_array[i]), 0, sizeof(RICcontrolAcknowledge_IEs_t));
181   // }
182
183   //E2N_RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
184   //ric_acknowledge->protocolIEs.list.count = 0;
185   
186   ie_index = 0;
187   E2N_RICcontrolAcknowledge_IEs_t *ies_ricreq = &IE_array[ie_index];  
188   ies_ricreq->criticality = E2N_Criticality_reject;
189   ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
190   ies_ricreq->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RICrequestID;
191   E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
192   ricrequest_ie->ricRequestorID = dinput.req_id;
193   ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
194   //ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ricreq);
195   
196   ie_index = 1;
197   E2N_RICcontrolAcknowledge_IEs_t *ies_ranfunc = &IE_array[ie_index];
198   ies_ranfunc->criticality = E2N_Criticality_reject;
199   ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
200   ies_ranfunc->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RANfunctionID;
201   E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
202   *ranfunction_ie = dinput.func_id;
203   //ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ranfunc);
204
205   // ie_index = 2;
206   // E2N_RICcontrolAcknowledge_IEs_t *ies_riccallprocessid = &IE_array[ie_index];
207   // ies_riccallprocessid->criticality = E2N_Criticality_reject;
208   // ies_riccallprocessid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
209   // ies_riccallprocessid->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RICcallProcessID;
210   // RICcallProcessID_t *riccallprocessid_ie = &ies_riccallprocessid->value.choice.RICcallProcessID;
211   // riccallprocessid_ie->buf = dinput.call_process_id;
212   // riccallprocessid_ie->size = dinput.call_process_id_size;
213   // ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_riccallprocessid);
214   
215   ie_index = 2;
216   E2N_RICcontrolAcknowledge_IEs_t *ies_ric_cause = &IE_array[ie_index];
217   ies_ric_cause->criticality = E2N_Criticality_reject;
218   ies_ric_cause->id = E2N_ProtocolIE_ID_id_RICcontrolStatus;
219   ies_ric_cause->value.present = E2N_RICcontrolAcknowledge_IEs__value_PR_RICcontrolStatus;
220   ies_ric_cause->value.choice.RICcontrolStatus = dinput.control_status;  
221   //ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ric_cause);
222   
223   return true;
224
225 };
226
227 bool ric_control_response::set_fields(E2N_UnsuccessfulOutcome_t *unsuccessMsg, ric_control_helper &dinput){
228   unsigned int ie_index;
229
230   if (unsuccessMsg == 0){
231     error_string = "Invalid reference for E2AP Control Failure in set_fields";
232     return false;
233   }
234   
235   // for(i = 0; i < NUM_CONTROL_FAILURE_IES;i++){
236   //   memset(&(IE_failure_array[i]), 0, sizeof(RICcontrolFailure_IEs_t));
237   // }
238
239   //E2N_RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
240   //ric_failure->protocolIEs.list.count = 0;
241   
242   ie_index = 0;
243   E2N_RICcontrolFailure_IEs_t *ies_ricreq = &IE_failure_array[ie_index];  
244   ies_ricreq->criticality = E2N_Criticality_reject;
245   ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
246   ies_ricreq->value.present = E2N_RICcontrolFailure_IEs__value_PR_RICrequestID;
247   E2N_RICrequestID_t *ricrequest_ie = &(ies_ricreq->value.choice.RICrequestID);
248   ricrequest_ie->ricRequestorID = dinput.req_id;
249   ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
250   //ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ricreq);
251   
252   ie_index = 1;
253   E2N_RICcontrolFailure_IEs_t *ies_ranfunc = &IE_failure_array[ie_index];
254   ies_ranfunc->criticality = E2N_Criticality_reject;
255   ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
256   ies_ranfunc->value.present = E2N_RICcontrolFailure_IEs__value_PR_RANfunctionID;
257   E2N_RANfunctionID_t *ranfunction_ie = &(ies_ranfunc->value.choice.RANfunctionID);
258   *ranfunction_ie = dinput.func_id;
259   //ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ranfunc);
260
261   // ie_index = 2;
262   // E2N_RICcontrolFailure_IEs_t *ies_riccallprocessid = &IE_failure_array[i];
263   // ies_riccallprocessid->criticality = E2N_Criticality_reject;
264   // ies_riccallprocessid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
265   // ies_riccallprocessid->value.present = E2N_RICcontrolFailure_IEs__value_PR_RICcallProcessID;
266   // RICcallProcessID_t *riccallprocessid_ie = &(ies_riccallprocessid->value.choice.RICcallProcessID);
267   // riccallprocessid_ie->buf = dinput.call_process_id;
268   // riccallprocessid_ie->size = dinput.call_process_id_size;
269   // ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_riccallprocessid);
270   
271   ie_index = 2;
272   E2N_RICcontrolFailure_IEs_t *ies_ric_cause = &IE_failure_array[ie_index];
273   ies_ric_cause->criticality = E2N_Criticality_ignore;
274   ies_ric_cause->id = E2N_ProtocolIE_ID_id_RICcause;
275   ies_ric_cause->value.present = E2N_RICcontrolFailure_IEs__value_PR_RICcause;
276   E2N_RICcause_t * ric_cause = &(ies_ric_cause->value.choice.RICcause);
277   ric_cause->present = (E2N_RICcause_PR)dinput.cause;
278   
279   switch(dinput.cause){
280   case E2N_RICcause_PR_radioNetwork:
281     ric_cause->choice.radioNetwork = dinput.sub_cause;
282     break;
283   case E2N_RICcause_PR_transport:
284     ric_cause->choice.transport = dinput.sub_cause;
285     break;
286   case E2N_RICcause_PR_protocol:
287     ric_cause->choice.protocol= dinput.sub_cause;
288     break;
289   case E2N_RICcause_PR_misc:
290     ric_cause->choice.misc = dinput.sub_cause;
291     break;
292   case E2N_RICcause_PR_ric:
293     ric_cause->choice.ric = dinput.sub_cause;
294     break;
295   default:
296     std::cout <<"Error ! Illegal cause enum" << dinput.cause << std::endl;
297     return false;
298   }
299   
300   //ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ric_cause);
301   return true;
302
303 };
304
305   
306
307
308 bool ric_control_response:: get_fields(E2N_SuccessfulOutcome_t * success_msg,  ric_control_helper &dout)
309 {
310   if (success_msg == 0){
311     error_string = "Invalid reference for E2AP Control Acknowledge message in get_fields";
312     return false;
313   }
314   
315   
316   for(int edx = 0; edx < success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.count; edx++) {
317     E2N_RICcontrolAcknowledge_IEs_t *memb_ptr = success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.array[edx];
318     
319     switch(memb_ptr->id)
320       {
321         
322       case (E2N_ProtocolIE_ID_id_RICcallProcessID):
323         dout.call_process_id =  memb_ptr->value.choice.RICcallProcessID.buf;
324         dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
325         break;
326
327       case (E2N_ProtocolIE_ID_id_RICrequestID):
328         dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
329         dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
330         break;
331         
332       case (E2N_ProtocolIE_ID_id_RANfunctionID):
333         dout.func_id = memb_ptr->value.choice.RANfunctionID;
334         break;
335         
336       case (E2N_ProtocolIE_ID_id_RICcause):
337         dout.control_status = memb_ptr->value.choice.RICcontrolStatus;
338         break;
339         
340       }
341     
342   }
343   
344   return true;
345
346 }
347
348
349 bool ric_control_response:: get_fields(E2N_UnsuccessfulOutcome_t * unsuccess_msg,  ric_control_helper &dout)
350 {
351   if (unsuccess_msg == 0){
352     error_string = "Invalid reference for E2AP Control Failure message in get_fields";
353     return false;
354   }
355   
356   
357   for(int edx = 0; edx < unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.count; edx++) {
358     E2N_RICcontrolFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.array[edx];
359     
360     switch(memb_ptr->id)
361       {
362         
363       case (E2N_ProtocolIE_ID_id_RICcallProcessID):
364         dout.call_process_id =  memb_ptr->value.choice.RICcallProcessID.buf;
365         dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
366         break;
367
368       case (E2N_ProtocolIE_ID_id_RICrequestID):
369         dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
370         dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
371         break;
372         
373       case (E2N_ProtocolIE_ID_id_RANfunctionID):
374         dout.func_id = memb_ptr->value.choice.RANfunctionID;
375         break;
376         
377         
378       case (E2N_ProtocolIE_ID_id_RICcause):
379         dout.cause = memb_ptr->value.choice.RICcause.present;
380         switch(dout.cause){
381           case  E2N_RICcause_PR_radioNetwork :
382             dout.sub_cause = memb_ptr->value.choice.RICcause.choice.radioNetwork;
383             break;
384               
385           case E2N_RICcause_PR_transport :
386             dout.sub_cause = memb_ptr->value.choice.RICcause.choice.transport;
387             break;
388               
389           case  E2N_RICcause_PR_protocol :
390             dout.sub_cause = memb_ptr->value.choice.RICcause.choice.protocol;
391             break;
392               
393           case E2N_RICcause_PR_misc :
394             dout.sub_cause = memb_ptr->value.choice.RICcause.choice.misc;
395             break;
396               
397           case E2N_RICcause_PR_ric :
398             dout.sub_cause = memb_ptr->value.choice.RICcause.choice.ric;
399             break;
400                 
401         default:
402           dout.sub_cause = -1;
403           break;
404         }       
405
406       default:
407         break;
408       }
409     
410   }
411   
412   return true;
413   
414 }
415