d64f620b499aa513757a12f47329d117959db2db
[ric-app/admin.git] / src / X2AP / sgnb_addition_response.cc
1 /*
2 ==================================================================================
3         Copyright (c) 2018-2019 AT&T Intellectual Property.
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 ==================================================================================
17 */
18 /*
19  * sgnb_addition_response.cc
20  *
21  *  Created on: Aug 22, 2019
22  *      Author: sjana
23  */
24
25 #include <sgnb_addition_response.hpp>
26
27 sgnb_addition_response::sgnb_addition_response(void ) {
28   
29
30   x2ap_pdu_obj = 0;
31   x2ap_pdu_obj = (X2AP_PDU_t * )calloc(1, sizeof(X2AP_PDU_t));
32   assert(x2ap_pdu_obj != 0);
33
34   successMsg = 0;
35   successMsg = (X2SuccessfulOutcome_t * )calloc(1, sizeof(X2SuccessfulOutcome_t));
36   assert(successMsg != 0);
37
38   unsuccessMsg = 0;
39   unsuccessMsg = (X2UnsuccessfulOutcome_t * )calloc(1, sizeof(X2UnsuccessfulOutcome_t));
40   assert(unsuccessMsg != 0);
41
42   IE_array = 0;
43   IE_array = (SgNBAdditionRequestAcknowledge_IEs_t *)calloc(NUM_SGNB_ADDITION_RESPONSE_ACKNOWLEDGE_IES, sizeof(SgNBAdditionRequestAcknowledge_IEs_t));
44   assert(IE_array != 0);
45
46   IE_reject_array = 0;
47   IE_reject_array = (SgNBAdditionRequestReject_IEs_t *)calloc(NUM_SGNB_ADDITION_RESPONSE_FAILURE_IES, sizeof(SgNBAdditionRequestReject_IEs_t));
48   assert(IE_reject_array != 0);
49   
50   
51   erab_admit_array = 0;
52   erab_admit_array = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t * ) calloc(INITIAL_SIZE, sizeof(E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t));
53   assert(erab_admit_array != 0);
54   erab_admit_array_size = INITIAL_SIZE;
55
56
57   erab_sgnb_present_array = 0;
58   erab_sgnb_present_array = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t *) calloc(INITIAL_SIZE, sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t));
59   assert(erab_sgnb_present_array != 0);
60   erab_sgnb_present_array_size = INITIAL_SIZE;
61   
62   erab_sgnb_notpresent_array = 0;
63   erab_sgnb_notpresent_array = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t *) calloc(INITIAL_SIZE, sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t));
64   assert(erab_sgnb_notpresent_array != 0);
65   erab_sgnb_notpresent_array_size = INITIAL_SIZE;
66
67   SgNBAdditionRequestAcknowledge_t * sgnb_ack = &(successMsg->value.choice.SgNBAdditionRequestAcknowledge);
68   for(int i = 0; i < NUM_SGNB_ADDITION_RESPONSE_ACKNOWLEDGE_IES; i++){
69     ASN_SEQUENCE_ADD(&(sgnb_ack->protocolIEs), &(IE_array[i]));
70   }
71   
72   
73   SgNBAdditionRequestReject_t * sgnb_reject = &(unsuccessMsg->value.choice.SgNBAdditionRequestReject);
74   for(int i = 0; i < NUM_SGNB_ADDITION_RESPONSE_FAILURE_IES; i++){
75     ASN_SEQUENCE_ADD(&(sgnb_reject->protocolIEs), &(IE_reject_array[i]));
76   }
77
78 }
79
80 sgnb_addition_response::~sgnb_addition_response(void){
81
82   mdclog_write(MDCLOG_INFO, "Freeing X2AP SgNB Addition Response object memory");
83
84   E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList_t  * erabs_toadd_list = &(IE_array[3].value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList);
85   for(int i = 0; i < erabs_toadd_list->list.size; i++){
86     erabs_toadd_list->list.array[i] = 0;
87   }
88   if (erabs_toadd_list->list.size > 0){
89     free(erabs_toadd_list->list.array);
90     erabs_toadd_list->list.array = 0;
91     erabs_toadd_list->list.size = 0;
92     erabs_toadd_list->list.count= 0;
93   }
94   
95   free(erab_sgnb_present_array);
96   free(erab_sgnb_notpresent_array);
97   free(erab_admit_array);
98
99   SgNBAdditionRequestAcknowledge_t *sgnb_ack  = &(successMsg->value.choice.SgNBAdditionRequestAcknowledge);
100   for(int i = 0; i < sgnb_ack->protocolIEs.list.size; i++){
101     sgnb_ack->protocolIEs.list.array[i] = 0;
102   }
103
104   if (sgnb_ack->protocolIEs.list.size > 0){
105     free(sgnb_ack->protocolIEs.list.array);
106     sgnb_ack->protocolIEs.list.array = 0;
107     sgnb_ack->protocolIEs.list.size = 0;
108   }
109   
110   SgNBAdditionRequestReject_t *sgnb_reject  = &(unsuccessMsg->value.choice.SgNBAdditionRequestReject);
111    for(int i = 0; i < sgnb_reject->protocolIEs.list.size; i++){
112      sgnb_reject->protocolIEs.list.array[i] = 0;
113    }
114
115    if (sgnb_reject->protocolIEs.list.size > 0){
116      free(sgnb_reject->protocolIEs.list.array);
117      sgnb_reject->protocolIEs.list.array = 0;
118      sgnb_reject->protocolIEs.list.size = 0;
119    }
120
121
122   free(IE_array);
123   free(IE_reject_array);
124   free(successMsg);
125   free(unsuccessMsg);
126
127   x2ap_pdu_obj->choice.initiatingMessage = NULL;
128   x2ap_pdu_obj->present = X2AP_PDU_PR_NOTHING;
129   
130   ASN_STRUCT_FREE(asn_DEF_X2AP_PDU, x2ap_pdu_obj);
131
132   mdclog_write(MDCLOG_INFO, "Freed X2AP SgNB Addition Response object memory");
133 }
134
135 bool sgnb_addition_response::set_fields(X2UnsuccessfulOutcome_t * unsuccessMsg, sgnb_addition_helper &sgnb_data){
136   
137   unsigned ie_index = 0;
138
139   if (unsuccessMsg == 0){
140     error_string = "Invalid reference for X2AP Sgnb Addition Reject message in set_fields";
141     return false;
142   }
143   SgNBAdditionRequestReject_IEs_t *ies_sgnb_add_reject;
144
145   ie_index = 0;
146   ies_sgnb_add_reject= &IE_reject_array[ie_index];
147   ies_sgnb_add_reject->criticality = Criticality_reject;
148   ies_sgnb_add_reject->id = ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
149   ies_sgnb_add_reject->value.present = SgNBAdditionRequestReject_IEs__value_PR_UE_X2AP_ID;
150   ies_sgnb_add_reject->value.choice.UE_X2AP_ID = sgnb_data.menb_ue_x2ap_id;
151
152
153   ie_index = 1;
154   ies_sgnb_add_reject= &IE_reject_array[ie_index];
155   ies_sgnb_add_reject->criticality = Criticality_reject;
156   ies_sgnb_add_reject->id = ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
157   ies_sgnb_add_reject->value.present = SgNBAdditionRequestReject_IEs__value_PR_SgNB_UE_X2AP_ID;
158   ies_sgnb_add_reject->value.choice.SgNB_UE_X2AP_ID = sgnb_data.sgnb_ue_x2ap_id;
159
160
161   ie_index = 2;
162   ies_sgnb_add_reject= &IE_reject_array[ie_index];
163   ies_sgnb_add_reject->criticality = Criticality_reject;
164   ies_sgnb_add_reject->id = ProtocolIE_ID_id_Cause;
165   ies_sgnb_add_reject->value.present = SgNBAdditionRequestReject_IEs__value_PR_Cause;
166   Cause_t *caus = &ies_sgnb_add_reject->value.choice.Cause;
167
168   switch(sgnb_data.cause)
169     {
170     case Cause_PR_misc: //Misc
171       caus->present = Cause_PR_misc;
172       caus->choice.misc = sgnb_data.cause_desc;
173       break;
174     case Cause_PR_radioNetwork: //radio network
175       caus->present = Cause_PR_radioNetwork;
176       caus->choice.radioNetwork = sgnb_data.cause_desc;
177       break;
178     case Cause_PR_protocol : //protocol
179       caus->present = Cause_PR_protocol;
180       caus->choice.protocol = sgnb_data.cause_desc;
181       break;
182     case Cause_PR_transport: //transport
183       caus->present = Cause_PR_transport;
184       caus->choice.transport = sgnb_data.cause_desc;
185       break;
186       
187     default:
188       caus->present = Cause_PR_NOTHING;
189       break;
190     }
191
192   return true;
193
194 }
195
196
197 bool sgnb_addition_response::set_fields(X2SuccessfulOutcome_t * successMsg, sgnb_addition_helper &sgnb_data){
198
199   unsigned ie_index = 0;
200
201   if (successMsg == 0){
202     error_string = "Invalid reference for X2AP Sgnb Addition Acknowledge message in set_fields";
203     return false;
204   }
205
206   SgNBAdditionRequestAcknowledge_IEs_t *ies_sgnb_add_ack;
207
208   ie_index = 0;
209   ies_sgnb_add_ack= &IE_array[ie_index];
210   ies_sgnb_add_ack->criticality = Criticality_reject;
211   ies_sgnb_add_ack->id = ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
212   ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
213   ies_sgnb_add_ack->value.choice.UE_X2AP_ID = sgnb_data.menb_ue_x2ap_id;
214
215   
216   ie_index = 1;
217   ies_sgnb_add_ack= &IE_array[ie_index];
218   ies_sgnb_add_ack->criticality = Criticality_reject;
219   ies_sgnb_add_ack->id = ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
220   ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
221   ies_sgnb_add_ack->value.choice.SgNB_UE_X2AP_ID = sgnb_data.sgnb_ue_x2ap_id;
222
223   ie_index = 2;
224   ies_sgnb_add_ack= &IE_array[ie_index];
225   ies_sgnb_add_ack->criticality = Criticality_reject;
226   ies_sgnb_add_ack->id = ProtocolIE_ID_id_SgNBtoMeNBContainer;
227   ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNBtoMeNBContainer;
228   SgNBtoMeNBContainer_t *container = &ies_sgnb_add_ack->value.choice.SgNBtoMeNBContainer;
229   container->buf = sgnb_data.menb_sgnb_container;
230   container->size = sgnb_data.menb_sgnb_container_size;
231
232   ie_index = 3;
233   ies_sgnb_add_ack = &IE_array[ie_index];
234   ies_sgnb_add_ack->criticality = Criticality_reject;
235   ies_sgnb_add_ack->id =  ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList;
236   ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList;
237   E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList_t  * erabs_toadd_list = &(ies_sgnb_add_ack->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList);
238
239
240   int lcount = sgnb_data.erab_list.size();
241   //std::cout <<"Adding " << lcount << " erabs in response" << std::endl;
242   
243   //resize empty array in constructor
244   if (lcount >= erab_admit_array_size){
245     erab_admit_array_size = 2*lcount;
246
247     E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t * new_ref = 0;
248     new_ref = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *)realloc(erab_admit_array, erab_admit_array_size * sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t));
249     assert(new_ref != 0);
250     erab_admit_array = new_ref;
251
252     erab_sgnb_present_array_size = 2 * lcount;
253     E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t  * new_present = 0;
254     new_present = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t  *)realloc(erab_sgnb_present_array, erab_sgnb_present_array_size * sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t ));
255     assert(new_present != 0);
256     erab_sgnb_present_array = new_present;
257
258     erab_sgnb_notpresent_array_size = 2 * lcount;
259     E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t  * new_notpresent = 0;
260     new_notpresent = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t  *)realloc(erab_sgnb_notpresent_array, erab_sgnb_notpresent_array_size * sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t ));
261     assert(new_notpresent != 0);
262     erab_sgnb_notpresent_array = new_notpresent;
263   }
264
265   std::vector<struct erab_item> * ref_erab_input  = &(sgnb_data.erab_list);
266   erabs_toadd_list->list.count = 0;
267
268   int sgnb_present_index = 0;
269   int sgnb_notpresent_index = 0;
270
271   for(unsigned int i = 0; i < lcount; i++){
272
273     erab_admit_array[i].id = ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item ;
274     erab_admit_array[i].criticality = Criticality_ignore;
275     erab_admit_array[i].value.present =  E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
276
277     E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t * erab_item = &(erab_admit_array[i].value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item);
278
279     erab_item->e_RAB_ID = (*ref_erab_input)[i].erab_id;
280     erab_item->en_DC_ResourceConfiguration.pDCPatSgNB =  (*ref_erab_input)[i].pdcp_at_sgnb;
281     erab_item->en_DC_ResourceConfiguration.mCGresources =  (*ref_erab_input)[i].mcg_resources;
282     erab_item->en_DC_ResourceConfiguration.sCGresources =  (*ref_erab_input)[i].scg_resources;
283
284
285     erab_item->resource_configuration.present = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR)(*ref_erab_input)[i].sgnb_pdcp_present;
286     if( erab_item->resource_configuration.present == E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent){
287       
288       erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf = (*ref_erab_input)[i].sgnb_item.transport_layer_addr;
289       erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_size;
290       erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused  = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_unused;
291
292       erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.gTP_TEID.buf = (*ref_erab_input)[i].sgnb_item.gtp_tei;
293       erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.gTP_TEID.size = (*ref_erab_input)[i].sgnb_item.gtp_tei_size;
294
295       /* Force all optional parameters that are not set to NULL */
296       erab_sgnb_present_array[sgnb_present_index].sgNB_UL_GTP_TEIDatPDCP = NULL;
297
298       /* validate constraints ..*/
299       int ret_constr;
300       ret_constr = asn_check_constraints(&asn_DEF_GTP_TEI, &erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.gTP_TEID, errbuf, &errbuf_len);
301       if(ret_constr){
302         error_string.assign(&errbuf[0], errbuf_len);
303         error_string = "Error in constraints for GTP TEID.. Reason = " + error_string;
304         return false;
305       }
306
307       ret_constr = asn_check_constraints(&asn_DEF_GTPtunnelEndpoint, &erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint, errbuf, &errbuf_len);
308       if(ret_constr){
309         error_string.assign(&errbuf[0], errbuf_len);
310         error_string = "Error in constraints for GTP tunnel endpoint .. Reason = " + error_string;
311         return false;
312       }
313
314       ret_constr = asn_check_constraints(&asn_DEF_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent, &erab_sgnb_present_array[sgnb_present_index], errbuf, &errbuf_len);
315       if(ret_constr){
316         error_string.assign(&errbuf[0], errbuf_len);
317         error_string = "Error in constraints for E_RABS_ToBeAdded_SgNBAddReq_SgNBPDCPpresent.. Reason = " + error_string;
318         return false;
319       }
320
321       erab_item->resource_configuration.choice.sgNBPDCPpresent = &erab_sgnb_present_array[sgnb_present_index];
322       sgnb_present_index ++;
323
324     }
325     else if (erab_item->resource_configuration.present ==  E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPnotpresent){
326
327       erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.transportLayerAddress.buf = (*ref_erab_input)[i].sgnb_item.transport_layer_addr;
328       erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.transportLayerAddress.size = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_size;
329       erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.transportLayerAddress.bits_unused  = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_unused;
330
331       erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.gTP_TEID.buf = (unsigned char *)(*ref_erab_input)[i].sgnb_item.gtp_tei;
332       erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.gTP_TEID.size = (*ref_erab_input)[i].sgnb_item.gtp_tei_size;
333
334       erab_sgnb_notpresent_array[sgnb_notpresent_index].secondary_sgNB_DL_GTP_TEIDatSCG = NULL;
335
336       /* validate constraints ..*/
337       int ret_constr;
338       ret_constr = asn_check_constraints(&asn_DEF_GTPtunnelEndpoint, &erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG, errbuf, &errbuf_len);
339       if(ret_constr){
340         error_string.assign(&errbuf[0], errbuf_len);
341         error_string = "Error in constraints for GTP tunnel endpoint .. Reason = " + error_string;
342         return false;
343       }
344
345
346       ret_constr = asn_check_constraints(&asn_DEF_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent, &erab_sgnb_notpresent_array[sgnb_notpresent_index], errbuf, &errbuf_len);
347       if(ret_constr){
348         error_string.assign(&errbuf[0], errbuf_len);
349         error_string = "Error in constraints for E_RABS_ToBeAdded_SgNBAddReq_SgNBPDCPnotpresent.. Reason = " + error_string;
350         return false;
351       }
352
353       erab_item->resource_configuration.choice.sgNBPDCPnotpresent = &erab_sgnb_notpresent_array[sgnb_notpresent_index]; ;
354       sgnb_notpresent_index ++;
355     }
356     else {
357       std::cerr <<"Could not find a pdcp present or not present flag. not adding erab item .." << std::endl;
358       continue;
359     }
360
361     // check constraint
362     int ret_constr = asn_check_constraints(&asn_DEF_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs, &erab_admit_array[i], errbuf, &errbuf_len);
363     if(ret_constr){
364       error_string.assign(&errbuf[0], errbuf_len);
365       error_string = "Error in constraints for E_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs.. Reason = " + error_string;
366       return false;
367     }
368
369     ASN_SEQUENCE_ADD(erabs_toadd_list, &erab_admit_array[i]);
370   }
371
372   return true;
373 }
374
375 bool sgnb_addition_response::encode_sgnb_addition_response(unsigned char* data_buf, size_t *data_size, sgnb_addition_helper &sgnb_data, bool sgnb_response)
376 {
377
378   bool res;
379   if(sgnb_response == true){
380
381     x2ap_pdu_obj->present = X2AP_PDU_PR_successfulOutcome;
382     x2ap_pdu_obj->choice.successfulOutcome = successMsg;
383     
384     successMsg->procedureCode = ProcedureCode_id_sgNBAdditionPreparation;
385     successMsg->criticality = Criticality_ignore;
386     successMsg->value.present = X2SuccessfulOutcome__value_PR_SgNBAdditionRequestAcknowledge;
387
388     res = set_fields(successMsg, sgnb_data);
389
390   } else {
391
392     x2ap_pdu_obj->present = X2AP_PDU_PR_unsuccessfulOutcome;
393     x2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
394
395
396     unsuccessMsg->procedureCode = ProcedureCode_id_sgNBAdditionPreparation;
397     unsuccessMsg->criticality = Criticality_ignore;
398     unsuccessMsg->value.present = X2UnsuccessfulOutcome__value_PR_SgNBAdditionRequestReject;
399
400     res = set_fields(unsuccessMsg, sgnb_data);
401   }
402
403   if (!res){
404     return false;
405   }
406   int ret_constr = asn_check_constraints(&asn_DEF_X2AP_PDU, x2ap_pdu_obj, errbuf, &errbuf_len);
407   if(ret_constr){
408     error_string.assign(&errbuf[0], errbuf_len);
409     error_string = "Error encoding X2AP Sgnb Addition Response  message. Reason = " + error_string;
410     return false;
411   }
412
413   //xer_fprint(stdout, &asn_DEF_X2AP_PDU, x2ap_pdu_obj);
414
415   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_X2AP_PDU, x2ap_pdu_obj, data_buf, *data_size);
416   if(retval.encoded == -1){
417     error_string.assign(strerror(errno));
418     return false;
419   }
420
421   else {
422     if(*data_size < retval.encoded){
423       std::stringstream ss;
424       ss  <<"Error encoding SgNB Addition Request Response. Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *data_size << std::endl;
425       error_string = ss.str();
426       return false;
427     }
428   }
429
430   *data_size = retval.encoded;
431   return true;
432 }
433
434