Adding Bouncer code for RIC-Benchmarking
[ric-app/bouncer.git] / Bouncer / src / xapp-asn / e2ap / subscription_request.cc
1
2
3 /*
4 ==================================================================================
5         Copyright (c) 2019-2020 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21
22 #include "subscription_request.hpp"
23
24
25 // Set up memory allocations for each IE for encoding
26 // We are responsible for memory management for each IE for encoding
27 // Hence destructor should clear out memory
28 // When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
29 // for releasing memory by external calling function)
30 subscription_request::subscription_request(void){
31
32   _name = "default";
33
34   e2ap_pdu_obj = 0;
35   e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
36   assert(e2ap_pdu_obj != 0);
37
38   initMsg = 0;
39   initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
40   assert(initMsg != 0);
41
42   IE_array = 0;
43   IE_array = (RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(RICsubscriptionRequest_IEs_t));
44   assert(IE_array != 0);
45   
46   action_array = 0;
47   action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(RICaction_ToBeSetup_ItemIEs_t));
48   assert(action_array != 0);
49   action_array_size = INITIAL_REQUEST_LIST_SIZE;
50   // also need to add subsequent action and time to wait ..
51   for (unsigned int i = 0; i < action_array_size; i++){
52     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
53     assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction  != 0);
54   }
55   
56   e2ap_pdu_obj->choice.initiatingMessage = initMsg;
57   e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
58
59
60   
61 };
62
63
64
65 // Clear assigned protocolIE list from RIC indication IE container
66 subscription_request::~subscription_request(void){
67     
68   mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory");;
69   
70   // Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer  
71   RICsubscriptionDetails_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscriptionDetails);
72
73   for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
74     ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
75   }
76
77   if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
78     free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
79     ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
80     ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
81     ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
82   }
83
84   // clear subsequent action array
85   for (unsigned int i = 0; i < action_array_size; i++){
86     free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
87   }
88   
89   free(action_array);
90   RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
91   
92   for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
93     subscription_request->protocolIEs.list.array[i] = 0;
94   }
95   
96   if( subscription_request->protocolIEs.list.size > 0){
97     free( subscription_request->protocolIEs.list.array);
98     subscription_request->protocolIEs.list.array = 0;
99     subscription_request->protocolIEs.list.size = 0;
100     subscription_request->protocolIEs.list.count = 0;
101   }
102   
103   free(IE_array);
104   free(initMsg);
105   e2ap_pdu_obj->choice.initiatingMessage = 0;
106   
107   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
108   mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
109 };
110
111
112 bool subscription_request::encode_e2ap_subscription(unsigned char *buf, size_t *size,  subscription_helper &dinput){
113
114   bool res;
115
116   initMsg->procedureCode = ProcedureCode_id_RICsubscription;
117   initMsg->criticality = Criticality_ignore;
118   initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
119
120   res = set_fields(initMsg, dinput);
121   if (!res){
122     return false;
123   }
124   
125   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
126   if(ret_constr){
127     error_string.assign(errbuf, errbuf_len);
128     error_string = "Constraints failed for encoding subscription request. Reason = " + error_string;
129     return false;
130   }
131
132   //xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
133   
134   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
135     
136   if(retval.encoded == -1){
137     error_string.assign(strerror(errno));
138     error_string = "Error encoding Subscription  Request. Reason = " + error_string;
139     return false;
140   }
141   else {
142     if(*size < retval.encoded){
143       std::stringstream ss;
144       ss  <<"Error encoding Subscription  Request . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
145       error_string = ss.str();
146       retval.encoded = -1;
147       return false;
148     }
149   }
150     
151   *size = retval.encoded;
152   return true;
153     
154 }
155
156
157 bool subscription_request::set_fields( InitiatingMessage_t * init_msg, subscription_helper &helper){
158
159   
160   int ie_index;
161   int result = 0;
162
163   if (init_msg == 0){
164     error_string = "Error. Invalid reference when getting fields from subscription request";
165     return false;
166   }
167
168   RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
169   ric_subscription->protocolIEs.list.count = 0;
170   
171   ie_index = 0;
172   RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
173   ies_ricreq->criticality = Criticality_reject;
174   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
175   ies_ricreq->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
176   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
177   ricrequest_ie->ricRequestorID = helper.get_request_id();
178   //ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
179   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
180   assert(result == 0);
181      
182   ie_index = 1;
183   RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
184   ies_ranfunc->criticality = Criticality_reject;
185   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
186   ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
187   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
188   *ranfunction_ie = helper.get_function_id();
189   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
190   assert(result == 0);
191
192
193   ie_index = 2;
194   RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
195   ies_actid->criticality = Criticality_reject;
196   ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
197   ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
198   RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
199
200   ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
201   ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
202    
203   std::vector<Action> * ref_action_array = helper.get_list();
204   // do we need to resize  ?
205   // we don't care about contents, so just do a free/calloc
206   if(action_array_size < ref_action_array->size()){
207     std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() <<  std::endl;
208     // free subsequent allocation
209     for (unsigned int i = 0; i < action_array_size; i++){
210       free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
211     }
212     
213     action_array_size = 2 * ref_action_array->size();
214     free(action_array);
215     action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(RICaction_ToBeSetup_ItemIEs_t));
216     assert(action_array != 0);
217
218     // also need to add subsequent action and time to wait ..
219     for (unsigned int i = 0; i < action_array_size; i++){
220       action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
221       assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction  != 0);
222     }
223     
224   }
225   
226   // reset the list count on ricAction_ToBeSetup_List;
227   ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
228   
229   for(unsigned int i = 0; i < ref_action_array->size(); i ++){
230     action_array[i].criticality = Criticality_ignore;
231     action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
232     action_array[i].value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
233     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
234     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
235     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
236     
237     result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
238     if (result == -1){
239       error_string = "Erorr : Unable to assign memory to add Action item to set up list";
240       return false;
241     }
242     
243   }
244   
245   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
246   assert(result == 0);
247
248
249     
250   return true;
251 };
252
253
254
255 bool subscription_request:: get_fields(InitiatingMessage_t * init_msg,  subscription_helper & dout)
256 {
257
258   if (init_msg == 0){
259     error_string = "Error. Invalid reference when getting fields from subscription request";
260     return false;
261   }
262   
263   RICrequestID_t *requestid;
264   RANfunctionID_t * ranfunctionid;
265   RICsubscriptionDetails_t * ricsubscription;
266     
267   for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
268     RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
269     
270     switch(memb_ptr->id)
271       {
272       case (ProtocolIE_ID_id_RICrequestID):
273         requestid = &memb_ptr->value.choice.RICrequestID;
274         //dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
275         break;
276           
277       case (ProtocolIE_ID_id_RANfunctionID):
278         ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
279         dout.set_function_id(*ranfunctionid);
280         break;
281           
282       case (ProtocolIE_ID_id_RICsubscriptionDetails):
283         ricsubscription = &memb_ptr->value.choice.RICsubscriptionDetails;
284         dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
285           
286         for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
287           RICaction_ToBeSetup_ItemIEs_t * item = (RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
288           if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
289             dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
290           }
291           else{
292             std::string action_def = ""; // for now we are ignoring action definition
293           }   
294         };
295         
296         break;
297       }
298       
299   }
300     
301   //asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
302   return true;
303 };
304
305
306